mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
4
.ci/Jenkinsfile
vendored
4
.ci/Jenkinsfile
vendored
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)"'/'
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
351
src/disk/hdd.c
351
src/disk/hdd.c
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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@
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
22
src/include/86box/vid_xga_device.h
Normal file
22
src/include/86box/vid_xga_device.h
Normal 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*/
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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ő:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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 "ジョイスティック:"
|
||||
|
||||
@@ -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 "조이스틱:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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 "Джойстик:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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:"
|
||||
|
||||
@@ -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 "Джойстик:"
|
||||
|
||||
@@ -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 "操纵杆:"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user