This commit is contained in:
OBattler
2022-07-10 00:38:46 +02:00
60 changed files with 1442 additions and 1186 deletions

4
.ci/Jenkinsfile vendored
View File

@@ -90,8 +90,8 @@ def presetSlugs = [
def presetFlags = [
'Regular': '-t --preset=regular -D CMAKE_BUILD_TYPE=Release',
'Debug': '--preset=debug -D CMAKE_BUILD_TYPE=Debug',
'Dev': '--preset=experimental -D CMAKE_BUILD_TYPE=Debug -D VNC=OFF'
'Debug': '--preset=debug -D CMAKE_BUILD_TYPE=Debug -D STATIC_BUILD=OFF',
'Dev': '--preset=experimental -D CMAKE_BUILD_TYPE=Debug -D VNC=OFF -D STATIC_BUILD=OFF'
]
def gitClone(repository, branch) {

View File

@@ -662,7 +662,7 @@ fi
if [ ! -e "discord_game_sdk.zip" ]
then
echo [-] Downloading Discord Game SDK
wget -qO discord_game_sdk.zip "https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip"
wget -qO discord_game_sdk.zip "https://dl-game-sdk.discordapp.net/latest/discord_game_sdk.zip"
status=$?
if [ $status -ne 0 ]
then
@@ -673,9 +673,10 @@ fi
# Determine Discord Game SDK architecture.
case $arch in
32) arch_discord="x86";;
64) arch_discord="x86_64";;
*) arch_discord="$arch";;
32) arch_discord="x86";;
64) arch_discord="x86_64";;
arm64 | ARM64) arch_discord="aarch64";;
*) arch_discord="$arch";;
esac
# Create temporary directory for archival.

View File

@@ -35,7 +35,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
VERSION 3.5
VERSION 3.6
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)
@@ -187,11 +187,10 @@ elseif(BUILD_TYPE_LOWER STREQUAL "alpha")
add_compile_definitions(ALPHA_BUILD)
endif()
# Variables introduced by richardg867 for versioning stuff
# Versioning variables
if(NOT CMAKE_PROJECT_VERSION_PATCH)
set(CMAKE_PROJECT_VERSION_PATCH 0)
endif()
set(EMU_VERSION_EX "3.50")
if(NOT EMU_BUILD_NUM)
set(EMU_BUILD_NUM 0)
endif()

View File

@@ -17,44 +17,34 @@
# Parse arguments.
newversion="$1"
if [ -z "$(echo $newversion | grep '\.')" ]
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
# Extract version components.
newversion_maj=$(echo $newversion | cut -d. -f1)
newversion_min=$(echo $newversion | cut -d. -f2)
newversion_patch=$(echo $newversion | cut -d. -f3)
newversion_maj=$(echo "$newversion" | cut -d. -f1)
newversion_min=$(echo "$newversion" | cut -d. -f2)
newversion_patch=$(echo "$newversion" | cut -d. -f3)
[ -z "$newversion_patch" ] && newversion_patch=0
base36() {
if [ $1 -lt 10 ]
then
echo $1
else
printf '%b' $(printf '\\%03o' $((55 + $1)))
fi
}
newversion_maj_base36=$(base36 $newversion_maj)
newversion_min_base36=$(base36 $newversion_min)
newversion_patch_base36=$(base36 $newversion_patch)
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")"
get_latest_rom_release() {
# get the latest ROM release from GitHub api
curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" |
grep '"tag_name":' |
sed -E 's/.*"([^"]+)".*/\1/'
}
cd "$(dirname "$0")" || exit
pretty_date() {
# Ensure we get the date in English
LANG=en_US.UTF-8 date '+%a %b %d %Y'
# Ensure we get the date in English.
LANG=en_US.UTF-8 date '+%a %b %d %Y'
}
# Patch files.
@@ -71,17 +61,15 @@ patch_file() {
fi
}
patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/'
patch_file CMakeLists.txt EMU_VERSION_EX 's/(\s*set\(EMU_VERSION_EX\s+")[^"]+/\1'"$newversion_maj_base36.$newversion_min_base36$newversion_patch_base36"'/'
patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/'
patch_file src/include_make/*/version.h EMU_VERSION 's/(#\s*define\s+EMU_VERSION\s+")[^"]+/\1'"$newversion"'/'
patch_file src/include_make/*/version.h EMU_VERSION_EX 's/(#\s*define\s+EMU_VERSION_EX\s+")[^"]+/\1'"$newversion_maj_base36.$newversion_min_base36$newversion_patch_base36"'/'
patch_file src/include_make/*/version.h EMU_VERSION_MAJ 's/(#\s*define\s+EMU_VERSION_MAJ\s+)[0-9]+/\1'"$newversion_maj"'/'
patch_file src/include_make/*/version.h EMU_VERSION_MIN 's/(#\s*define\s+EMU_VERSION_MIN\s+)[0-9]+/\1'"$newversion_min"'/'
patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_VERSION_PATCH\s+)[0-9]+/\1'"$newversion_patch"'/'
patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/'
patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/'
patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/'
patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/'"$(get_latest_rom_release)"'/'
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

@@ -343,7 +343,7 @@ softresetx86(void)
if (soft_reset_mask)
return;
if (ibm8514_enabled)
if (ibm8514_enabled || xga_enabled)
vga_on = 1;
reset_common(0);

View File

@@ -86,15 +86,15 @@
#define ESDI_IOADDR_SEC 0x3518
#define ESDI_IRQCHAN 14
#define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin"
#define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin"
#define BIOS_FILE_L "roms/hdd/esdi/62-000193-036.BIN"
#define BIOS_FILE_H "roms/hdd/esdi/62-000194-036.BIN"
#define ESDI_TIME (200*TIMER_USEC)
#define ESDI_TIME 512
#define CMD_ADAPTER 0
typedef struct esdi_drive {
typedef struct esdi_drive_t {
int spt, hpc;
int tracks;
int sectors;
@@ -102,7 +102,7 @@ typedef struct esdi_drive {
int hdd_num;
} drive_t;
typedef struct esdi {
typedef struct esdi_t {
int8_t dma;
uint32_t bios;
@@ -133,7 +133,7 @@ typedef struct esdi {
int command;
int cmd_state;
int in_reset;
int in_reset, in_reset2;
uint64_t callback;
pc_timer_t timer;
@@ -240,10 +240,10 @@ esdi_mca_set_callback(esdi_t *dev, uint64_t callback)
if (callback) {
dev->callback = callback;
timer_set_delay_u64(&dev->timer, dev->callback);
timer_on_auto(&dev->timer, dev->callback);
} else {
dev->callback = 0;
timer_disable(&dev->timer);
timer_stop(&dev->timer);
}
}
@@ -824,11 +824,18 @@ esdi_read(uint16_t port, void *priv)
uint8_t ret = 0xff;
switch (port & 7) {
case 2: /*Basic status register*/
case 2: /*Basic status register*/
if (!dev->status) {
if (((dev->command == CMD_WRITE) || dev->in_reset2) && !dev->cmd_dev) {
dev->in_reset2 = 0;
dev->status |= STATUS_STATUS_OUT_FULL;
} else if (dev->command && (dev->cmd_dev == ATTN_HOST_ADAPTER))
dev->status |= STATUS_STATUS_OUT_FULL;
}
ret = dev->status;
break;
case 3: /*IRQ status*/
case 3: /*IRQ status*/
dev->status &= ~STATUS_IRQ;
ret = dev->irq_status;
break;
@@ -852,6 +859,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
case 2: /*Basic control register*/
if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) {
dev->in_reset = 1;
dev->in_reset2 = 1;
esdi_mca_set_callback(dev, ESDI_TIME * 50);
dev->status = STATUS_BUSY;
}
@@ -883,6 +891,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
case ATTN_RESET:
dev->in_reset = 1;
dev->in_reset2 = 1;
esdi_mca_set_callback(dev, ESDI_TIME * 50);
dev->status = STATUS_BUSY;
break;
@@ -1143,6 +1152,7 @@ esdi_init(const device_t *info)
/* Mark for a reset. */
dev->in_reset = 1;
dev->in_reset2 = 1;
esdi_mca_set_callback(dev, ESDI_TIME * 50);
dev->status = STATUS_BUSY;

View File

@@ -220,7 +220,7 @@ ide_get_drive(int ch)
double
ide_get_period(ide_t *ide, int size)
ide_get_xfer_time(ide_t *ide, int size)
{
double period = (10.0 / 3.0);
@@ -313,7 +313,7 @@ ide_atapi_get_period(uint8_t channel)
return -1.0;
}
return ide_get_period(ide, 1);
return ide_get_xfer_time(ide, 1);
}
@@ -535,7 +535,7 @@ static void ide_hd_identify(ide_t *ide)
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
ide->buffer[0] = (1 << 6); /*Fixed drive*/
ide->buffer[20] = 3; /*Buffer type*/
ide->buffer[21] = 512; /*Buffer size*/
ide->buffer[21] = hdd[ide->hdd_num].cache.num_segments * hdd[ide->hdd_num].cache.segment_size; /*Buffer size*/
ide->buffer[50] = 0x4000; /* Capabilities */
ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0;
@@ -577,12 +577,11 @@ static void ide_hd_identify(ide_t *ide)
ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]);
}
ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; /*Max sectors on multiple transfer command*/
if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board]) {
ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/
ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/
ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/
} else {
ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/
ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/
}
}
@@ -692,13 +691,15 @@ ide_get_sector(ide_t *ide)
uint32_t heads, sectors;
if (ide->lba)
return (off64_t)ide->lba_addr + ide->skip512;
return (off64_t)ide->lba_addr;
else {
heads = ide->cfg_hpc;
sectors = ide->cfg_spt;
uint8_t sector = ide->sector ? ide->sector : 1;
return ((((off64_t) ide->cylinder * heads) + ide->head) *
sectors) + (ide->sector - 1) + ide->skip512;
sectors) + (sector - 1);
}
}
@@ -733,6 +734,8 @@ loadhd(ide_t *ide, int d, const char *fn)
return;
}
hdd_preset_auto(&hdd[d]);
ide->spt = ide->cfg_spt = hdd[d].spt;
ide->hpc = ide->cfg_hpc = hdd[d].hpc;
ide->tracks = hdd[d].tracks;
@@ -1226,31 +1229,41 @@ ide_write_data(ide_t *ide, uint32_t val, int length)
if (ide->type == IDE_ATAPI)
ide_atapi_packet_write(ide, val, length);
} else {
switch(length) {
case 1:
idebufferb[ide->pos] = val & 0xff;
ide->pos++;
break;
case 2:
idebufferw[ide->pos >> 1] = val & 0xffff;
ide->pos += 2;
break;
case 4:
idebufferl[ide->pos >> 2] = val;
ide->pos += 4;
break;
default:
return;
}
switch(length) {
case 1:
idebufferb[ide->pos] = val & 0xff;
ide->pos++;
break;
case 2:
idebufferw[ide->pos >> 1] = val & 0xffff;
ide->pos += 2;
break;
case 4:
idebufferl[ide->pos >> 2] = val;
ide->pos += 4;
break;
default:
return;
}
if (ide->pos >= 512) {
ide->pos=0;
ide->atastat = BSY_STAT;
if (ide->command == WIN_WRITE_MULTIPLE)
ide_callback(ide);
else
ide_set_callback(ide, ide_get_period(ide, 512));
}
if (ide->pos >= 512) {
ide->pos=0;
ide->atastat = BSY_STAT;
double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
double xfer_time = ide_get_xfer_time(ide, 512);
double wait_time = seek_time + xfer_time;
if (ide->command == WIN_WRITE_MULTIPLE) {
if ((ide->blockcount+1) >= ide->blocksize || ide->secount == 1) {
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
ide->pending_delay = 0;
} else {
ide->pending_delay += wait_time;
ide_callback(ide);
}
} else {
ide_set_callback(ide, wait_time);
}
}
}
}
@@ -1601,9 +1614,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
else
ide->atastat = READY_STAT | BSY_STAT;
if (ide->type == IDE_ATAPI)
if (ide->type == IDE_ATAPI) {
ide->sc->callback = 100.0 * IDE_TIME;
ide_set_callback(ide, 100.0 * IDE_TIME);
ide_set_callback(ide, 100.0 * IDE_TIME);
} else {
double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0);
ide_set_callback(ide, seek_time);
}
return;
}
@@ -1641,15 +1658,26 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide->atastat = BSY_STAT;
if (ide->type == IDE_HDD) {
uint32_t sec_count;
double wait_time;
if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) {
if (ide->secount)
ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9));
else
ide_set_callback(ide, ide_get_period(ide, 131072));
} else if (val == WIN_READ_MULTIPLE)
ide_set_callback(ide, 200.0 * IDE_TIME);
else
ide_set_callback(ide, ide_get_period(ide, 512));
// TODO make DMA timing more accurate
sec_count = ide->secount ? ide->secount : 256;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
wait_time = seek_time > xfer_time ? seek_time : xfer_time;
} else if (val == WIN_READ_MULTIPLE) {
sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
wait_time = seek_time + xfer_time;
} else {
sec_count = 1;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
wait_time = seek_time + xfer_time;
}
ide_set_callback(ide, wait_time);
} else
ide_set_callback(ide, 200.0 * IDE_TIME);
ide->do_initial_read = 1;
@@ -1690,14 +1718,16 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
if ((ide->type == IDE_HDD) &&
((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) {
if (ide->secount)
ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9));
else
ide_set_callback(ide, ide_get_period(ide, 131072));
uint32_t sec_count = ide->secount ? ide->secount : 256;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
double wait_time = seek_time > xfer_time ? seek_time : xfer_time;
ide_set_callback(ide, wait_time);
} else if ((ide->type == IDE_HDD) &&
((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE)))
ide_set_callback(ide, ide_get_period(ide, 512));
else if (val == WIN_IDENTIFY)
((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) {
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), ide->secount);
ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2));
} else if (val == WIN_IDENTIFY)
ide_callback(ide);
else
ide_set_callback(ide, 200.0 * IDE_TIME);
@@ -1864,10 +1894,20 @@ ide_read_data(ide_t *ide, int length)
if (ide->secount) {
ide_next_sector(ide);
ide->atastat = BSY_STAT | READY_STAT | DSC_STAT;
if (ide->command == WIN_READ_MULTIPLE)
ide_callback(ide);
else
ide_set_callback(ide, ide_get_period(ide, 512));
if (ide->command == WIN_READ_MULTIPLE) {
if (!ide->blockcount) {
uint32_t sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
ide_set_callback(ide, seek_time + xfer_time);
} else {
ide_callback(ide);
}
} else {
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
double xfer_time = ide_get_xfer_time(ide, 512);
ide_set_callback(ide, seek_time + xfer_time);
}
} else if (ide->command != WIN_READ_MULTIPLE)
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
}

View File

@@ -17,15 +17,19 @@
* Copyright 2017-2019 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/hdd.h>
#include <86box/cdrom.h>
#include <86box/video.h>
#include "cpu.h"
hard_disk_t hdd[HDD_NUM];
@@ -150,3 +154,346 @@ hdd_is_valid(int c)
return(1);
}
double
hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time)
{
hdd_zone_t *zone = NULL;
for (int i = 0; i < hdd->num_zones; i++) {
zone = &hdd->zones[i];
if (zone->end_sector >= dst_addr)
break;
}
uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track);
uint32_t new_cylinder = new_track / hdd->phy_heads;
uint32_t cylinder_diff = abs((int)hdd->cur_cylinder - (int)new_cylinder);
bool sequential = dst_addr == hdd->cur_addr + 1;
continuous = continuous && sequential;
double seek_time = 0.0;
if (continuous) {
if (new_track == hdd->cur_track) {
// Same track
seek_time = zone->sector_time_usec;
} else if (!cylinder_diff) {
// Same cylinder, sequential track
seek_time = hdd->head_switch_usec;
} else {
// Sequential cylinder
seek_time = hdd->cyl_switch_usec;
}
} else {
if (!cylinder_diff) {
if (operation != HDD_OP_SEEK) {
seek_time = hdd->avg_rotation_lat_usec;
} else {
//seek_time = hdd->cyl_switch_usec;
seek_time = 50.0;
}
} else {
seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double)cylinder_diff / (double)hdd->phy_cyl);
if (operation != HDD_OP_SEEK) {
seek_time += hdd->avg_rotation_lat_usec;
}
}
}
if (!max_seek_time || seek_time <= max_seek_time) {
hdd->cur_addr = dst_addr;
hdd->cur_track = new_track;
hdd->cur_cylinder = new_cylinder;
}
return seek_time;
}
static void
hdd_readahead_update(hard_disk_t *hdd)
{
hdd_cache_t *cache = &hdd->cache;
if (cache->ra_ongoing) {
hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment];
uint64_t elapsed_cycles = tsc - cache->ra_start_time;
double elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
// Do not overwrite data not yet read by host
uint32_t max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr;
double seek_time = 0.0;
for (uint32_t i = 0; i < max_read_ahead; i++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;
segment->ra_addr++;
}
if (segment->ra_addr > segment->lba_addr + cache->segment_size) {
uint32_t space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size);
segment->lba_addr += space_needed;
}
}
}
static double
hdd_writecache_flush(hard_disk_t *hdd)
{
double seek_time = 0.0;
while (hdd->cache.write_pending) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
hdd->cache.write_addr++;
hdd->cache.write_pending--;
}
return seek_time;
}
static void
hdd_writecache_update(hard_disk_t *hdd)
{
if (hdd->cache.write_pending) {
uint64_t elapsed_cycles = tsc - hdd->cache.write_start_time;
double elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
double seek_time = 0.0;
while (hdd->cache.write_pending) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time);
if (seek_time > elapsed_us)
break;
hdd->cache.write_addr++;
hdd->cache.write_pending--;
}
}
}
double
hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
{
hdd_readahead_update(hdd);
hdd_writecache_update(hdd);
hdd->cache.ra_ongoing = 0;
double seek_time = 0.0;
if (hdd->cache.write_pending && (addr != (hdd->cache.write_addr + hdd->cache.write_pending))) {
// New request is not sequential to existing cache, need to flush it
seek_time += hdd_writecache_flush(hdd);
}
if (!hdd->cache.write_pending) {
// Cache is empty
hdd->cache.write_addr = addr;
}
hdd->cache.write_pending += len;
if (hdd->cache.write_pending > hdd->cache.write_size) {
// If request is bigger than free cache, flush some data first
uint32_t flush_needed = hdd->cache.write_pending - hdd->cache.write_size;
for (uint32_t i = 0; i < flush_needed; i++) {
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
hdd->cache.write_addr++;
}
}
hdd->cache.write_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
return seek_time;
}
double
hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len)
{
hdd_readahead_update(hdd);
hdd_writecache_update(hdd);
double seek_time = 0.0;
seek_time += hdd_writecache_flush(hdd);
hdd_cache_t *cache = &hdd->cache;
hdd_cache_seg_t *active_seg = &cache->segments[0];
for (uint32_t i = 0; i < cache->num_segments; i++) {
hdd_cache_seg_t *segment = &cache->segments[i];
if (!segment->valid) {
active_seg = segment;
continue;
}
if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) {
// Cache HIT
segment->host_addr = addr;
active_seg = segment;
if (addr + len > segment->ra_addr) {
uint32_t need_read = (addr + len) - segment->ra_addr;
for (uint32_t j = 0; j < need_read; j++) {
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0);
segment->ra_addr++;
}
}
if (addr + len > segment->lba_addr + cache->segment_size) {
// Need to erase some previously cached data
uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size);
segment->lba_addr += space_needed;
}
goto update_lru;
} else {
if (segment->lru > active_seg->lru) {
active_seg = segment;
}
}
}
// Cache MISS
active_seg->lba_addr = addr;
active_seg->valid = 1;
active_seg->host_addr = addr;
active_seg->ra_addr = addr;
for (uint32_t i = 0; i < len; i++) {
seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0);
active_seg->ra_addr++;
}
update_lru:
for (uint32_t i = 0; i < cache->num_segments; i++) {
cache->segments[i].lru++;
}
active_seg->lru = 0;
cache->ra_ongoing = 1;
cache->ra_segment = active_seg->id;
cache->ra_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
return seek_time;
}
static void
hdd_cache_init(hard_disk_t *hdd)
{
hdd_cache_t *cache = &hdd->cache;
cache->ra_segment = 0;
cache->ra_ongoing = 0;
cache->ra_start_time = 0;
for (uint32_t i = 0; i < cache->num_segments; i++) {
cache->segments[i].valid = 0;
cache->segments[i].lru = 0;
cache->segments[i].id = i;
cache->segments[i].ra_addr = 0;
cache->segments[i].host_addr = 0;
}
}
static void
hdd_zones_init(hard_disk_t *hdd)
{
uint32_t lba = 0;
uint32_t track = 0;
double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0;
for (uint32_t i = 0; i < hdd->num_zones; i++) {
hdd_zone_t *zone = &hdd->zones[i];
zone->start_sector = lba;
zone->start_track = track;
zone->sector_time_usec = revolution_usec / (double)zone->sectors_per_track;
uint32_t tracks = zone->cylinders * hdd->phy_heads;
lba += tracks * zone->sectors_per_track;
zone->end_sector = lba - 1;
track += tracks - 1;
}
}
hdd_preset_t hdd_presets[] = {
{ .target_year = 1989, .match_max_mbyte = 99, .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8,
.rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 },
{ .target_year = 1992, .match_max_mbyte = 249, .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3500, .full_stroke_ms = 30, .track_seek_ms = 6,
.rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .target_year = 1994, .match_max_mbyte = 999, .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5,
.rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 },
{ .target_year = 1996, .match_max_mbyte = 1999, .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3,
.rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 },
{ .target_year = 1997, .match_max_mbyte = 4999, .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5,
.rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 },
{ .target_year = 1998, .match_max_mbyte = 9999, .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2,
.rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
{ .target_year = 2000, .match_max_mbyte = 99999, .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2,
.rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
};
void
hdd_preset_apply(hard_disk_t *hdd, hdd_preset_t *preset)
{
hdd->phy_heads = preset->heads;
hdd->rpm = preset->rpm;
double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0;
hdd->avg_rotation_lat_usec = revolution_usec / 2;
hdd->full_stroke_usec = preset->full_stroke_ms * 1000;
hdd->head_switch_usec = preset->track_seek_ms * 1000;
hdd->cyl_switch_usec = preset->track_seek_ms * 1000;
hdd->cache.num_segments = preset->rcache_num_seg;
hdd->cache.segment_size = preset->rcache_seg_size;
hdd->max_multiple_block = preset->max_multiple;
hdd->cache.write_size = 64;
hdd->num_zones = preset->zones;
uint32_t disk_sectors = hdd->tracks * hdd->hpc * hdd->spt;
uint32_t sectors_per_surface = (uint32_t)ceil((double)disk_sectors / (double)hdd->phy_heads);
uint32_t cylinders = (uint32_t)ceil((double)sectors_per_surface / (double)preset->avg_spt);
hdd->phy_cyl = cylinders;
uint32_t cylinders_per_zone = cylinders / preset->zones;
uint32_t total_sectors = 0;
for (uint32_t i = 0; i < preset->zones; i++) {
uint32_t spt;
double zone_percent = i * 100 / (double)preset->zones;
if (i < preset->zones - 1) {
// Function for realistic zone sector density
double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48;
spt = (uint32_t)ceil((double)preset->avg_spt * spt_percent / 100);
} else {
spt = (uint32_t)ceil((double)(disk_sectors - total_sectors) / (double)(cylinders_per_zone*preset->heads));
}
uint32_t zone_sectors = spt * cylinders_per_zone * preset->heads;
total_sectors += zone_sectors;
hdd->zones[i].cylinders = cylinders_per_zone;
hdd->zones[i].sectors_per_track = spt;
}
hdd_zones_init(hdd);
hdd_cache_init(hdd);
}
void
hdd_preset_auto(hard_disk_t *hdd)
{
uint32_t disk_sectors = hdd->tracks * hdd->hpc * hdd->spt;
uint32_t disk_size_mb = disk_sectors * 512 / 1024 / 1024;
int i;
for (i = 0; i < (sizeof(hdd_presets) / sizeof(hdd_presets[0])); i++) {
if (hdd_presets[i].match_max_mbyte >= disk_size_mb)
break;
}
hdd_preset_t *preset = &hdd_presets[i];
hdd_preset_apply(hdd, preset);
}

View File

@@ -49,7 +49,7 @@ typedef struct ide_s {
blocksize, blockcount,
hdd_num, channel,
pos, sector_pos,
lba, skip512,
lba,
reset, mdma_mode,
do_initial_read;
uint32_t secount, sector,
@@ -67,6 +67,7 @@ typedef struct ide_s {
/* Stuff mostly used by ATAPI */
scsi_common_t *sc;
int interrupt_drq;
double pending_delay;
int (*get_max)(int ide_has_dma, int type);
int (*get_timings)(int ide_has_dma, int type);

View File

@@ -72,6 +72,62 @@ enum {
};
#endif
enum {
HDD_OP_SEEK = 0,
HDD_OP_READ,
HDD_OP_WRITE
};
#define HDD_MAX_ZONES 16
#define HDD_MAX_CACHE_SEG 16
typedef struct {
uint32_t match_max_mbyte;
uint32_t zones;
uint32_t avg_spt;
uint32_t heads;
uint32_t rpm;
uint32_t target_year;
uint32_t rcache_num_seg;
uint32_t rcache_seg_size;
uint32_t max_multiple;
double full_stroke_ms;
double track_seek_ms;
} hdd_preset_t;
typedef struct {
uint32_t id;
uint32_t lba_addr;
uint32_t ra_addr;
uint32_t host_addr;
uint8_t lru;
uint8_t valid;
} hdd_cache_seg_t;
typedef struct {
// Read cache
hdd_cache_seg_t segments[HDD_MAX_CACHE_SEG];
uint32_t num_segments;
uint32_t segment_size;
uint32_t ra_segment;
uint8_t ra_ongoing;
uint64_t ra_start_time;
// Write cache
uint32_t write_addr;
uint32_t write_pending;
uint32_t write_size;
uint64_t write_start_time;
} hdd_cache_t;
typedef struct {
uint32_t cylinders;
uint32_t sectors_per_track;
double sector_time_usec;
uint32_t start_sector;
uint32_t end_sector;
uint32_t start_track;
} hdd_zone_t;
/* Define the virtual Hard Disk. */
typedef struct {
@@ -100,6 +156,23 @@ typedef struct {
spt,
hpc, /* Physical geometry parameters */
tracks;
hdd_zone_t zones[HDD_MAX_ZONES];
uint32_t num_zones;
hdd_cache_t cache;
uint32_t phy_cyl;
uint32_t phy_heads;
uint32_t rpm;
uint8_t max_multiple_block;
uint32_t cur_cylinder;
uint32_t cur_track;
uint32_t cur_addr;
double avg_rotation_lat_usec;
double full_stroke_usec;
double head_switch_usec;
double cyl_switch_usec;
} hard_disk_t;
@@ -131,5 +204,10 @@ extern int image_is_hdi(const char *s);
extern int image_is_hdx(const char *s, int check_signature);
extern int image_is_vhd(const char *s, int check_signature);
extern double hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len);
extern double hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len);
extern double hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time);
extern void hdd_preset_apply(hard_disk_t *hdd, hdd_preset_t *preset);
extern void hdd_preset_auto(hard_disk_t *hdd);
#endif /*EMU_HDD_H*/

View File

@@ -18,6 +18,7 @@
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2018,2019 David Hrdlička.
* Copyright 2021-2022 Jasmine Iwanek.
*/
#ifndef WIN_RESOURCE_H
@@ -184,6 +185,8 @@
#define IDC_CHECK_VOODOO 1022
#define IDC_BUTTON_VOODOO 1023
#define IDC_CHECK_IBM8514 1024
#define IDC_CHECK_XGA 1025
#define IDC_BUTTON_XGA 1026
#define IDC_INPUT 1030 /* input config */
#define IDC_COMBO_MOUSE 1031

View File

@@ -26,6 +26,7 @@
extern const device_t scsi_lcs6821n_device;
extern const device_t scsi_rt1000b_device;
extern const device_t scsi_rt1000mc_device;
extern const device_t scsi_t128_device;
extern const device_t scsi_t130b_device;
extern const device_t scsi_ls2000_device;

View File

@@ -22,7 +22,7 @@
#define EMU_VERSION "@CMAKE_PROJECT_VERSION@"
#define EMU_VERSION_W LSTR(EMU_VERSION)
#define EMU_VERSION_EX "@EMU_VERSION_EX@"
#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */
#define EMU_VERSION_MAJ @CMAKE_PROJECT_VERSION_MAJOR@
#define EMU_VERSION_MIN @CMAKE_PROJECT_VERSION_MINOR@
#define EMU_VERSION_PATCH @CMAKE_PROJECT_VERSION_PATCH@

View File

@@ -62,9 +62,10 @@ typedef struct ibm8514_t
int x1, x2, y1, y2;
int sys_cnt, sys_cnt2;
int temp_cnt;
int16_t cx, cy;
int sx, sy;
int dx, dy;
int16_t cx, cy, oldcy;
int16_t sx, sy;
int16_t dx, dy;
int16_t err;
uint32_t src, dest;
uint32_t newsrc_blt, newdest_blt;
uint32_t newdest_in, newdest_out;
@@ -79,7 +80,7 @@ typedef struct ibm8514_t
int odd_in, odd_out;
uint16_t scratch;
int fill_state, fill_drop;
int fill_state, xdir, ydir;
} accel;
uint16_t test;

View File

@@ -63,6 +63,8 @@ typedef struct xga_t
uint8_t pal_g, pal_g_prefetch;
uint8_t pal_b, pal_b_prefetch;
uint8_t sprite_data[1024];
uint8_t scrollcache;
uint8_t direct_color;
uint8_t *vram, *changedvram;
int16_t hwc_pos_x;
@@ -88,11 +90,10 @@ typedef struct xga_t
char_width, hwcursor_on;
int pal_pos, pal_pos_prefetch;
int on;
int op_mode_reset;
int op_mode_reset, linear_endian_reverse;
int sprite_pos, sprite_pos_prefetch, cursor_data_on;
int pal_test;
int dma_channel;
int from_to_vram;
int type, bus;
uint32_t linear_base, linear_size, banked_mask;
uint32_t base_addr_1mb;

View File

@@ -0,0 +1,22 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* IBM XGA emulation.
*
*
*
* Authors: TheCollector1995.
*
* Copyright 2022 TheCollector1995.
*/
#ifndef VIDEO_XGA_DEVICE_H
# define VIDEO_XGA_DEVICE_H
extern const device_t xga_device;
extern const device_t xga_isa_device;
#endif /*VIDEO_XGA_DEVICE_H*/

View File

@@ -20,11 +20,11 @@
#define EMU_NAME "86Box"
#define EMU_NAME_W LSTR(EMU_NAME)
#define EMU_VERSION "3.5"
#define EMU_VERSION "3.6"
#define EMU_VERSION_W LSTR(EMU_VERSION)
#define EMU_VERSION_EX "3.50"
#define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */
#define EMU_VERSION_MAJ 3
#define EMU_VERSION_MIN 5
#define EMU_VERSION_MIN 6
#define EMU_VERSION_PATCH 0
#define EMU_BUILD_NUM 0
@@ -40,7 +40,7 @@
#define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest"
#define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL)
#ifdef RELEASE_BUILD
# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.5/"
# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.6/"
#else
# define EMU_DOCS_URL "https://86box.readthedocs.io"
#endif

View File

@@ -240,12 +240,24 @@ if(WIN32)
# needed for static builds
qt_import_plugins(plat INCLUDE Qt${QT_MAJOR}::QWindowsIntegrationPlugin Qt${QT_MAJOR}::QICOPlugin Qt${QT_MAJOR}::QWindowsVistaStylePlugin)
else()
install(CODE "
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE)
execute_process(
COMMAND $<TARGET_FILE:Qt${QT_MAJOR}::windeployqt>
\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$<TARGET_FILE_NAME:86Box>\")
")
if(USE_QT6)
install(CODE "
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE)
execute_process(
COMMAND $<TARGET_FILE:Qt${QT_MAJOR}::windeployqt>
\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$<TARGET_FILE_NAME:86Box>\")
")
else()
find_program(WINDEPLOYQT_EXECUTABLE windeployqt)
if(WINDEPLOYQT_EXECUTABLE)
install(CODE "
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE)
execute_process(
COMMAND ${WINDEPLOYQT_EXECUTABLE}
\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/$<TARGET_FILE_NAME:86Box>\")
")
endif()
endif()
endif()
endif()

View File

@@ -36,6 +36,7 @@ extern "C" {
#include <86box/config.h>
#include <86box/keyboard.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/discord.h>
#include <86box/video.h>
#include <86box/machine.h>
@@ -1448,18 +1449,25 @@ void MainWindow::refreshMediaMenu() {
ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA));
}
void MainWindow::showMessage(const QString& header, const QString& message) {
void MainWindow::showMessage(int flags, const QString& header, const QString& message) {
if (QThread::currentThread() == this->thread()) {
showMessage_(header, message);
showMessage_(flags, header, message);
} else {
emit showMessageForNonQtThread(header, message);
emit showMessageForNonQtThread(flags, header, message);
}
}
void MainWindow::showMessage_(const QString &header, const QString &message) {
void MainWindow::showMessage_(int flags, const QString &header, const QString &message) {
QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this);
if (flags & (MBX_FATAL)) {
box.setIcon(QMessageBox::Critical);
}
else if (!(flags & (MBX_ERROR | MBX_WARNING))) {
box.setIcon(QMessageBox::Warning);
}
box.setTextFormat(Qt::TextFormat::RichText);
box.exec();
if (cpu_thread_run == 0) QApplication::exit(-1);
}
void MainWindow::keyPressEvent(QKeyEvent* event)

View File

@@ -24,7 +24,7 @@ public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void showMessage(const QString& header, const QString& message);
void showMessage(int flags, const QString& header, const QString& message);
void getTitle(wchar_t* title);
void blitToWidget(int x, int y, int w, int h);
QSize getRenderWidgetSize();
@@ -45,7 +45,7 @@ signals:
void setFullscreen(bool state);
void setMouseCapture(bool state);
void showMessageForNonQtThread(const QString& header, const QString& message);
void showMessageForNonQtThread(int flags, const QString& header, const QString& message);
void getTitleForNonQtThread(wchar_t* title);
public slots:
void showSettings();
@@ -100,7 +100,7 @@ private slots:
void on_actionRenderer_options_triggered();
void refreshMediaMenu();
void showMessage_(const QString& header, const QString& message);
void showMessage_(int flags, const QString& header, const QString& message);
void getTitle_(wchar_t* title);
void on_actionMCA_devices_triggered();

View File

@@ -244,6 +244,7 @@ RendererStack::switchRenderer(Renderer renderer)
createRenderer(renderer);
disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy);
blitDummied = false;
QTimer::singleShot(1000, this, [this]() { this->blitDummied = false; } );
});
rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater();

View File

@@ -24,6 +24,7 @@ extern "C" {
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/video.h>
#include <86box/vid_xga_device.h>
}
#include "qt_deviceconfig.hpp"
@@ -102,6 +103,14 @@ void SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() {
DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast<Settings*>(Settings::settings));
}
void SettingsDisplay::on_pushButtonConfigureXga_clicked() {
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast<Settings*>(Settings::settings));
} else {
DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast<Settings*>(Settings::settings));
}
}
void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) {
if (index < 0) {
return;
@@ -126,8 +135,14 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) {
ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA);
if (hasIsa16 || has_MCA)
ui->checkBoxXga->setChecked(xga_enabled);
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked());
}
void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) {
ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked);
}
void SettingsDisplay::on_checkBoxXga_stateChanged(int state) {
ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked);
}

View File

@@ -22,8 +22,10 @@ public slots:
private slots:
void on_checkBoxVoodoo_stateChanged(int state);
void on_checkBoxXga_stateChanged(int state);
void on_comboBoxVideo_currentIndexChanged(int index);
void on_pushButtonConfigureVoodoo_clicked();
void on_pushButtonConfigureXga_clicked();
void on_pushButtonConfigure_clicked();
private:

View File

@@ -70,6 +70,13 @@
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="pushButtonConfigureXga">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkBoxXga">
<property name="text">

View File

@@ -93,7 +93,7 @@ int ui_msgbox_header(int flags, void *header, void* message) {
msgBox.exec();
} else {
// else scope it to main_window
main_window->showMessage(hdr, msg);
main_window->showMessage(flags, hdr, msg);
}
return 0;
}

View File

@@ -86,6 +86,7 @@ static SCSI_CARD scsi_cards[] = {
{ &scsi_ls2000_device, },
{ &scsi_lcs6821n_device, },
{ &scsi_rt1000b_device, },
{ &scsi_rt1000mc_device, },
{ &scsi_t128_device, },
{ &scsi_t130b_device, },
#ifdef WALTJE

View File

@@ -156,6 +156,7 @@ typedef struct {
double period;
int ncr_busy;
uint8_t pos_regs[8];
} ncr5380_t;
#define STATE_IDLE 0
@@ -749,6 +750,11 @@ ncr_read(uint16_t port, void *priv)
break;
case 2: /* Mode register */
if (((ncr->mode & 0x30) == 0x30) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))
ncr->mode = 0;
if (((ncr->mode & 0x20) == 0x20) && (ncr_dev->type == 0))
ncr->mode = 0;
ncr_log("Read: Mode register\n");
ret = ncr->mode;
break;
@@ -764,6 +770,10 @@ ncr_read(uint16_t port, void *priv)
ncr_bus_read(ncr_dev);
ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff);
ret |= (ncr->cur_bus & 0xff);
if ((ncr->icr & ICR_SEL) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))
ret |= 0x02;
if ((ncr->icr & ICR_BSY) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))
ret |= 0x40;
break;
case 5: /* Bus and Status register */
@@ -782,9 +792,9 @@ ncr_read(uint16_t port, void *priv)
ncr_bus_read(ncr_dev);
bus = ncr->cur_bus;
if (bus & BUS_ACK)
if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))))
ret |= STATUS_ACK;
if (bus & BUS_ATN)
if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))))
ret |= 0x02;
if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) {
@@ -920,8 +930,6 @@ memio_write(uint32_t addr, uint8_t val, void *priv)
addr &= 0x3fff;
ncr_log("memio_write(%08x,%02x) %i %02x\n", addr, val, ncr_dev->buffer_host_pos, ncr_dev->status_ctrl);
if (addr >= 0x3a00)
ncr_dev->ext_ram[addr - 0x3a00] = val;
else switch (addr & 0x3f80) {
@@ -1428,6 +1436,64 @@ t128_write(uint32_t addr, uint8_t val, void *priv)
}
}
static uint8_t
rt1000b_mc_read(int port, void *priv)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
return(ncr_dev->pos_regs[port & 7]);
}
static void
rt1000b_mc_write(int port, uint8_t val, void *priv)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
/* MCA does not write registers below 0x0100. */
if (port < 0x0102) return;
mem_mapping_disable(&ncr_dev->bios_rom.mapping);
mem_mapping_disable(&ncr_dev->mapping);
/* Save the MCA register value. */
ncr_dev->pos_regs[port & 7] = val;
if (ncr_dev->pos_regs[2] & 1) {
switch (ncr_dev->pos_regs[2] & 0xe0) {
case 0:
ncr_dev->rom_addr = 0xd4000;
break;
case 0x20:
ncr_dev->rom_addr = 0xd0000;
break;
case 0x40:
ncr_dev->rom_addr = 0xcc000;
break;
case 0x60:
ncr_dev->rom_addr = 0xc8000;
break;
case 0xc0:
ncr_dev->rom_addr = 0xdc000;
break;
case 0xe0:
ncr_dev->rom_addr = 0xd8000;
break;
}
mem_mapping_set_addr(&ncr_dev->bios_rom.mapping, ncr_dev->rom_addr, 0x4000);
mem_mapping_set_addr(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000);
}
}
static uint8_t
rt1000b_mc_feedb(void *priv)
{
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
return ncr_dev->pos_regs[2] & 1;
}
static void *
ncr_init(const device_t *info)
{
@@ -1455,10 +1521,14 @@ ncr_init(const device_t *info)
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
break;
case 1: /* Rancho RT1000B */
case 1: /* Rancho RT1000B/MC */
ncr_dev->rom_addr = device_get_config_hex20("bios_addr");
ncr_dev->irq = device_get_config_int("irq");
ncr_dev->bios_ver = device_get_config_int("bios_ver");
if (info->flags & DEVICE_MCA) {
ncr_dev->rom_addr = 0xd8000;
ncr_dev->bios_ver = 1;
}
if (ncr_dev->bios_ver == 1)
fn = RT1000B_820R_ROM;
@@ -1468,10 +1538,20 @@ ncr_init(const device_t *info)
rom_init(&ncr_dev->bios_rom, fn,
ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000,
memio_read, NULL, NULL,
memio_write, NULL, NULL,
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
if (info->flags & DEVICE_MCA) {
mem_mapping_add(&ncr_dev->mapping, 0, 0,
memio_read, NULL, NULL,
memio_write, NULL, NULL,
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
ncr_dev->pos_regs[0] = 0x8d;
ncr_dev->pos_regs[1] = 0x70;
mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev);
} else {
mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000,
memio_read, NULL, NULL,
memio_write, NULL, NULL,
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
}
break;
case 2: /* Trantor T130B */
@@ -1573,6 +1653,12 @@ rt1000b_available(void)
return(rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM));
}
static int
rt1000b_820_available(void)
{
return(rom_present(RT1000B_820R_ROM));
}
static int
t130b_available(void)
{
@@ -1604,6 +1690,8 @@ static const device_config_t ncr5380_mmio_config[] = {
.selection = {
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "" }
@@ -1639,6 +1727,8 @@ static const device_config_t rancho_config[] = {
.selection = {
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "" }
@@ -1676,6 +1766,25 @@ static const device_config_t rancho_config[] = {
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t rancho_mc_config[] = {
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 5,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "" }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t t130b_config[] = {
{
.name = "bios_addr",
@@ -1740,6 +1849,8 @@ static const device_config_t t128_config[] = {
.selection = {
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "" }
@@ -1799,6 +1910,20 @@ const device_t scsi_rt1000b_device = {
.config = rancho_config
};
const device_t scsi_rt1000mc_device = {
.name = "Rancho RT1000B-MC",
.internal_name = "rt1000mc",
.flags = DEVICE_MCA,
.local = 1,
.init = ncr_init,
.close = ncr_close,
.reset = NULL,
{ .available = rt1000b_820_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = rancho_mc_config
};
const device_t scsi_t130b_device = {
.name = "Trantor T130B",
.internal_name = "t130b",

View File

@@ -12,10 +12,10 @@
# 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 20220523
%global romver 20220701
Name: 86Box
Version: 3.5
Version: 3.6
Release: 1%{?dist}
Summary: Classic PC emulator
License: GPLv2+
@@ -120,5 +120,5 @@ popd
%{_bindir}/roms
%changelog
* Mon May 23 2022 Robert de Rooy <robert.de.rooy[AT]gmail.com> 3.5-1
* Fri Jul 01 2022 Robert de Rooy <robert.de.rooy[AT]gmail.com> 3.6-1
- Bump release

View File

@@ -10,7 +10,7 @@
</categories>
<launchable type="desktop-id">net.86box.86Box.desktop</launchable>
<releases>
<release version="3.5" date="2022-04-26"/>
<release version="3.6" date="2022-06-27"/>
</releases>
<content_rating type="oars-1.1" />
<description>

View File

@@ -63,7 +63,7 @@ static void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_da
static void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len);
#define READ_PIXTRANS_WORD(cx, n) \
if (cmd <= 1) { \
if (cmd <= 1 || (cmd == 5)) { \
temp = dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n)) & dev->vram_mask]; \
temp |= (dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n + 1)) & dev->vram_mask] << 8); \
} else { \
@@ -248,8 +248,8 @@ regular_nibble:
nibble |= 0x01;
}
if ((and3 == 0) || (dev->accel.cmd & 0x1000) || (dev->accel.cmd & 8)) {
if (dev->accel.cmd & 8) {
if ((and3 == 0) || (dev->accel.cmd & 0x1000) || ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev))) {
if ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev)) {
monoxfer = val;
} else
monoxfer = nibble;
@@ -1117,6 +1117,8 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t
ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, dev, len);
}
#define SWAP(a,b) { tmpswap = a; a = b; b = tmpswap; }
static void
ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len)
{
@@ -1137,6 +1139,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
uint32_t old_mix_dat;
int and3 = dev->accel.cur_x & 3;
uint8_t poly_src = 0;
int16_t tmpswap;
if (dev->accel.cmd & 0x100) {
dev->force_busy = 1;
@@ -1302,6 +1305,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
case 1: /*Draw line*/
if (!cpu_input) {
dev->accel.xx_count = 0;
dev->accel.cx = dev->accel.cur_x;
dev->accel.cy = dev->accel.cur_y;
@@ -1315,6 +1319,35 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
dev->accel.sy = dev->accel.maj_axis_pcnt;
if (ibm8514_cpu_src(dev)) {
if (dev->accel.cmd & 2) {
if (dev->accel.cmd & 8) {
if (and3 == 1) {
dev->accel.sy += 4;
if (dev->accel.cmd & 0x20)
dev->accel.cx += 4;
else
dev->accel.cx -= 4;
} else if (and3 == 2) {
dev->accel.sy += 5;
if (dev->accel.cmd & 0x20)
dev->accel.cx += 5;
else
dev->accel.cx -= 5;
} else if (and3 == 3) {
dev->accel.sy += 6;
if (dev->accel.cmd & 0x20)
dev->accel.cx += 6;
else
dev->accel.cx -= 6;
} else {
dev->accel.sy += 3;
if (dev->accel.cmd & 0x20)
dev->accel.cx += 3;
else
dev->accel.cx -= 3;
}
}
}
dev->data_available = 0;
dev->data_available2 = 0;
return; /*Wait for data from CPU*/
@@ -1326,6 +1359,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
}
if (dev->accel.cmd & 8) { /*Vector Line*/
if (ibm8514_cpu_dest(dev) && cpu_input && (dev->accel.cmd & 2))
count >>= 1;
dev->accel.xx_count++;
while (count-- && (dev->accel.sy >= 0)) {
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
@@ -1361,11 +1397,71 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
old_dest_dat = dest_dat;
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if (ibm8514_cpu_src(dev) || !cpu_input) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
if ((dev->accel.cmd & 2) && ibm8514_cpu_src(dev)) {
if (and3 == 1) {
if (dev->accel.xx_count >= 2) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
} else if (and3 == 2) {
if (dev->accel.xx_count == 2) {
if (count <= 2) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
} else if (dev->accel.xx_count >= 3) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
} else if (and3 == 3) {
if (dev->accel.xx_count == 2) {
if (count <= 1) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
} else if (dev->accel.xx_count >= 3) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
} else {
if (dev->accel.xx_count == 1) {
if (!count) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
} else if (dev->accel.xx_count >= 2) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
}
} else {
if (ibm8514_cpu_src(dev) || !cpu_input) {
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
}
}
@@ -1576,15 +1672,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
dev->accel.sy = dev->accel.multifunc[0] & 0x7ff;
dev->accel.cx = dev->accel.cur_x & 0x3ff;
dev->accel.cy = dev->accel.cur_y & 0x3ff;
if (dev->accel.cur_x & 0x400)
dev->accel.cx |= ~0x3ff;
dev->accel.cy = dev->accel.cur_y & 0x3ff;
if (dev->accel.cur_y & 0x400)
dev->accel.cy |= ~0x3ff;
dev->accel.fill_state = 0;
dev->accel.dest = dev->accel.cy * dev->h_disp;
dev->accel.fill_state = 0;
if (cmd == 4)
dev->accel.cmd |= 2;
@@ -1644,6 +1739,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
dev->accel.input = 1;
dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp;
}
} else if (dev->accel.cmd & 2) {
if (dev->accel.cmd & 8) {
dev->accel.sx += and3;
dev->accel.nibbleset = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1);
dev->accel.writemono = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1);
dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1;
}
}
dev->data_available = 1;
dev->data_available2 = 1;
@@ -1654,25 +1756,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (dev->accel.cmd & 2) {
if (cpu_input) {
rect_fill_pix:
if (dev->accel.cmd & 8) {
if ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev)) {
dev->accel.xx_count++;
while (count-- && (dev->accel.sy >= 0)) {
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) {
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
} else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) {
/* Mix data = current video memory value. */
READ(dev->accel.dest + dev->accel.cx, mix_dat);
mix_dat = ((mix_dat & rd_mask) == rd_mask);
mix_dat = mix_dat ? mix_mask : 0;
}
if (ibm8514_cpu_dest(dev)) {
READ(dev->accel.dest + dev->accel.cx, src_dat);
if (pixcntl == 3)
src_dat = ((src_dat & rd_mask) == rd_mask);
} else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0: src_dat = bkgd_color; break;
case 1: src_dat = frgd_color; break;
case 2: src_dat = cpu_dat & 0xff; break;
@@ -2322,7 +2411,7 @@ rect_fill:
}
}
} else {
if (dev->accel.multifunc[0x0a] & 4) {
if (dev->accel.multifunc[0x0a] & 6) {
while (count-- && dev->accel.sy >= 0) {
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
@@ -2340,8 +2429,9 @@ rect_fill:
poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon);
}
if (poly_src)
if (poly_src) {
dev->accel.fill_state = !dev->accel.fill_state;
}
if (dev->accel.fill_state) {
READ(dev->accel.dest + dev->accel.cx, dest_dat);
@@ -2364,20 +2454,22 @@ rect_fill:
mix_dat <<= 1;
mix_dat |= 1;
if (dev->accel.cmd & 0x20)
if (dev->accel.cmd & 0x20) {
dev->accel.cx++;
else
} else {
dev->accel.cx--;
}
dev->accel.sx--;
if (dev->accel.sx < 0) {
dev->accel.fill_state = 0;
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
dev->accel.fill_state = 0;
if (dev->accel.cmd & 0x20) {
dev->accel.cx -= (dev->accel.sx) + 1;
} else
} else {
dev->accel.cx += (dev->accel.sx) + 1;
}
if (dev->accel.cmd & 0x80)
dev->accel.cy++;
@@ -2463,22 +2555,12 @@ rect_fill:
if (!cpu_input) {
dev->accel.cx = dev->accel.cur_x;
dev->accel.cy = dev->accel.cur_y;
dev->accel.oldcy = dev->accel.cy;
if (dev->accel.cur_x & 0x400) {
if (dev->accel.cx >= 1024) {
dev->accel.cx = 0;
} else
dev->accel.cx |= ~0x3ff;
}
dev->accel.xdir = (dev->accel.cmd & 0x20) ? 1 : -1;
dev->accel.ydir = (dev->accel.cmd & 0x80) ? 1 : -1;
if (dev->accel.cur_y & 0x400) {
if (dev->accel.cy >= 1024)
dev->accel.cy = 1;
else
dev->accel.cy |= ~0x3ff;
}
dev->accel.sy = dev->accel.maj_axis_pcnt;
dev->accel.sy = 0;
if (ibm8514_cpu_src(dev)) {
dev->data_available = 0;
@@ -2491,240 +2573,69 @@ rect_fill:
}
}
if (dev->accel.cmd & 8) { /*Vector Line*/
while (count-- && (dev->accel.sy >= 0)) {
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) {
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
} else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) {
/* Mix data = current video memory value. */
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat);
mix_dat = ((mix_dat & rd_mask) == rd_mask);
mix_dat = mix_dat ? mix_mask : 0;
}
while (count-- && (dev->accel.sy >= 0)) {
if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx <= clip_r) &&
(dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) {
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0: src_dat = bkgd_color; break;
case 1: src_dat = frgd_color; break;
case 2: src_dat = cpu_dat & 0xff; break;
case 3: src_dat = 0; break;
}
if (ibm8514_cpu_dest(dev)) {
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat);
if (pixcntl == 3)
src_dat = ((src_dat & rd_mask) == rd_mask);
} else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0: src_dat = bkgd_color; break;
case 1: src_dat = frgd_color; break;
case 2: src_dat = cpu_dat & 0xff; break;
case 3: src_dat = 0; break;
}
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
((compare_mode == 0x18) && (dest_dat < compare)) ||
((compare_mode == 0x20) && (dest_dat != compare)) ||
((compare_mode == 0x28) && (dest_dat == compare)) ||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
((compare_mode == 0x38) && (dest_dat > compare))) {
old_dest_dat = dest_dat;
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if ((dev->accel.cmd & 4) && dev->accel.sy) {
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
((compare_mode == 0x18) && (dest_dat < compare)) ||
((compare_mode == 0x20) && (dest_dat != compare)) ||
((compare_mode == 0x28) && (dest_dat == compare)) ||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
((compare_mode == 0x38) && (dest_dat > compare))) {
old_dest_dat = dest_dat;
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) {
if (!dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
} else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == dev->accel.oldcy + 1)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
}
mix_dat <<= 1;
mix_dat |= 1;
cpu_dat >>= 8;
if (dev->accel.sy == 0) {
break;
}
switch (dev->accel.cmd & 0xe0) {
case 0x00: dev->accel.cx++; break;
case 0x20: dev->accel.cx++; dev->accel.cy--; break;
case 0x40: dev->accel.cy--; break;
case 0x60: dev->accel.cx--; dev->accel.cy--; break;
case 0x80: dev->accel.cx--; break;
case 0xa0: dev->accel.cx--; dev->accel.cy++; break;
case 0xc0: dev->accel.cy++; break;
case 0xe0: dev->accel.cx++; dev->accel.cy++; break;
}
dev->accel.sy--;
}
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
} else { /*Bresenham*/
if (pixcntl == 1) {
dev->accel.temp_cnt = 8;
while (count-- && (dev->accel.sy >= 0)) {
if (dev->accel.temp_cnt == 0) {
dev->accel.temp_cnt = 8;
mix_dat = old_mix_dat;
}
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
if (ibm8514_cpu_dest(dev)) {
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat);
} else switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) {
case 0: src_dat = bkgd_color; break;
case 1: src_dat = frgd_color; break;
case 2: src_dat = cpu_dat & 0xff; break;
case 3: src_dat = 0; break;
}
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
mix_dat <<= 1;
mix_dat |= 1;
cpu_dat >>= 8;
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
((compare_mode == 0x18) && (dest_dat < compare)) ||
((compare_mode == 0x20) && (dest_dat != compare)) ||
((compare_mode == 0x28) && (dest_dat == compare)) ||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
((compare_mode == 0x38) && (dest_dat > compare))) {
old_dest_dat = dest_dat;
MIX(mix_dat & 1, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
}
dev->accel.temp_cnt--;
mix_dat >>= 1;
cpu_dat >>= 8;
if (dev->accel.sy == dev->accel.maj_axis_pcnt) {
return;
}
if (dev->accel.sy == 0) {
break;
}
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
dev->accel.err_term += dev->accel.destx_distp;
/*Step minor axis*/
switch (dev->accel.cmd & 0xe0) {
case 0x00: dev->accel.cy--; break;
case 0x20: dev->accel.cy--; break;
case 0x40: dev->accel.cx--; break;
case 0x60: dev->accel.cx++; break;
case 0x80: dev->accel.cy++; break;
case 0xa0: dev->accel.cy++; break;
case 0xc0: dev->accel.cx--; break;
case 0xe0: dev->accel.cx++; break;
}
} else
dev->accel.err_term += dev->accel.desty_axstp;
/*Step major axis*/
switch (dev->accel.cmd & 0xe0) {
case 0x00: dev->accel.cx--; break;
case 0x20: dev->accel.cx++; break;
case 0x40: dev->accel.cy--; break;
case 0x60: dev->accel.cy--; break;
case 0x80: dev->accel.cx--; break;
case 0xa0: dev->accel.cx++; break;
case 0xc0: dev->accel.cy++; break;
case 0xe0: dev->accel.cy++; break;
}
dev->accel.sy--;
if (dev->accel.cmd & 0x40) {
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy += dev->accel.ydir;
if (dev->accel.err_term >= 0) {
dev->accel.err_term += dev->accel.destx_distp;
dev->accel.cx += dev->accel.xdir;
} else {
dev->accel.err_term += dev->accel.desty_axstp;
}
} else {
while (count-- && (dev->accel.sy >= 0)) {
if (dev->accel.cur_x >= 1024) {
dev->accel.cx = 0;
}
if (dev->accel.cur_y >= 1024) {
dev->accel.cy = 1;
}
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) {
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
} else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) {
/* Mix data = current video memory value. */
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat);
mix_dat = ((mix_dat & rd_mask) == rd_mask);
mix_dat = mix_dat ? mix_mask : 0;
}
if (ibm8514_cpu_dest(dev)) {
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat);
if (pixcntl == 3)
src_dat = ((src_dat & rd_mask) == rd_mask);
} else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0: src_dat = bkgd_color; break;
case 1: src_dat = frgd_color; break;
case 2: src_dat = cpu_dat & 0xff; break;
case 3: src_dat = 0; break;
}
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
((compare_mode == 0x18) && (dest_dat < compare)) ||
((compare_mode == 0x20) && (dest_dat != compare)) ||
((compare_mode == 0x28) && (dest_dat == compare)) ||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
((compare_mode == 0x38) && (dest_dat > compare))) {
old_dest_dat = dest_dat;
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if ((dev->accel.cmd & 4) && dev->accel.sy) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
} else if (!(dev->accel.cmd & 4)) {
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
}
}
}
mix_dat <<= 1;
mix_dat |= 1;
cpu_dat >>= 8;
if (dev->accel.sy == 0) {
break;
}
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
dev->accel.err_term += dev->accel.destx_distp;
/*Step minor axis*/
switch (dev->accel.cmd & 0xe0) {
case 0x00: dev->accel.cy--; break;
case 0x20: dev->accel.cy--; break;
case 0x40: dev->accel.cx--; break;
case 0x60: dev->accel.cx++; break;
case 0x80: dev->accel.cy++; break;
case 0xa0: dev->accel.cy++; break;
case 0xc0: dev->accel.cx--; break;
case 0xe0: dev->accel.cx++; break;
}
} else
dev->accel.err_term += dev->accel.desty_axstp;
/*Step major axis*/
switch (dev->accel.cmd & 0xe0) {
case 0x00: dev->accel.cx--; break;
case 0x20: dev->accel.cx++; break;
case 0x40: dev->accel.cy--; break;
case 0x60: dev->accel.cy--; break;
case 0x80: dev->accel.cx--; break;
case 0xa0: dev->accel.cx++; break;
case 0xc0: dev->accel.cy++; break;
case 0xe0: dev->accel.cy++; break;
}
dev->accel.sy--;
dev->accel.cx += dev->accel.xdir;
if (dev->accel.err_term >= 0) {
dev->accel.err_term += dev->accel.destx_distp;
dev->accel.oldcy = dev->accel.cy;
dev->accel.cy += dev->accel.ydir;
} else {
dev->accel.err_term += dev->accel.desty_axstp;
}
}
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
dev->accel.sy++;
}
break;
@@ -3354,71 +3265,6 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga)
buffer32->line[dev->displine + svga->y_add][svga->x_add + dev->h_disp + i] = svga->overscan_color;
}
static void
ibm8514_doblit(int wx, int wy, ibm8514_t *dev, svga_t *svga)
{
int y_add, x_add, y_start, x_start, bottom;
uint32_t *p;
int i, j;
int xs_temp, ys_temp;
y_add = (enable_overscan) ? overscan_y : 0;
x_add = (enable_overscan) ? overscan_x : 0;
y_start = (enable_overscan) ? 0 : (overscan_y >> 1);
x_start = (enable_overscan) ? 0 : (overscan_x >> 1);
bottom = (overscan_y >> 1) + (svga->crtc[8] & 0x1f);
if ((wx <= 0) || (wy <= 0))
return;
xs_temp = wx;
ys_temp = wy + 1;
if (xs_temp < 64)
xs_temp = 640;
if (ys_temp < 32)
ys_temp = 200;
if ((svga->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
/* Screen res has changed.. fix up, and let them know. */
xsize = xs_temp;
ysize = ys_temp;
if ((xsize > 1984) || (ysize > 2016)) {
/* 2048x2048 is the biggest safe render texture, to account for overscan,
we suppress overscan starting from x 1984 and y 2016. */
x_add = 0;
y_add = 0;
suppress_overscan = 1;
} else
suppress_overscan = 0;
/* Block resolution changes while in DPMS mode to avoid getting a bogus
screen width (320). We're already rendering a blank screen anyway. */
set_screen_size(xsize + x_add, ysize + y_add);
if (video_force_resize_get())
video_force_resize_set(0);
}
if ((wx >= 160) && ((wy + 1) >= 120)) {
/* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */
for (i = 0; i < svga->y_add; i++) {
p = &buffer32->line[i & 0x7ff][0];
for (j = 0; j < (xsize + x_add); j++)
p[j] = svga->overscan_color;
}
for (i = 0; i < bottom; i++) {
p = &buffer32->line[(ysize + svga->y_add + i) & 0x7ff][0];
for (j = 0; j < (xsize + x_add); j++)
p[j] = svga->overscan_color;
}
}
video_blit_memtoscreen(x_start, y_start, xsize + x_add, ysize + y_add);
}
void
ibm8514_poll(ibm8514_t *dev, svga_t *svga)
{
@@ -3504,7 +3350,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga)
wx = x;
wy = dev->lastline - dev->firstline;
ibm8514_doblit(wx, wy, dev, svga);
svga_doblit(wx, wy, svga);
dev->firstline = 2000;
dev->lastline = 0;

View File

@@ -254,47 +254,42 @@ ega_render_2bpp_lowres(ega_t *ega)
int x;
uint8_t dat[2];
uint32_t addr, *p;
uint32_t changed_addr;
if ((ega->displine + ega->y_add) < 0)
return;
changed_addr = ega->remap_func(ega, ega->ma);
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (fullchange) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
addr = ega->remap_func(ega, ega->ma);
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
addr = ega->remap_func(ega, ega->ma);
dat[0] = ega->vram[addr];
dat[1] = ega->vram[addr | 0x1];
if (ega->seqregs[1] & 4)
ega->ma += 2;
else
ega->ma += 4;
dat[0] = ega->vram[addr];
dat[1] = ega->vram[addr | 0x1];
if (ega->seqregs[1] & 4)
ega->ma += 2;
else
ega->ma += 4;
ega->ma &= ega->vrammask;
ega->ma &= ega->vrammask;
if (ega->crtc[0x17] & 0x80) {
p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]];
p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]];
} else
memset(p, 0x00, 16 * sizeof(uint32_t));
if (ega->crtc[0x17] & 0x80) {
p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]];
p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]];
} else
memset(p, 0x00, 16 * sizeof(uint32_t));
p += 16;
}
}
p += 16;
}
}
@@ -304,14 +299,10 @@ ega_render_2bpp_highres(ega_t *ega)
int x;
uint8_t dat[2];
uint32_t addr, *p;
uint32_t changed_addr;
if ((ega->displine + ega->y_add) < 0)
return;
changed_addr = ega->remap_func(ega, ega->ma);
if (fullchange) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
@@ -344,7 +335,6 @@ ega_render_2bpp_highres(ega_t *ega)
p += 8;
}
}
}
@@ -354,54 +344,49 @@ ega_render_4bpp_lowres(ega_t *ega)
int x, oddeven;
uint8_t dat, edat[4];
uint32_t addr, *p;
uint32_t changed_addr;
if ((ega->displine + ega->y_add) < 0)
return;
changed_addr = ega->remap_func(ega, ega->ma);
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (fullchange) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
addr = ega->remap_func(ega, ega->ma);
oddeven = 0;
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
addr = ega->remap_func(ega, ega->ma);
oddeven = 0;
if (ega->seqregs[1] & 4) {
oddeven = (addr & 4) ? 1 : 0;
edat[0] = ega->vram[addr | oddeven];
edat[2] = ega->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
ega->ma += 2;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
ega->ma += 4;
}
ega->ma &= ega->vrammask;
if (ega->seqregs[1] & 4) {
oddeven = (addr & 4) ? 1 : 0;
edat[0] = ega->vram[addr | oddeven];
edat[2] = ega->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
ega->ma += 2;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
ega->ma += 4;
}
ega->ma &= ega->vrammask;
if (ega->crtc[0x17] & 0x80) {
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
} else
memset(p, 0x00, 16 * sizeof(uint32_t));
if (ega->crtc[0x17] & 0x80) {
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
} else
memset(p, 0x00, 16 * sizeof(uint32_t));
p += 16;
}
p += 16;
}
}
@@ -412,53 +397,48 @@ ega_render_4bpp_highres(ega_t *ega)
int x, oddeven;
uint8_t dat, edat[4];
uint32_t addr, *p;
uint32_t changed_addr;
if ((ega->displine + ega->y_add) < 0)
return;
changed_addr = ega->remap_func(ega, ega->ma);
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (fullchange) {
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
if (ega->firstline_draw == 2000)
ega->firstline_draw = ega->displine;
ega->lastline_draw = ega->displine;
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) {
addr = ega->remap_func(ega, ega->ma);
oddeven = 0;
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) {
addr = ega->remap_func(ega, ega->ma);
oddeven = 0;
if (ega->seqregs[1] & 4) {
oddeven = (addr & 4) ? 1 : 0;
edat[0] = ega->vram[addr | oddeven];
edat[2] = ega->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
ega->ma += 2;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
ega->ma += 4;
}
ega->ma &= ega->vrammask;
if (ega->seqregs[1] & 4) {
oddeven = (addr & 4) ? 1 : 0;
edat[0] = ega->vram[addr | oddeven];
edat[2] = ega->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
ega->ma += 2;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
ega->ma += 4;
}
ega->ma &= ega->vrammask;
if (ega->crtc[0x17] & 0x80) {
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
} else
memset(p, 0x00, 8 * sizeof(uint32_t));
if (ega->crtc[0x17] & 0x80) {
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
} else
memset(p, 0x00, 8 * sizeof(uint32_t));
p += 8;
}
p += 8;
}
}

View File

@@ -2363,7 +2363,12 @@ pgc_cga_text(pgc_t *dev, int w)
val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
else
val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
buffer32->line[dev->displine][(x * cw) + c] = val;
if (cw == 8) /* 80x25 CGA text screen. */
buffer32->line[dev->displine][(x * cw) + c] = val;
else { /* 40x25 CGA text screen. */
buffer32->line[dev->displine][(x * cw) + (c * 2)] = val;
buffer32->line[dev->displine][(x * cw) + (c * 2) + 1] = val;
}
}
ma++;

View File

@@ -3128,6 +3128,10 @@ static void s3_recalctimings(svga_t *svga)
if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V ||
s3->card_type == S3_NUMBER9_9FX_771))
svga->hdisp <<= 1;
if (s3->card_type == S3_NUMBER9_9FX_771) {
if (svga->hdisp == 832)
svga->hdisp -= 32;
}
if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 ||
s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 ||
s3->card_type == S3_SPEA_MERCURY_P64V) {
@@ -3378,12 +3382,9 @@ s3_updatemapping(s3_t *s3)
mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size);
}
if (s3->chip >= S3_TRIO64V)
svga->fb_only = 1;
svga->fb_only = 1;
} else {
if (s3->chip >= S3_TRIO64V)
svga->fb_only = 0;
svga->fb_only = 0;
mem_mapping_disable(&s3->linear_mapping);
}

View File

@@ -777,7 +777,6 @@ static void s3_virge_recalctimings(svga_t *svga)
if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/
{
svga->fb_only = 0;
svga->ma_latch |= (virge->ma_ext << 16);
if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4;
else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100;
@@ -820,8 +819,6 @@ static void s3_virge_recalctimings(svga_t *svga)
}
else /*Streams mode*/
{
svga->fb_only = 1;
if (virge->streams.buffer_ctrl & 1)
svga->ma_latch = virge->streams.pri_fb1 >> 2;
else

View File

@@ -1076,7 +1076,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) == 4) && (svga->xga.aperture_cntl == 1)) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
if (val == 0xa5) { /*Memory size test of XGA*/
svga->xga.test = val;
return;
@@ -1086,7 +1086,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
} else if (val == 0x12 || val == 0x34) {
addr += svga->xga.write_bank;
svga->xga.vram[addr & svga->xga.vram_mask] = val;
svga->xga.op_mode_reset = 1;
svga->xga.linear_endian_reverse = 1;
return;
}
} else
@@ -1277,7 +1277,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) == 4) && (svga->xga.aperture_cntl == 1)) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/
svga->xga.on = 1;
return svga->xga.test;

File diff suppressed because it is too large Load Diff

View File

@@ -71,7 +71,7 @@ ifeq ($(DEV_BUILD), y)
OPEN_AT := y
endif
ifndef PAS16
PAS16 := n
PAS16 := y
endif
ifndef SIO_DETECT
SIO_DETECT := y

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Grafika:"
#define STR_VOODOO "Použít grafický akcelerátor Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Myš:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Videokarte:"
#define STR_VOODOO "Voodoo-Grafik"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Maus:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -269,6 +269,12 @@ BEGIN
CONTROL STR_IBM8514, IDC_CHECK_IBM8514,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
7, 46, 199, CFG_CHECKBOX_HEIGHT
CONTROL STR_XGA, IDC_CHECK_XGA,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
7, 65, 199, CFG_CHECKBOX_HEIGHT
PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_XGA,
CFG_COMBO_BTN_LEFT, 64, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
END
DLG_CFG_INPUT DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Video:"
#define STR_VOODOO "Voodoo Graphics"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Mouse:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Video:"
#define STR_VOODOO "Voodoo Graphics"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Mouse:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Vídeo:"
#define STR_VOODOO "Voodoo Graphics"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Ratón:"
#define STR_JOYSTICK "Mando:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Näytönohjain:"
#define STR_VOODOO "Voodoo-grafiikkasuoritin"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Hiiri:"
#define STR_JOYSTICK "Peliohjain:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Vidéo:"
#define STR_VOODOO "Graphique Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Souris:"
#define STR_JOYSTICK "Manette de commande:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Video:"
#define STR_VOODOO "Voodoo grafika"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Miš:"
#define STR_JOYSTICK "Palica za igru:"

View File

@@ -277,6 +277,7 @@ END
#define STR_VIDEO "Videokártya:"
#define STR_VOODOO "Voodoo-gyorsítókártya"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Egér:"
#define STR_JOYSTICK "Játékvezérlő:"

View File

@@ -273,6 +273,7 @@ END
#define STR_VIDEO "Video:"
#define STR_VOODOO "Grafica Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Mouse:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "ビデオカード:"
#define STR_VOODOO "Voodooグラフィック"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "マウス:"
#define STR_JOYSTICK "ジョイスティック:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "비디오 카드:"
#define STR_VOODOO "Voodoo 그래픽"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "마우스:"
#define STR_JOYSTICK "조이스틱:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Wideo:"
#define STR_VOODOO "Grafika Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Mysz:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -275,6 +275,7 @@ END
#define STR_VIDEO "Vídeo:"
#define STR_VOODOO "3DFX Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Mouse:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Vídeo:"
#define STR_VOODOO "Gráficos Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Rato:"
#define STR_JOYSTICK "Joystick:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Видеокарта:"
#define STR_VOODOO "Ускоритель Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Мышь:"
#define STR_JOYSTICK "Джойстик:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Video:"
#define STR_VOODOO "Voodoo grafika"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Miška:"
#define STR_JOYSTICK "Igralna palica:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Ekran kartı:"
#define STR_VOODOO "Voodoo Grafikleri"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Fare:"
#define STR_JOYSTICK "Oyun kolu:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "Відеокарта:"
#define STR_VOODOO "Прискорювач Voodoo"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "Миша:"
#define STR_JOYSTICK "Джойстик:"

View File

@@ -272,6 +272,7 @@ END
#define STR_VIDEO "显卡:"
#define STR_VOODOO "Voodoo Graphics"
#define STR_IBM8514 "IBM 8514/a Graphics"
#define STR_XGA "XGA Graphics"
#define STR_MOUSE "鼠标:"
#define STR_JOYSTICK "操纵杆:"

View File

@@ -16,6 +16,7 @@
* Copyright 2016-2019 Miran Grca.
* Copyright 2018,2019 David Hrdlička.
* Copyright 2021 Laci bá'
* Copyright 2021-2022 Jasmine Iwanek.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
@@ -63,6 +64,7 @@
#include <86box/midi.h>
#include <86box/snd_mpu401.h>
#include <86box/video.h>
#include <86box/vid_xga_device.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/win.h>
@@ -85,7 +87,7 @@ static int temp_dynarec;
#endif
/* Video category */
static int temp_gfxcard, temp_ibm8514, temp_voodoo;
static int temp_gfxcard, temp_ibm8514, temp_voodoo, temp_xga;
/* Input devices category */
static int temp_mouse, temp_joystick;
@@ -333,6 +335,7 @@ win_settings_init(void)
temp_gfxcard = gfxcard;
temp_voodoo = voodoo_enabled;
temp_ibm8514 = ibm8514_enabled;
temp_xga = xga_enabled;
/* Input devices category */
temp_mouse = mouse_type;
@@ -458,6 +461,7 @@ win_settings_changed(void)
i = i || (gfxcard != temp_gfxcard);
i = i || (voodoo_enabled != temp_voodoo);
i = i || (ibm8514_enabled != temp_ibm8514);
i = i || (xga_enabled != temp_xga);
/* Input devices category */
i = i || (mouse_type != temp_mouse);
@@ -549,6 +553,7 @@ win_settings_save(void)
gfxcard = temp_gfxcard;
voodoo_enabled = temp_voodoo;
ibm8514_enabled = temp_ibm8514;
xga_enabled = temp_xga;
/* Input devices category */
mouse_type = temp_mouse;
@@ -1116,6 +1121,11 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
settings_enable_window(hdlg, IDC_CHECK_IBM8514, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA));
settings_set_check(hdlg, IDC_CHECK_IBM8514, temp_ibm8514);
settings_enable_window(hdlg, IDC_CHECK_XGA, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA));
settings_set_check(hdlg, IDC_CHECK_XGA, temp_xga);
settings_enable_window(hdlg, IDC_BUTTON_XGA, (machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)) && temp_xga);
return TRUE;
case WM_COMMAND:
@@ -1134,10 +1144,23 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514);
break;
case IDC_CHECK_XGA:
temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA);
settings_enable_window(hdlg, IDC_BUTTON_XGA, temp_xga);
break;
case IDC_BUTTON_VOODOO:
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&voodoo_device);
break;
case IDC_BUTTON_XGA:
if (machine_has_bus(temp_machine, MACHINE_BUS_MCA) > 0) {
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&xga_device);
} else {
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&xga_isa_device);
}
break;
case IDC_CONFIGURE_VID:
temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)video_card_getdevice(temp_gfxcard));
@@ -1149,6 +1172,7 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO);
temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514);
temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA);
default:
return FALSE;

View File

@@ -1,6 +1,6 @@
{
"name": "86box",
"version-string": "3.5",
"version-string": "3.6",
"homepage": "https://86box.net/",
"documentation": "http://86box.readthedocs.io/",
"license": "GPL-2.0-or-later",