diff --git a/bumpversion.sh b/bumpversion.sh index 31ebf154b..ac6116bcc 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -17,9 +17,11 @@ # Parse arguments. newversion="$1" +romversion="$2" + if [ -z "$(echo "$newversion" | grep '\.')" ] then - echo '[!] Usage: bumpversion.sh x.y[.z]' + echo '[!] Usage: bumpversion.sh x.y[.z] [romversion]' exit 1 fi shift @@ -30,6 +32,12 @@ 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" | + grep '"tag_name":' | + sed -E 's/.*"([^"]+)".*/\1/') +fi # Switch to the repository root directory. cd "$(dirname "$0")" || exit @@ -61,6 +69,7 @@ patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_V 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'/' patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' patch_file src/unix/assets/*.metainfo.xml release 's/( +enum { + HEADLAND_GC103 = 0x00, + HEADLAND_GC113 = 0x10, + HEADLAND_HT18_A = 0x11, + HEADLAND_HT18_B = 0x12, + HEADLAND_HT18_C = 0x18, + HEADLAND_HT21_C_D = 0x31, + HEADLAND_HT21_E = 0x32, +}; + + +#define HEADLAND_REV_MASK 0x0F + +#define HEADLAND_HAS_CRI 0x10 +#define HEADLAND_HAS_SLEEP 0x20 + + typedef struct { uint8_t valid, enabled; uint16_t mr; @@ -49,6 +66,7 @@ typedef struct { typedef struct headland_t { uint8_t revision; + uint8_t has_cri, has_sleep; uint8_t cri; uint8_t cr[7]; @@ -330,7 +348,7 @@ hl_write(uint16_t addr, uint8_t val, void *priv) break; case 0x01ed: - if (dev->revision > 0) + if (dev->has_cri) dev->cri = val; break; @@ -339,7 +357,7 @@ hl_write(uint16_t addr, uint8_t val, void *priv) break; case 0x01ef: - switch(dev->cri) { + switch(dev->cri & 0x07) { case 0: dev->cr[0] = (val & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; memmap_state_update(dev); @@ -352,11 +370,18 @@ hl_write(uint16_t addr, uint8_t val, void *priv) case 2: case 3: - case 5: dev->cr[dev->cri] = val; memmap_state_update(dev); break; + case 5: + if (dev->has_sleep) + dev->cr[dev->cri] = val; + else + dev->cr[dev->cri] = val & 0x0f; + memmap_state_update(dev); + break; + case 4: dev->cr[4] = (dev->cr[4] & 0xf0) | (val & 0x0f); memmap_state_update(dev); @@ -421,7 +446,7 @@ hl_read(uint16_t addr, void *priv) break; case 0x01ed: - if (dev->revision > 0) + if (dev->has_cri) ret = dev->cri; break; @@ -430,7 +455,7 @@ hl_read(uint16_t addr, void *priv) break; case 0x01ef: - switch(dev->cri) { + switch(dev->cri & 0x07) { case 0: ret = (dev->cr[0] & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; break; @@ -593,11 +618,14 @@ headland_init(const device_t *info) dev = (headland_t *) malloc(sizeof(headland_t)); memset(dev, 0x00, sizeof(headland_t)); - dev->revision = info->local; + dev->has_cri = (info->local & HEADLAND_HAS_CRI); + dev->has_sleep = (info->local & HEADLAND_HAS_SLEEP); + dev->revision = info->local & HEADLAND_REV_MASK; if (dev->revision > 0) ht386 = 1; + dev->cr[0] = 0x04; dev->cr[4] = dev->revision << 4; if (ht386) @@ -627,7 +655,7 @@ headland_init(const device_t *info) ram, MEM_MAPPING_INTERNAL, &dev->null_mr); if (mem_size > 640) { - mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x40000, + mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x60000, mem_read_b, mem_read_w, mem_read_l, mem_write_b, mem_write_w, mem_write_l, ram + 0xa0000, MEM_MAPPING_INTERNAL, &dev->null_mr); @@ -684,11 +712,26 @@ headland_init(const device_t *info) return(dev); } + const device_t headland_gc10x_device = { .name = "Headland GC101/102/103", .internal_name = "headland_gc10x", .flags = 0, - .local = 0, + .local = HEADLAND_GC103, + .init = headland_init, + .close = headland_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t headland_gc113_device = { + .name = "Headland GC101/102/113", + .internal_name = "headland_gc113", + .flags = 0, + .local = HEADLAND_GC113, .init = headland_init, .close = headland_close, .reset = NULL, @@ -702,7 +745,7 @@ const device_t headland_ht18a_device = { .name = "Headland HT18 Rev. A", .internal_name = "headland_ht18a", .flags = 0, - .local = 1, + .local = HEADLAND_HT18_A, .init = headland_init, .close = headland_close, .reset = NULL, @@ -716,7 +759,7 @@ const device_t headland_ht18b_device = { .name = "Headland HT18 Rev. B", .internal_name = "headland_ht18b", .flags = 0, - .local = 2, + .local = HEADLAND_HT18_B, .init = headland_init, .close = headland_close, .reset = NULL, @@ -730,7 +773,35 @@ const device_t headland_ht18c_device = { .name = "Headland HT18 Rev. C", .internal_name = "headland_ht18c", .flags = 0, - .local = 8, + .local = HEADLAND_HT18_C, + .init = headland_init, + .close = headland_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t headland_ht21c_d_device = { + .name = "Headland HT21 Rev. C/D", + .internal_name = "headland_ht21cd", + .flags = 0, + .local = HEADLAND_HT21_C_D, + .init = headland_init, + .close = headland_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t headland_ht21e_device = { + .name = "Headland HT21 Rev. E", + .internal_name = "headland_ht21", + .flags = 0, + .local = HEADLAND_HT21_E, .init = headland_init, .close = headland_close, .reset = NULL, diff --git a/src/config.c b/src/config.c index 2a2f58c6c..768bbe3e4 100644 --- a/src/config.c +++ b/src/config.c @@ -969,6 +969,8 @@ load_video(void) ibm8514_enabled = !!config_get_int(cat, "8514a", 0); xga_enabled = !!config_get_int(cat, "xga", 0); show_second_monitors = !!config_get_int(cat, "show_second_monitors", 1); + video_fullscreen_scale_maximized = !!config_get_int(cat, "video_fullscreen_scale_maximized", 0); + p = config_get_string(cat, "gfxcard_2", NULL); if (!p) p = "none"; @@ -2554,6 +2556,11 @@ save_video(void) else config_set_int(cat, "show_second_monitors", show_second_monitors); + if (video_fullscreen_scale_maximized == 0) + config_delete_var(cat, "video_fullscreen_scale_maximized"); + else + config_set_int(cat, "video_fullscreen_scale_maximized", video_fullscreen_scale_maximized); + delete_section_if_empty(cat); } diff --git a/src/cpu/386.c b/src/cpu/386.c index 5f30e1199..d6d4ded16 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -196,6 +196,7 @@ exec386(int cycs) enter_smm_check(0); else if (trap) { flags_rebuild(); + dr[6] |= 0x4000; if (msw&1) pmodeint(1,0); else { diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 92360a248..3c0cd168a 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1897,6 +1897,8 @@ nmi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x20000000)) cpu_fast_off_advance(); + + nmi = 1; } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 3e4d91ed2..f90ce5f80 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -404,6 +404,7 @@ exec386_dynarec_int(void) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; x86_int(1); } diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index b37b6a6df..efb0de264 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -32,7 +32,7 @@ static int opAAM(uint32_t fetchdat) { int base = getbytef(); - if (base == 0) { + if (base == 0) { x86de(NULL, 0); return 1; } diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 667ea9d31..0d973338e 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -91,7 +91,7 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + 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; @@ -104,7 +104,7 @@ static int opMOV_r_DRx_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + 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; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index c9398dd69..2fda437e7 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -168,8 +168,12 @@ x86_doabrt(int x86_abrt) void x86de(char *s, uint16_t error) { +#ifdef BAD_CODE cpu_state.abrt = ABRT_DE; abrt_error = error; +#else + x86_int(0); +#endif } diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 72db74359..6f6b77723 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -863,7 +863,8 @@ esdi_read(uint16_t port, void *priv) break; default: - fatal("esdi_read port=%04x\n", port); + esdi_mca_log("esdi_read port=%04x\n", port); + break; } return (ret); diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index ca7fbb99c..30a7542dc 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -76,6 +76,10 @@ extern uint64_t source_hwnd; extern char rom_path[1024]; /* (O) full path to ROMs */ extern char log_path[1024]; /* (O) full path of logfile */ extern char vm_name[1024]; /* (O) display name of the VM */ +#ifdef USE_INSTRUMENT +extern uint8_t instru_enabled; +extern uint64_t instru_run_ms; +#endif #define window_x monitor_settings[0].mon_window_x #define window_y monitor_settings[0].mon_window_y diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index eddb37bff..cc36578fa 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -55,9 +55,12 @@ extern const device_t gc100a_device; /* Headland */ extern const device_t headland_gc10x_device; +extern const device_t headland_gc113_device; extern const device_t headland_ht18a_device; extern const device_t headland_ht18b_device; extern const device_t headland_ht18c_device; +extern const device_t headland_ht21c_d_device; +extern const device_t headland_ht21e_device; /* IMS */ extern const device_t ims8848_device; diff --git a/src/include/86box/m_amstrad.h b/src/include/86box/m_amstrad.h index c33d10c70..1b99617ca 100644 --- a/src/include/86box/m_amstrad.h +++ b/src/include/86box/m_amstrad.h @@ -20,7 +20,7 @@ #ifndef MACHINE_AMSTRAD_H #define MACHINE_AMSTRAD_H -extern int amstrad_latch; +extern uint32_t amstrad_latch; enum { AMSTRAD_NOLATCH, diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index afbcec140..fcccb8494 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -198,30 +198,12 @@ extern pc_timer_t * timer_head; extern int timer_inited; -static __inline void -timer_remove_head_inline(void) -{ - pc_timer_t *timer; - - if (timer_inited && timer_head) { - timer = timer_head; - timer_head = timer->next; - if (timer_head) { - timer_head->prev = NULL; - timer->next->prev = NULL; - } - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - } -} - - static __inline void timer_process_inline(void) { pc_timer_t *timer; - if (!timer_inited || !timer_head) + if (!timer_head) return; while(1) { @@ -230,7 +212,12 @@ timer_process_inline(void) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) break; - timer_remove_head_inline(); + timer_head = timer->next; + if (timer_head) + timer_head->prev = NULL; + + timer->next = timer->prev = NULL; + timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 866aea4a3..f60b3359b 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -92,7 +92,7 @@ typedef struct xga_t { int on; int op_mode_reset, linear_endian_reverse; int sprite_pos, sprite_pos_prefetch, cursor_data_on; - int pal_test; + int pal_test, a5_test; int type, bus; uint32_t linear_base, linear_size, banked_mask; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 8661fcef8..85c95c98d 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -133,6 +133,7 @@ extern atomic_bool doresize_monitors[MONITORS_NUM]; extern int monitor_index_global; extern int gfxcard_2; extern int show_second_monitors; +extern int video_fullscreen_scale_maximized; typedef rgb_t PALETTE[256]; diff --git a/src/io.c b/src/io.c index 268305e1a..6501a199a 100644 --- a/src/io.c +++ b/src/io.c @@ -312,19 +312,21 @@ inb(uint16_t port) p = q; } - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; /* TriGem 486-BIOS MHz output. */ - if (port == 0x1ed) - ret = 0xfe; + /* if (port == 0x1ed) + ret = 0xfe; */ io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); @@ -401,12 +403,14 @@ inw(uint16_t port) } ret = (ret8[1] << 8) | ret8[0]; - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; @@ -487,17 +491,26 @@ inl(uint16_t port) ret16[0] = ret & 0xffff; ret16[1] = (ret >> 16) & 0xffff; - for (i = 0; i < 4; i += 2) { - p = io[(port + i) & 0xffff]; - while(p) { - q = p->next; - if (p->inw && !p->inl) { - ret16[i >> 1] &= p->inw(port + i, p->priv); - found |= 2; - qfound++; - } - p = q; - } + p = io[port & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[0] &= p->inw(port, p->priv); + found |= 2; + qfound++; + } + p = q; + } + + p = io[(port + 2) & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[1] &= p->inw(port + 2, p->priv); + found |= 2; + qfound++; + } + p = q; } ret = (ret16[1] << 16) | ret16[0]; @@ -519,12 +532,14 @@ inl(uint16_t port) } ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 5dc82226d..eb934ebd1 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -156,7 +156,7 @@ typedef struct { fdc_t *fdc; } amstrad_t; -int amstrad_latch; +uint32_t amstrad_latch; static uint8_t key_queue[16]; static int key_queue_start = 0, @@ -2255,7 +2255,7 @@ ams_read(uint16_t port, void *priv) else if (video_is_mda()) ret |= 0xc0; - switch (amstrad_latch) { + switch (amstrad_latch & 0x7fffffff) { case AMSTRAD_NOLATCH: ret &= ~0x20; break; @@ -2293,6 +2293,7 @@ machine_amstrad_init(const machine_t *model, int type) ams = (amstrad_t *) malloc(sizeof(amstrad_t)); memset(ams, 0x00, sizeof(amstrad_t)); ams->type = type; + amstrad_latch = 0x80000000; switch (type) { case AMS_PC200: diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index fb4186c4e..e30272063 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -67,15 +67,17 @@ machine_at_mr286_init(const machine_t *model) } static void -machine_at_headland_common_init(int ht386) +machine_at_headland_common_init(int type) { device_add(&keyboard_at_ami_device); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - if (ht386) + if (type == 2) device_add(&headland_ht18b_device); + else if (type == 1) + device_add(&headland_gc113_device); else device_add(&headland_gc10x_device); } @@ -93,7 +95,7 @@ machine_at_tg286m_init(const machine_t *model) machine_at_common_ide_init(model); - machine_at_headland_common_init(0); + machine_at_headland_common_init(1); return ret; } @@ -114,7 +116,7 @@ machine_at_ama932j_init(const machine_t *model) if (gfxcard == VID_INTERNAL) device_add(&oti067_ama932j_device); - machine_at_headland_common_init(1); + machine_at_headland_common_init(2); return ret; } diff --git a/src/nvr.c b/src/nvr.c index b73aa6fa7..a68331e34 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -237,6 +237,7 @@ nvr_load(void) { char *path; FILE *fp; + uint8_t regs[NVR_MAXSIZE] = { 0 }; /* Make sure we have been initialized. */ if (saved_nvr == NULL) return(0); @@ -255,9 +256,12 @@ nvr_load(void) fp = plat_fopen(path, "rb"); saved_nvr->is_new = (fp == NULL); if (fp != NULL) { + memcpy(regs, saved_nvr->regs, sizeof(regs)); /* Read NVR contents from file. */ - if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) - fatal("nvr_load(): Error reading data\n"); + if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) { + memcpy(saved_nvr->regs, regs, sizeof(regs)); + saved_nvr->is_new = 1; + } (void)fclose(fp); } } else diff --git a/src/nvr_at.c b/src/nvr_at.c index bb4c38b85..eb749ff49 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -467,10 +467,10 @@ timer_update(void *priv) nvr->regs[RTC_REGC] |= REGC_AF; if (nvr->regs[RTC_REGB] & REGB_AIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } @@ -481,10 +481,10 @@ timer_update(void *priv) nvr->regs[RTC_REGC] |= REGC_UF; if (nvr->regs[RTC_REGB] & REGB_UIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } } @@ -533,10 +533,10 @@ timer_intr(void *priv) nvr->regs[RTC_REGC] |= REGC_PF; if (nvr->regs[RTC_REGB] & REGB_PIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } } @@ -592,6 +592,7 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) local_t *local = (local_t *)nvr->data; struct tm tm; uint8_t old; + uint8_t irq = 0, old_irq = 0; old = nvr->regs[reg]; switch(reg) { @@ -601,12 +602,21 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) break; case RTC_REGB: + old_irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; nvr->regs[RTC_REGB] = val; if (((old^val) & REGB_SET) && (val & REGB_SET)) { /* According to the datasheet... */ nvr->regs[RTC_REGA] &= ~REGA_UIP; nvr->regs[RTC_REGB] &= ~REGB_UIE; } + irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; + if (old_irq && !irq) { + picintc(1 << nvr->irq); + nvr->regs[RTC_REGC] &= ~REGC_IRQF; + } else if (!old_irq && irq) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } break; case RTC_REGC: /* R/O */ @@ -694,8 +704,8 @@ nvr_read(uint16_t addr, void *priv) break; case RTC_REGC: - picintc(1 << nvr->irq); ret = nvr->regs[RTC_REGC]; + picintc(1 << nvr->irq); nvr->regs[RTC_REGC] = 0x00; break; diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 120f4572c..5ad252f1a 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -31,6 +31,7 @@ extern "C" #include <86box/86box.h> #include <86box/plat.h> #include <86box/mouse.h> +#include } static std::vector> evdev_mice; @@ -54,25 +55,39 @@ void evdev_mouse_poll() void evdev_thread_func() { + struct pollfd *pfds = (struct pollfd*)calloc(evdev_mice.size(), sizeof(struct pollfd)); + for (unsigned int i = 0; i < evdev_mice.size(); i++) + { + pfds[i].fd = libevdev_get_fd(evdev_mice[i].second); + pfds[i].events = POLLIN; + } + while (!stopped) { + poll(pfds, evdev_mice.size(), 500); for (unsigned int i = 0; i < evdev_mice.size(); i++) { struct input_event ev; - int rc = libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev); - if (rc == 0 && ev.type == EV_REL && mouse_capture) - { - if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; - if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + if (pfds[i].revents & POLLIN) { + while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) + { + if (ev.type == EV_REL && mouse_capture) + { + if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; + if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + } + } } } } + for (unsigned int i = 0; i < evdev_mice.size(); i++) { libevdev_free(evdev_mice[i].second); evdev_mice[i].second = nullptr; close(evdev_mice[i].first); } + free(pfds); evdev_mice.clear(); } diff --git a/src/qt/qt.c b/src/qt/qt.c index 68b204dbc..bb6d9658d 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -51,6 +51,8 @@ plat_vidapi(char* api) { return 4; } else if (!strcasecmp(api, "qt_d3d9")) { return 5; + } else if (!strcasecmp(api, "vnc")) { + return 6; } return 0; @@ -78,6 +80,9 @@ char* plat_vidapi_name(int api) { case 5: name = "qt_d3d9"; break; + case 6: + name = "vnc"; + break; default: fatal("Unknown renderer: %i\n", api); break; diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index e7ef16f77..b4269d2e7 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -108,6 +108,7 @@ void D3D9Renderer::paintEvent(QPaintEvent *event) dstRect.left = destination.left(); dstRect.right = destination.right(); 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); @@ -145,6 +146,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h) return; } surfaceInUse = true; + auto origSource = source; source.setRect(x, y, w, h); RECT srcRect; D3DLOCKED_RECT lockRect; @@ -164,6 +166,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h) 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_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 30ca74ecd..3577234ee 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -134,6 +134,7 @@ void HardwareRenderer::initializeGL() pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); glClearColor(0, 0, 0, 1); + m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); } void HardwareRenderer::paintGL() { @@ -187,6 +188,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { auto tval = this; void* nuldata = 0; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + auto origSource = source; if (!m_texture || !m_texture->isCreated()) { buf_usage[buf_idx].clear(); @@ -197,6 +199,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)imagebufs[buf_idx].get()); buf_usage[buf_idx].clear(); source.setRect(x, y, w, h); + if (origSource != source) onResize(this->width(), this->height()); update(); } diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index af4f05464..b9b7895e0 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -47,6 +47,10 @@ public: void resizeGL(int w, int h) override; void initializeGL() override; void paintGL() override; + void exposeEvent(QExposeEvent* event) override + { + onResize(size().width(), size().height()); + } std::vector> getBuffers() override; HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a74958511..694a0e5f6 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -109,9 +109,21 @@ main_thread_fn() if (drawits > 50) drawits = 0; +#ifdef USE_INSTRUMENT + uint64_t start_time = elapsed_timer.nsecsElapsed(); +#endif /* Run a block of code. */ pc_run(); +#ifdef USE_INSTRUMENT + if (instru_enabled) { + uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; + uint64_t total_elapsed_ms = (uint64_t)((double)tsc / cpu_s->rspeed * 1000); + printf("[instrument] %llu, %llu\n", total_elapsed_ms, elapsed_us); + if (instru_run_ms && total_elapsed_ms >= instru_run_ms) + break; + } +#endif /* Every 200 frames we save the machine status. */ if (++frames >= 200 && nvr_dosave) { qt_nvr_save(); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 00ebb578e..c19dc4f54 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -46,6 +46,10 @@ extern "C" { #include <86box/vid_ega.h> #include <86box/version.h> +#ifdef USE_VNC +#include <86box/vnc.h> +#endif + extern int qt_nvr_save(void); #ifdef MTR_ENABLED @@ -70,6 +74,7 @@ extern "C" { #include #include #include +#include #include #include @@ -128,6 +133,8 @@ 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); +extern MainWindow* main_window; + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -141,6 +148,8 @@ MainWindow::MainWindow(QWidget *parent) : ((BWindow*)this->winId())->AddFilter(filter); #endif setUnifiedTitleAndToolBarOnMac(true); + extern MainWindow* main_window; + main_window = this; ui->setupUi(this); ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); @@ -286,6 +295,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionShow_non_primary_monitors->setChecked(show_second_monitors); 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); #if defined Q_OS_WINDOWS || defined Q_OS_MACOS /* Make the option visible only if ANGLE is loaded. */ @@ -308,6 +318,11 @@ MainWindow::MainWindow(QWidget *parent) : if (vid_api == 5) vid_api = 0; #endif +#ifndef USE_VNC + if (vid_api == 6) vid_api = 0; + ui->actionVNC->setVisible(false); +#endif + #if !QT_CONFIG(vulkan) if (vid_api == 4) vid_api = 0; ui->actionVulkan->setVisible(false); @@ -322,10 +337,20 @@ MainWindow::MainWindow(QWidget *parent) : 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) { + startblit(); + vnc_enabled = 0; + vnc_close(); + video_setblit(qt_blit); + endblit(); + } +#endif RendererStack::Renderer newVidApi = RendererStack::Renderer::Software; switch (vid_api) { @@ -347,6 +372,15 @@ MainWindow::MainWindow(QWidget *parent) : case 5: newVidApi = (RendererStack::Renderer::Direct3D9); break; +#ifdef USE_VNC + case 6: + { + newVidApi = RendererStack::Renderer::Software; + startblit(); + vnc_enabled = vnc_init(nullptr); + endblit(); + } +#endif } ui->stackedWidget->switchRenderer(newVidApi); if (!show_second_monitors) return; @@ -469,7 +503,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); ui->actionTake_screenshot->setShortcutVisibleInContextMenu(true); #endif - video_setblit(qt_blit); + if (!vnc_enabled) video_setblit(qt_blit); if (start_in_fullscreen) { connect(ui->stackedWidget, &RendererStack::blit, this, [this] () { @@ -1742,11 +1776,15 @@ static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* sele ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); - if (video_fullscreen > 0) { + { auto widget = ui->stackedWidget->currentWidget(); ui->stackedWidget->onResize(widget->width(), widget->height()); } + for (int i = 1; i < MONITORS_NUM; i++) { + if (main_window->renderers[i]) main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); + } + device_force_redraw(); config_save(); } @@ -2092,3 +2130,26 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() blitDummied = false; } + +void MainWindow::on_actionOpen_screenshots_folder_triggered() +{ + QDir(QString(usr_path) + QString("/screenshots/")).mkpath("."); + QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); +} + + +void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked) +{ + video_fullscreen_scale_maximized = checked; + + auto widget = ui->stackedWidget->currentWidget(); + ui->stackedWidget->onResize(widget->width(), widget->height()); + + for (int i = 1; i < MONITORS_NUM; i++) { + if (renderers[i]) renderers[i]->onResize(renderers[i]->width(), renderers[i]->height()); + } + + device_force_redraw(); + config_save(); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 0f8a5ecd2..c48333706 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -33,6 +33,8 @@ public: void blitToWidget(int x, int y, int w, int h, int monitor_index); QSize getRenderWidgetSize(); void setSendKeyboardInput(bool enabled); + + std::array, 8> renderers; signals: void paint(const QImage& image); void resizeContents(int w, int h); @@ -129,10 +131,13 @@ protected: private slots: void on_actionShow_non_primary_monitors_triggered(); + void on_actionOpen_screenshots_folder_triggered(); + + void on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked); + private: Ui::MainWindow *ui; std::unique_ptr status; - std::array, 8> renderers; std::shared_ptr mm; #ifdef Q_OS_MACOS @@ -144,6 +149,7 @@ private: bool send_keyboard_input = true; bool shownonce = false; bool resizableonce = false; + bool vnc_enabled = false; friend class SpecifyDimensions; friend class ProgSettings; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index f077f7e97..3551eddb1 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -91,6 +91,8 @@ + + @@ -106,6 +108,7 @@ + @@ -176,6 +179,7 @@ + @@ -766,6 +770,30 @@ Show non-primary monitors + + + true + + + VNC + + + 6 + + + + + Open screenshots folder... + + + + + true + + + Apply fullscreen stretch mode when maximized + + diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 3a5f58846..115e6af7f 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -80,6 +80,8 @@ OpenGLRenderer::exposeEvent(QExposeEvent *event) if (!isInitialized) initialize(); + + onResize(size().width(), size().height()); } void @@ -95,8 +97,8 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event) context->makeCurrent(this); glViewport( - destination.x(), - destination.y(), + destination.x() * devicePixelRatio(), + destination.y() * devicePixelRatio(), destination.width() * devicePixelRatio(), destination.height() * devicePixelRatio()); } @@ -179,8 +181,8 @@ OpenGLRenderer::initialize() glClearColor(0.f, 0.f, 0.f, 1.f); glViewport( - destination.x(), - destination.y(), + destination.x() * devicePixelRatio(), + destination.y() * devicePixelRatio(), destination.width() * devicePixelRatio(), destination.height() * devicePixelRatio()); @@ -425,6 +427,14 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) context->makeCurrent(this); +#ifdef Q_OS_MACOS + glViewport( + destination.x() * devicePixelRatio(), + destination.y() * devicePixelRatio(), + destination.width() * devicePixelRatio(), + destination.height() * devicePixelRatio()); +#endif + if (source.width() != w || source.height() != h) { source.setRect(0, 0, w, h); diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 0974c1f78..bb4903ee8 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -47,7 +47,7 @@ static void integer_scale(double *d, double *g) { } void RendererCommon::onResize(int width, int height) { - if (video_fullscreen == 0) { + if (video_fullscreen == 0 && video_fullscreen_scale_maximized ? (parentWidget->isMaximized() == false && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1) { destination.setRect(0, 0, width, height); return; } diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 1a0bf73e1..4a1b18341 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -37,7 +37,7 @@ public: protected: bool eventDelegate(QEvent *event, bool &result); - QRect source, destination; + QRect source{0, 0, 0, 0}, destination; QWidget *parentWidget { nullptr }; std::vector buf_usage; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 273bc4c95..3ff223ce4 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -397,6 +397,7 @@ RendererStack::createRenderer(Renderer renderer) if (current.get() == nullptr) return; current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); + current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); addWidget(current.get()); this->setStyleSheet("background-color: black"); diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 75cabec49..b2eccc84a 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -32,6 +32,10 @@ public: void wheelEvent(QWheelEvent *event) override; void leaveEvent(QEvent *event) override; void closeEvent(QCloseEvent *event) override; + void resizeEvent(QResizeEvent *event) override + { + onResize(event->size().width(), event->size().height()); + } void keyPressEvent(QKeyEvent *event) override { event->ignore(); diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 30f375f7e..d5ff1ca59 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -7,7 +7,7 @@ 0 0 458 - 390 + 391 @@ -28,7 +28,7 @@ - + 0 @@ -51,58 +51,55 @@ - + Machine: - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + Configure + + + + + + + CPU type: - - - - FPU: - - - - - - - Wait states: - - - - - - - Memory: - - - - - - - - - - - - - - 0 - 0 - - - - - + @@ -150,38 +147,41 @@ - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - Configure - - - - + + + + FPU: + + + + + + + + + + Wait states: + + + + + + + + + + Memory: + + + + + + + + 0 + 0 + + diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index c4c44b019..30a59f982 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -172,7 +172,7 @@ - + Controller 4: diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 850e8369a..44a69c144 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -57,11 +57,14 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { auto tval = this; void* nuldata = 0; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + auto origSource = source; cur_image = buf_idx; buf_usage[(buf_idx + 1) % 2].clear(); source.setRect(x, y, w, h); + + if (source != origSource) onResize(this->width(), this->height()); update(); } diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index cb3b96e14..629665d62 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -836,9 +836,11 @@ bool VulkanWindowRenderer::event(QEvent *event) void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { + auto origSource = source; source.setRect(x, y, w, h); if (isExposed()) requestUpdate(); buf_usage[0].clear(); + if (origSource != source) onResize(this->width(), this->height()); } uint32_t VulkanWindowRenderer::getBytesPerRow() diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index cb442032c..10ef7b5e0 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1844,6 +1844,18 @@ static const device_config_t mpu401_standalone_config[] = { .description = "0x330", .value = 0x330 }, + { + .description = "0x332", + .value = 0x332 + }, + { + .description = "0x334", + .value = 0x334 + }, + { + .description = "0x336", + .value = 0x336 + }, { .description = "0x340", .value = 0x340 diff --git a/src/timer.c b/src/timer.c index 32d382d54..f8e17be2e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -41,20 +41,31 @@ timer_enable(pc_timer_t *timer) return; } - timer_node = timer_head; + if (TIMER_LESS_THAN(timer, timer_head)) { + timer->next = timer_head; + timer->prev = NULL; + timer_head->prev = timer; + timer_head = timer; + timer_target = timer_head->ts.ts32.integer; + return; + } + + if (!timer_head->next) { + timer_head->next = timer; + timer->prev = timer_head; + return; + } + + pc_timer_t *prev = timer_head; + timer_node = timer_head->next; while(1) { /*Timer expires before timer_node. Add to list in front of timer_node*/ if (TIMER_LESS_THAN(timer, timer_node)) { timer->next = timer_node; - timer->prev = timer_node->prev; + timer->prev = prev; timer_node->prev = timer; - if (timer->prev) - timer->prev->next = timer; - else { - timer_head = timer; - timer_target = timer_head->ts.ts32.integer; - } + prev->next = timer; return; } @@ -65,6 +76,7 @@ timer_enable(pc_timer_t *timer) return; } + prev = timer_node; timer_node = timer_node->next; } } @@ -91,33 +103,12 @@ timer_disable(pc_timer_t *timer) } -void -timer_remove_head(void) -{ - pc_timer_t *timer; - - if (!timer_inited) - return; - - if (timer_head) { - timer = timer_head; - timer_head = timer->next; - if (timer_head) { - timer_head->prev = NULL; - timer->next->prev = NULL; - } - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - } -} - - void timer_process(void) { pc_timer_t *timer; - if (!timer_inited || !timer_head) + if (!timer_head) return; while(1) { @@ -126,7 +117,12 @@ timer_process(void) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) break; - timer_remove_head(); + timer_head = timer->next; + if (timer_head) + timer_head->prev = NULL; + + timer->next = timer->prev = NULL; + timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index d5fe0a0b1..585e1aa17 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,6 +12,8 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* +%global romver v3.7 + Name: 86Box Version: 3.7.1 Release: 1%{?dist} @@ -20,7 +22,7 @@ License: GPLv2+ URL: https://86box.net Source0: https://github.com/86Box/86Box/archive/refs/tags/v%%{version}.tar.gz -Source1: https://github.com/86Box/roms/archive/refs/tags/%{version}.tar.gz +Source1: https://github.com/86Box/roms/archive/refs/tags/%{romver}.zip BuildRequires: cmake BuildRequires: desktop-file-utils @@ -55,7 +57,7 @@ It supports various models of PCs, graphics and sound cards, and CPUs. %package roms Summary: ROMs for use with 86Box -Version: %{version} +Version: %{romver} License: Proprietary BuildArch: noarch @@ -111,7 +113,7 @@ popd # files part of the rom package %files roms -%license roms-%{version}/LICENSE +%license roms-%{romver}/LICENSE %{_datadir}/%{name}/roms %changelog diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 7572e44b6..cea26a71f 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -366,6 +366,7 @@ oti_getclock(int clock) break; } + return ret; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index ea70248dc..9ab96c169 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1079,6 +1079,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ svga->xga.test = val; + svga->xga.a5_test = 1; return; } else if (val == 0x5a) { svga->xga.test = val; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 17b4c4981..3a8c4b10a 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -43,35 +43,33 @@ svga_render_null(svga_t *svga) void svga_render_blank(svga_t *svga) { - int x, xx; - if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; + svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x < (svga->hdisp + svga->scrollcache); x++) { - switch (svga->seqregs[1] & 9) { - case 0: - for (xx = 0; xx < 9; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 9) + xx] = 0x00000000; - break; - case 1: - for (xx = 0; xx < 8; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 8) + xx] = 0x00000000; - break; - case 8: - for (xx = 0; xx < 18; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 18) + xx] = 0x00000000; - break; - case 9: - for (xx = 0; xx < 16; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 16) + xx] = 0x00000000; - break; - } + uint32_t char_width = 0; + + switch (svga->seqregs[1] & 9) { + case 0: + char_width = 9; + break; + case 1: + char_width = 8; + break; + case 8: + char_width = 18; + break; + case 9: + char_width = 16; + break; } + + uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); + memset(line_ptr, 0, line_width); } @@ -81,13 +79,14 @@ svga_render_overscan_left(svga_t *svga) int i; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->scrblank || (svga->hdisp == 0)) - return; + return; + uint32_t *line_ptr = buffer32->line[svga->displine + svga->y_add]; for (i = 0; i < svga->x_add; i++) - buffer32->line[svga->displine + svga->y_add][i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; } @@ -97,14 +96,15 @@ svga_render_overscan_right(svga_t *svga) int i, right; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->scrblank || (svga->hdisp == 0)) - return; + return; + uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp]; right = (overscan_x >> 1); for (i = 0; i < right; i++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp + i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 2941d9cb2..4a141660b 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -73,6 +73,8 @@ linear: } xga->on = 0; vga_on = 1; + if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test) + xga->linear_endian_reverse = 1; } else { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); @@ -320,8 +322,18 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 0; } } - if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) - 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; + } + } + //pclog("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); break; case 0x62: @@ -716,7 +728,7 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b xga_t *xga = &svga->xga; uint32_t addr = base; int bits; - uint32_t byte, byte2; + uint32_t byte; uint8_t px; int skip = 0; @@ -735,7 +747,6 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) if (xga->linear_endian_reverse) bits = 7 - (x & 7); @@ -744,18 +755,18 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b else { bits = 7 - (x & 7); } - px = (byte2 >> bits) & 1; + px = (byte >> bits) & 1; return px; } static uint32_t -xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, int height) +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) { xga_t *xga = &svga->xga; uint32_t addr = base; int bits; - uint32_t byte, byte2; + uint32_t byte; uint8_t px; int skip = 0; @@ -776,7 +787,6 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) if (xga->linear_endian_reverse) bits = 7 - (x & 7); @@ -785,7 +795,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int else { bits = 7 - (x & 7); } - px = (byte2 >> bits) & 1; + px = (byte >> bits) & 1; return px; case 3: /*8-bit*/ addr += (y * width); @@ -819,12 +829,11 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } static void -xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width, int height) +xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width) { xga_t *xga = &svga->xga; uint32_t addr = base; uint8_t byte, mask; - uint8_t byte2; int skip = 0; if (xga->base_addr_1mb) { @@ -844,7 +853,6 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { if (xga->linear_endian_reverse) mask = 1 << (7 - (x & 7)); @@ -853,11 +861,19 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { mask = 1 << (7 - (x & 7)); } - byte2 = (byte2 & ~mask) | ((pixel ? 0xff : 0) & mask); - if (!skip) { - WRITE(addr, byte2); + byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); + if (pixel & 1) { + if (!skip) { + xga->vram[((addr)) & (xga->vram_mask)] |= mask; + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + } + } else { + if (!skip) { + xga->vram[((addr)) & (xga->vram_mask)] &= ~mask; + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + } } - mem_writeb_phys(addr, byte2); + mem_writeb_phys(addr, byte); break; case 3: /*8-bit*/ addr += (y * width); @@ -947,8 +963,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -962,19 +978,19 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -988,13 +1004,13 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } @@ -1080,8 +1096,8 @@ xga_line_draw_write(svga_t *svga) if (steep) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1094,18 +1110,18 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } else { if ((dy >= xga->accel.mask_map_origin_x_off) && (dy <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dx >= xga->accel.mask_map_origin_y_off) && (dx <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1118,18 +1134,18 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } } else { if (steep) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1142,15 +1158,15 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1163,11 +1179,11 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } @@ -1267,8 +1283,8 @@ xga_bitblt(svga_t *svga) if (xga->accel.command & 0xc0) { if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1280,12 +1296,12 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1297,7 +1313,7 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } @@ -1361,11 +1377,11 @@ xga_bitblt(svga_t *svga) if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.bkgd_color; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1377,16 +1393,16 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.bkgd_color; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1398,7 +1414,7 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } @@ -1827,7 +1843,7 @@ exec_command: xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); //if (xga->accel.pat_src) { - // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x\n", + // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x, planemask = %08x\n", // CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], // xga->accel.px_map_width[xga->accel.dst_map], xga->accel.px_map_width[xga->accel.src_map], // xga->accel.px_map_height[xga->accel.pat_src], xga->accel.px_map_height[xga->accel.dst_map], @@ -1837,8 +1853,8 @@ exec_command: // xga->accel.src_map_x, xga->accel.src_map_y, // xga->accel.pat_src, xga->accel.dst_map, xga->accel.src_map, // xga->accel.px_map_base[xga->accel.dst_map], xga->accel.px_map_base[xga->accel.src_map], xga->accel.px_map_base[xga->accel.pat_src], - // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f); - // pclog("\n"); + // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); + // //pclog("\n"); //} switch ((xga->accel.command >> 24) & 0x0f) { case 3: /*Bresenham Line Draw Read*/ @@ -2681,6 +2697,8 @@ static void xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; xga->bios_rom.sz = 0x2000; + xga->linear_endian_reverse = 0; + xga->a5_test = 0; f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); diff --git a/src/vnc.c b/src/vnc.c index 46ef21c5d..0cc745883 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -172,8 +172,10 @@ vnc_blit(int x, int y, int w, int h, int monitor_index) uint32_t *p; int yy; - if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL)) - return; + if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL)) { + video_blit_complete_monitor(monitor_index); + return; + } for (yy=0; yyframeBuffer)[yy*VNC_MAX_X]); @@ -185,7 +187,7 @@ vnc_blit(int x, int y, int w, int h, int monitor_index) if (screenshots) video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, VNC_MAX_X); - video_blit_complete(); + video_blit_complete_monitor(monitor_index); if (! updatingSize) rfbMarkRectAsModified(rfb, 0,0, allowedX,allowedY); @@ -210,7 +212,8 @@ vnc_init(UNUSED(void *arg)) 32, 32, 0, 1, 255,255,255, 16, 8, 0, 0, 0 }; - cgapal_rebuild(); + plat_pause(1); + cgapal_rebuild_monitor(0); if (rfb == NULL) { wcstombs(title, ui_window_title(NULL), sizeof(title));