Merge branch '86Box:master' into nec-v20

This commit is contained in:
Jasmine Iwanek
2022-08-10 13:12:27 -04:00
committed by GitHub
49 changed files with 637 additions and 309 deletions

View File

@@ -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/(<release version=")[^"]+(" date=")[^"]+/\1'"$newversion"'\2'"$(date +%Y-%m-%d)"'/'

View File

@@ -138,6 +138,10 @@ char rom_path[1024] = { '\0'}; /* (O) full path to ROMs */
rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */
char log_path[1024] = { '\0'}; /* (O) full path of logfile */
char vm_name[1024] = { '\0'}; /* (O) display name of the VM */
#ifdef USE_INSTRUMENT
uint8_t instru_enabled = 0;
uint64_t instru_run_ms = 0;
#endif
/* Configuration values. */
int window_remember;
@@ -184,6 +188,7 @@ int enable_discord = 0; /* (C) enable Discord integration */
int pit_mode = -1; /* (C) force setting PIT mode */
int fm_driver = 0; /* (C) select FM sound driver */
int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */
int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */
/* Statistics. */
extern int mmuflush;
@@ -567,6 +572,12 @@ usage:
/* .. and then exit. */
return(0);
#ifdef USE_INSTRUMENT
} else if (!strcasecmp(argv[c], "--instrument")) {
if ((c+1) == argc) goto usage;
instru_enabled = 1;
sscanf(argv[++c], "%llu", &instru_run_ms);
#endif
}
/* Uhm... out of options here.. */

View File

@@ -57,6 +57,10 @@ if(VNC)
endif()
endif()
if(INSTRUMENT)
add_compile_definitions(USE_INSTRUMENT)
endif()
target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd
net print scsi sio snd vid voodoo plat ui)

View File

@@ -38,6 +38,23 @@
#include <86box/chipset.h>
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,

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -1897,6 +1897,8 @@ nmi_raise(void)
{
if (is486 && (cpu_fast_off_flags & 0x20000000))
cpu_fast_off_advance();
nmi = 1;
}

View File

@@ -404,6 +404,7 @@ exec386_dynarec_int(void)
oldcs = CS;
#endif
cpu_state.oldpc = cpu_state.pc;
dr[6] |= 0x4000;
x86_int(1);
}

View File

@@ -32,7 +32,7 @@ static int opAAM(uint32_t fetchdat)
{
int base = getbytef();
if (base == 0) {
if (base == 0) {
x86de(NULL, 0);
return 1;
}

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -20,7 +20,7 @@
#ifndef MACHINE_AMSTRAD_H
#define MACHINE_AMSTRAD_H
extern int amstrad_latch;
extern uint32_t amstrad_latch;
enum {
AMSTRAD_NOLATCH,

View File

@@ -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. */

View File

@@ -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;

View File

@@ -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];

View File

@@ -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;

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -31,6 +31,7 @@ extern "C"
#include <86box/86box.h>
#include <86box/plat.h>
#include <86box/mouse.h>
#include <poll.h>
}
static std::vector<std::pair<int, libevdev*>> 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();
}

View File

@@ -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;

View File

@@ -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(); });
}

View File

@@ -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();
}

View File

@@ -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<std::tuple<uint8_t*, std::atomic_flag*>> getBuffers() override;
HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL)
: QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions()

View File

@@ -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();

View File

@@ -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 <QOpenGLContext>
#include <QScreen>
#include <QString>
#include <QDir>
#include <array>
#include <unordered_map>
@@ -128,6 +133,8 @@ std::atomic<bool> 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();
}

View File

@@ -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<std::unique_ptr<RendererStack>, 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<MachineStatus> status;
std::array<std::unique_ptr<RendererStack>, 8> renderers;
std::shared_ptr<MediaMenu> 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;

View File

@@ -91,6 +91,8 @@
<addaction name="actionEnd_trace"/>
<addaction name="separator"/>
<addaction name="actionMCA_devices"/>
<addaction name="separator"/>
<addaction name="actionOpen_screenshots_folder"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
@@ -106,6 +108,7 @@
<addaction name="actionOpenGL_3_0_Core"/>
<addaction name="actionVulkan"/>
<addaction name="actionDirect3D_9"/>
<addaction name="actionVNC"/>
</widget>
<widget class="QMenu" name="menuWindow_scale_factor">
<property name="title">
@@ -176,6 +179,7 @@
<addaction name="separator"/>
<addaction name="actionFullscreen"/>
<addaction name="menuFullscreen_stretch_mode"/>
<addaction name="actionApply_fullscreen_stretch_mode_when_maximized"/>
<addaction name="menuEGA_S_VGA_settings"/>
<addaction name="separator"/>
<addaction name="actionCGA_PCjr_Tandy_EGA_S_VGA_overscan"/>
@@ -766,6 +770,30 @@
<string>Show non-primary monitors</string>
</property>
</action>
<action name="actionVNC">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>VNC</string>
</property>
<property name="vid_api" stdset="0">
<number>6</number>
</property>
</action>
<action name="actionOpen_screenshots_folder">
<property name="text">
<string>Open screenshots folder...</string>
</property>
</action>
<action name="actionApply_fullscreen_stretch_mode_when_maximized">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Apply fullscreen stretch mode when maximized</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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<std::atomic_flag> buf_usage;

View File

@@ -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");

View File

@@ -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();

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>458</width>
<height>390</height>
<height>391</height>
</rect>
</property>
<property name="windowTitle">
@@ -28,7 +28,7 @@
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QFormLayout" name="formLayout">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
@@ -51,58 +51,55 @@
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxMachineType"/>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Machine:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="1" column="1">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="comboBoxMachine"/>
</item>
<item>
<widget class="QPushButton" name="pushButtonConfigure">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>CPU type:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>FPU:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Wait states:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Memory:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBoxFPU"/>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="comboBoxWaitStates"/>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="spinBoxRAM">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="2" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
@@ -150,38 +147,41 @@
</layout>
</widget>
</item>
<item row="2" column="1">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="comboBoxMachine"/>
</item>
<item>
<widget class="QPushButton" name="pushButtonConfigure">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
</layout>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>FPU:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBoxFPU"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Wait states:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBoxWaitStates"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Memory:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBoxRAM">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>

View File

@@ -172,7 +172,7 @@
</property>
</widget>
</item>
<item row="3" column="0" rowspan="2">
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Controller 4:</string>

View File

@@ -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();
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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. */

View File

@@ -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

View File

@@ -366,6 +366,7 @@ oti_getclock(int clock)
break;
}
return ret;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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; yy<h; yy++) {
p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[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));