Merge branch 'master' into qt-scroll-states

This commit is contained in:
Cacodemon345
2025-05-06 12:23:23 +06:00
committed by GitHub
258 changed files with 20390 additions and 8738 deletions

2
.ci/Jenkinsfile vendored
View File

@@ -20,7 +20,7 @@ def repository = ['https://github.com/86Box/86Box.git', scm.userRemoteConfigs[0]
def commitBrowser = ['https://github.com/86Box/86Box/commit/%s', null]
def branch = ['master', scm.branches[0].name]
def buildType = ['beta', 'alpha']
def tarballFlags = ['', '-s']
def tarballFlags = ['', '-t']
def buildBranch = env.JOB_BASE_NAME.contains('-') ? 1 : 0
def osArchs = [

View File

@@ -56,22 +56,13 @@ jobs:
- name: SDL GUI
qt: off
static: on
src-packages: >-
libsndfile
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qt@5
src-packages: >-
libsndfile
steps:
- name: Install source dependencies
run: >-
brew reinstall -s
${{ matrix.ui.src-packages }}
- name: Install dependencies
run: >-
brew install
@@ -158,22 +149,13 @@ jobs:
- name: SDL GUI
qt: off
static: on
src-packages: >-
libsndfile
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qt@5
src-packages: >-
libsndfile
steps:
- name: Install source dependencies
run: >-
brew reinstall -s
${{ matrix.ui.src-packages }}
- name: Install dependencies
run: >-
brew install

View File

@@ -18,7 +18,6 @@ on:
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/cmake_windows_msys2.yml
- vcpkg.json
- "!**/Makefile*"
@@ -26,9 +25,9 @@ on:
jobs:
msys2:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
name: "${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
runs-on: windows-2022
runs-on: ${{ matrix.environment.runner }}
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
@@ -41,47 +40,38 @@ jobs:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
- name: Dev Debug
preset: dev_debug
slug: -Debug
slug: -Dev-Debug
- name: Dev
preset: development
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Qt GUI
qt: on
static: on
slug: -Qt
packages: >-
qt5-static:p
vulkan-headers:p
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake
# - msystem: UCRT64
# prefix: mingw-w64-ucrt-x86_64
# toolchain: ./cmake/flags-gcc-x86_64.cmake
slug: "-64"
runner: windows-2022
- msystem: CLANGARM64
toolchain: ./cmake/flags-gcc-aarch64.cmake
slug: -arm64
runner: windows-11-arm
exclude:
- dynarec:
new: off
environment:
msystem: CLANGARM64
steps:
- name: Prepare MSYS2 environment
uses: msys2/setup-msys2@v2
with:
release: false
release: true
update: true
msystem: ${{ matrix.environment.msystem }}
pacboy: >-
@@ -98,15 +88,17 @@ jobs:
libslirp:p
fluidsynth:p
libserialport:p
${{ matrix.ui.packages }}
qt5-static:p
vulkan-headers:p
openmp:p
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v3
# - name: Install sonar-scanner and build-wrapper
# uses: SonarSource/sonarcloud-github-c-cpp@v3
- name: Configure CMake
run: >-
@@ -114,20 +106,20 @@ jobs:
--toolchain ${{ matrix.environment.toolchain }}
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D STATIC_BUILD=${{ matrix.ui.static }}
# - name: Build
# run: |
# .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Build
run: |
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
run: cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
# - name: Run sonar-scanner
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# run: |
# .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: cmake --install build
@@ -135,5 +127,5 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows${{ matrix.environment.slug }}-gha${{ github.run_number }}'
path: build/artifacts/**

View File

@@ -36,7 +36,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
VERSION 4.3
VERSION 5.0
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)
@@ -180,7 +180,6 @@ cmake_dependent_option(GUSMAX "Gravis UltraSound MAX"
cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)

View File

@@ -30,9 +30,9 @@ Performance may vary depending on both host and guest configuration. Most emulat
It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines.
* [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux)
* [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only)
* [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia)
* [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux)
* [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python)
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested)
* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only)

View File

@@ -0,0 +1,20 @@
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box distribution.
#
# CMake toolchain file defining GCC compiler flags
# for 64-bit x86 targets.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
#
# Copyright 2021 David Hrdlička.
#
include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-x86_64.cmake)
set(CMAKE_C_COMPILER icx)
set(CMAKE_CXX_COMPILER icpx)

View File

@@ -0,0 +1,23 @@
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box distribution.
#
# CMake toolchain file defining Clang compiler flags
# for 64-bit x86 targets.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# dob205
#
# Copyright 2021 David Hrdlička.
# Copyright 2022 dob205.
#
include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-x86_64.cmake)
# Use the GCC-compatible Clang executables in order to use our flags
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)

4
debian/changelog vendored
View File

@@ -1,5 +1,5 @@
86box (4.3) UNRELEASED; urgency=medium
86box (5.0) UNRELEASED; urgency=medium
* Bump release.
-- Jasmine Iwanek <jriwanek@gmail.com> Wed, 13 Nov 2024 06:31:46 +0100
-- Jasmine Iwanek <jriwanek@gmail.com> Wed, 16 Apr 2025 22:08:04 +0200

View File

@@ -160,6 +160,7 @@ int window_remember;
int vid_resize; /* (C) allow resizing */
int invert_display = 0; /* (C) invert the display */
int suppress_overscan = 0; /* (C) suppress overscans */
int lang_id = 0; /* (C) language id */
int scale = 0; /* (C) screen scale factor */
int dpi_scale = 0; /* (C) DPI scaling of the emulated
screen */
@@ -173,7 +174,7 @@ int force_43 = 0; /* (C) video *
int video_filter_method = 1; /* (C) video */
int video_vsync = 0; /* (C) video */
int video_framerate = -1; /* (C) video */
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; /* (C) activation and kind of
bool serial_passthrough_enabled[SERIAL_MAX - 1] = { 0, 0, 0, 0, 0, 0, 0 }; /* (C) activation and kind of
pass-through for serial ports */
int bugger_enabled = 0; /* (C) enable ISAbugger */
int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */
@@ -221,6 +222,37 @@ int other_ide_present = 0; /* IDE control
int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are
present */
// Accelerator key array
struct accelKey acc_keys[NUM_ACCELS];
// Default accelerator key values
struct accelKey def_acc_keys[NUM_ACCELS] = {
{ .name="send_ctrl_alt_del", .desc="Send Control+Alt+Del",
.seq="Ctrl+F12" },
{ .name="send_ctrl_alt_esc", .desc="Send Control+Alt+Escape",
.seq="Ctrl+F10" },
{ .name="fullscreen", .desc="Toggle fullscreen",
.seq="Ctrl+Alt+PgUp" },
{ .name="screenshot", .desc="Screenshot",
.seq="Ctrl+F11" },
{ .name="release_mouse", .desc="Release mouse pointer",
.seq="Ctrl+End" },
{ .name="hard_reset", .desc="Hard reset",
.seq="Ctrl+Alt+F12" },
{ .name="pause", .desc="Toggle pause",
.seq="Ctrl+Alt+F1" },
{ .name="mute", .desc="Toggle mute",
.seq="Ctrl+Alt+M" }
};
/* Statistics. */
extern int mmuflush;
extern int readlnum;
@@ -554,6 +586,62 @@ delete_nvr_file(uint8_t flash)
extern void device_find_all_descs(void);
static void
pc_show_usage(char *s)
{
char p[4096] = { 0 };
sprintf(p,
"\n%sUsage: 86box [options] [cfg-file]\n\n"
"Valid options are:\n\n"
"-? or --help\t\t\t- show this information\n"
"-C or --config path\t\t- set 'path' to be config file\n"
#ifdef _WIN32
"-D or --debug\t\t\t- force debug output logging\n"
#endif
#if 0
"-E or --nographic\t\t- forces the old behavior\n"
#endif
"-F or --fullscreen\t\t- start in fullscreen mode\n"
"-G or --lang langid\t\t- start with specified language\n"
"\t\t\t\t (e.g. en-US, or system)\n"
#ifdef _WIN32
"-H or --hwnd id,hwnd\t\t- sends back the main dialog's hwnd\n"
#endif
"-I or --image d:path\t\t- load 'path' as floppy image on drive d\n"
#ifdef USE_INSTRUMENT
"-J or --instrument name\t- set 'name' to be the profiling instrument\n"
#endif
"-L or --logfile pat\t\t- set 'path' to be the logfile\n"
"-M or --missing\t\t- dump missing machines and video cards\n"
"-N or --noconfirm\t\t- do not ask for confirmation on quit\n"
"-P or --vmpath path\t\t- set 'path' to be root for vm\n"
"-R or --rompath path\t\t- set 'path' to be ROM path\n"
#ifndef USE_SDL_UI
"-S or --settings\t\t\t- show only the settings dialog\n"
#endif
"-T or --testmode\t\t- test mode: execute the test mode entry\n"
"\t\t\t\t point on init/hard reset\n"
"-V or --vmname name\t\t- overrides the name of the running VM\n"
"-W or --nohook\t\t- disables keyboard hook\n"
"\t\t\t\t (compatibility-only outside Windows)\n"
"-X or --clear what\t\t- clears the 'what' (cmos/flash/both)\n"
"-Y or --donothing\t\t- do not show any UI or run the emulation\n"
"-Z or --lastvmpath\t\t- the last parameter is VM path rather\n"
"\t\t\t\t than config\n"
"\nA config file can be specified. If none is, the default file will be used.\n",
(s == NULL) ? "" : s);
#ifdef _WIN32
ui_msgbox(MBX_ANSI | ((s == NULL) ? MBX_INFO : MBX_WARNING), p);
#else
if (s == NULL)
pclog(p);
else
ui_msgbox(MBX_ANSI | MBX_WARNING, p);
#endif
}
/*
* Perform initial startup of the PC.
*
@@ -577,6 +665,9 @@ pc_init(int argc, char *argv[])
time_t now;
int c;
int lvmp = 0;
#ifdef DEPRECATE_USAGE
int deprecated = 1;
#endif
#ifdef ENABLE_NG
int ng = 0;
#endif
@@ -584,7 +675,7 @@ pc_init(int argc, char *argv[])
uint32_t *uid;
uint32_t *shwnd;
#endif
uint32_t lang_init = 0;
int lang_init = 0;
/* Grab the executable's full path. */
plat_get_exe_name(exe_path, sizeof(exe_path) - 1);
@@ -634,41 +725,7 @@ usage:
}
}
printf("\nUsage: 86box [options] [cfg-file]\n\n");
printf("Valid options are:\n\n");
printf("-? or --help - show this information\n");
printf("-C or --config path - set 'path' to be config file\n");
#ifdef _WIN32
printf("-D or --debug - force debug output logging\n");
#endif
#if 0
printf("-E or --nographic - forces the old behavior\n");
#endif
printf("-F or --fullscreen - start in fullscreen mode\n");
printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n");
#ifdef _WIN32
printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n");
#endif
printf("-I or --image d:path - load 'path' as floppy image on drive d\n");
#ifdef USE_INSTRUMENT
printf("-J or --instrument name - set 'name' to be the profiling instrument\n");
#endif
printf("-K or --keycodes codes - set 'codes' to be the uncapture combination\n");
printf("-L or --logfile path - set 'path' to be the logfile\n");
printf("-M or --missing - dump missing machines and video cards\n");
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
printf("-P or --vmpath path - set 'path' to be root for vm\n");
printf("-R or --rompath path - set 'path' to be ROM path\n");
#ifndef USE_SDL_UI
printf("-S or --settings - show only the settings dialog\n");
#endif
printf("-T or --testmode - test mode: execute the test mode entry point on init/hard reset\n");
printf("-V or --vmname name - overrides the name of the running VM\n");
printf("-W or --nohook - disables keyboard hook (compatibility-only outside Windows)\n");
printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n");
printf("-Y or --donothing - do not show any UI or run the emulation\n");
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
printf("\nA config file can be specified. If none is, the default file will be used.\n");
pc_show_usage(NULL);
return 0;
} else if (!strcasecmp(argv[c], "--lastvmpath") || !strcasecmp(argv[c], "-Z")) {
lvmp = 1;
@@ -695,6 +752,9 @@ usage:
goto usage;
ppath = argv[++c];
#ifdef DEPRECATE_USAGE
deprecated = 0;
#endif
} else if (!strcasecmp(argv[c], "--rompath") || !strcasecmp(argv[c], "-R")) {
if ((c + 1) == argc)
goto usage;
@@ -706,6 +766,9 @@ usage:
goto usage;
cfg = argv[++c];
#ifdef DEPRECATE_USAGE
deprecated = 0;
#endif
} else if (!strcasecmp(argv[c], "--image") || !strcasecmp(argv[c], "-I")) {
if ((c + 1) == argc)
goto usage;
@@ -744,13 +807,6 @@ usage:
do_nothing = 1;
} else if (!strcasecmp(argv[c], "--nohook") || !strcasecmp(argv[c], "-W")) {
hook_enabled = 0;
} else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) {
if ((c + 1) == argc)
goto usage;
sscanf(argv[++c], "%03hX,%03hX,%03hX,%03hX,%03hX,%03hX",
&key_prefix_1_1, &key_prefix_1_2, &key_prefix_2_1, &key_prefix_2_2,
&key_uncapture_1, &key_uncapture_2);
} else if (!strcasecmp(argv[c], "--clearboth") || !strcasecmp(argv[c], "-X")) {
if ((c + 1) == argc)
goto usage;
@@ -811,11 +867,22 @@ usage:
ppath = argv[c++];
else
cfg = argv[c++];
#ifdef DEPRECATE_USAGE
deprecated = 0;
#endif
}
if (c != argc)
goto usage;
#ifdef DEPRECATE_USAGE
if (deprecated)
pc_show_usage("Running 86Box without a specified VM path and/or configuration\n"
"file has been deprected. Please specify one or use a manager\n"
"(Avalonia 86 is recommended).\n\n");
#endif
path_slash(usr_path);
path_slash(rom_path);
@@ -972,6 +1039,13 @@ usage:
zip_global_init();
mo_global_init();
/* Initialize the keyboard accelerator list with default values */
for (int x = 0; x < NUM_ACCELS; x++) {
strcpy(acc_keys[x].name, def_acc_keys[x].name);
strcpy(acc_keys[x].desc, def_acc_keys[x].desc);
strcpy(acc_keys[x].seq, def_acc_keys[x].seq);
}
/* Load the configuration file. */
config_load();
@@ -1624,6 +1698,8 @@ set_screen_size_monitor(int x, int y, int monitor_index)
{
int temp_overscan_x = monitors[monitor_index].mon_overscan_x;
int temp_overscan_y = monitors[monitor_index].mon_overscan_y;
int is_svga = (video_get_type_monitor(monitor_index) == VIDEO_FLAG_TYPE_SPECIAL) ||
(video_get_type_monitor(monitor_index) == VIDEO_FLAG_TYPE_8514);
double dx;
double dy;
double dtx;
@@ -1657,19 +1733,19 @@ set_screen_size_monitor(int x, int y, int monitor_index)
dty = (double) temp_overscan_y;
/* Account for possible overscan. */
if (video_get_type_monitor(monitor_index) != VIDEO_FLAG_TYPE_SPECIAL && (temp_overscan_y == 16)) {
if (!is_svga && (temp_overscan_y == 16)) {
/* CGA */
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
} else if (video_get_type_monitor(monitor_index) != VIDEO_FLAG_TYPE_SPECIAL && (temp_overscan_y < 16)) {
} else if (!is_svga && (temp_overscan_y < 16)) {
/* MDA/Hercules */
dy = (x / 4.0) * 3.0;
dy = (dx / 4.0) * 3.0;
} else {
if (enable_overscan) {
/* EGA/(S)VGA with overscan */
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
} else {
/* EGA/(S)VGA without overscan */
dy = (x / 4.0) * 3.0;
dy = (dx / 4.0) * 3.0;
}
}
monitors[monitor_index].mon_unscaled_size_y = (int) dy;
@@ -1786,3 +1862,16 @@ do_pause(int p)
}
atomic_store(&pause_ack, 0);
}
// Helper to find an accelerator key and return it's index in acc_keys
int FindAccelerator(const char *name) {
for(int x=0;x<NUM_ACCELS;x++)
{
if(strcmp(acc_keys[x].name, name) == 0)
{
return(x);
}
}
// No key was found
return -1;
}

View File

@@ -2387,6 +2387,14 @@ acpi_reset(void *priv)
dev->regs.gpi_val = 0xfff57fc1;
if (!strcmp(machine_get_internal_name(), "ficva503a") || !strcmp(machine_get_internal_name(), "6via90ap"))
dev->regs.gpi_val |= 0x00000004;
/*
TriGem Delhi-III second GPI word:
- Bit 7 = Save CMOS (must be set);
- Bit 6 = Password jumper (must be set);
- Bit 5 = Enable Setup (must be set).
*/
else if (!strcmp(machine_get_internal_name(), "delhi3"))
dev->regs.gpi_val |= 0x00008000;
}
if (acpi_power_on) {

View File

@@ -29,6 +29,9 @@
#include <86box/cdrom.h>
#include <86box/cdrom_image.h>
#include <86box/cdrom_interface.h>
#ifdef USE_CDROM_MITSUMI
#include <86box/cdrom_mitsumi.h>
#endif
#include <86box/log.h>
#include <86box/plat.h>
#include <86box/plat_cdrom_ioctl.h>
@@ -117,6 +120,9 @@ static const struct {
} controllers[] = {
// clang-format off
{ &cdrom_interface_none_device },
#ifdef USE_CDROM_MITSUMI
{ &mitsumi_cdrom_device },
#endif
{ NULL }
// clang-format on
};
@@ -2274,13 +2280,73 @@ cdrom_read_disc_info_toc(cdrom_t *dev, uint8_t *b,
return ret;
}
static uint32_t
cdrom_msf_to_lba(const int sector, const int ismsf,
int cdrom_sector_type, const uint8_t vendor_type)
{
int pos = sector;
uint32_t lba;
if ((cdrom_sector_type & 0x0f) >= 0x08) {
mult = cdrom_sector_type >> 4;
pos /= mult;
}
if (ismsf) {
const int m = (pos >> 16) & 0xff;
const int s = (pos >> 8) & 0xff;
const int f = pos & 0xff;
lba = MSFtoLBA(m, s, f) - 150;
} else {
switch (vendor_type) {
case 0x00:
lba = pos;
break;
case 0x40: {
const int m = bcd2bin((pos >> 24) & 0xff);
const int s = bcd2bin((pos >> 16) & 0xff);
const int f = bcd2bin((pos >> 8) & 0xff);
lba = MSFtoLBA(m, s, f) - 150;
break;
} case 0x80:
lba = bcd2bin((pos >> 24) & 0xff);
break;
/* Never used values but the compiler complains. */
default:
lba = 0;
}
}
return lba;
}
int
cdrom_is_track_audio(cdrom_t *dev, const int sector,
const int ismsf, int cdrom_sector_type,
const uint8_t vendor_type)
{
int audio = 0;
uint32_t lba = cdrom_msf_to_lba(sector, ismsf,
cdrom_sector_type, vendor_type);
if (dev->ops->get_track_type)
audio = dev->ops->get_track_type(dev->local, lba);
audio &= CD_TRACK_AUDIO;
return audio;
}
int
cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int ismsf,
int cdrom_sector_type, const int cdrom_sector_flags,
int *len, const uint8_t vendor_type)
{
int pos = sector;
int ret = 0;
int pos = sector;
int ret = 0;
const int old_type = cdrom_sector_type;
if ((cdrom_sector_type & 0x0f) >= 0x08) {
mult = cdrom_sector_type >> 4;
@@ -2298,38 +2364,12 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int
uint8_t *temp_b;
uint8_t *b = temp_b = buffer;
int audio = 0;
uint32_t lba;
uint32_t lba = cdrom_msf_to_lba(sector, ismsf,
old_type, vendor_type);
int mode2 = 0;
*len = 0;
if (ismsf) {
const int m = (pos >> 16) & 0xff;
const int s = (pos >> 8) & 0xff;
const int f = pos & 0xff;
lba = MSFtoLBA(m, s, f) - 150;
} else {
switch (vendor_type) {
case 0x00:
lba = pos;
break;
case 0x40: {
const int m = bcd2bin((pos >> 24) & 0xff);
const int s = bcd2bin((pos >> 16) & 0xff);
const int f = bcd2bin((pos >> 8) & 0xff);
lba = MSFtoLBA(m, s, f) - 150;
break;
} case 0x80:
lba = bcd2bin((pos >> 24) & 0xff);
break;
/* Never used values but the compiler complains. */
default:
lba = 0;
}
}
if (dev->ops->get_track_type)
audio = dev->ops->get_track_type(dev->local, lba);

View File

@@ -2016,6 +2016,10 @@ image_open(cdrom_t *dev, const char *path)
img->has_audio = 0;
else if (ret)
img->has_audio = 1;
else {
image_close(img);
img = NULL;
}
} else {
ret = image_load_iso(img, path);
@@ -2033,7 +2037,8 @@ image_open(cdrom_t *dev, const char *path)
img->log = log_open(n);
dev->ops = &image_ops;
}
} else
warning("Unable to load CD-ROM image: %s\n", path);
}
return img;

View File

@@ -782,9 +782,8 @@ viso_close(void *priv)
if (viso->entry_map)
free(viso->entry_map);
if (tf->log != NULL) {
}
if (tf->log != NULL)
log_close(tf->log);
free(viso);
}
@@ -1607,10 +1606,12 @@ end:
return &viso->tf;
} else {
image_viso_log(viso->tf.log, "Initialization failed\n");
if (data)
free(data);
viso_close(&viso->tf);
if (viso != NULL) {
image_viso_log(viso->tf.log, "Initialization failed\n");
if (data)
free(data);
viso_close(&viso->tf);
}
return NULL;
}
}

View File

@@ -59,7 +59,6 @@ typedef struct piix_io_trap_t {
} piix_io_trap_t;
typedef struct _piix_ {
uint8_t cur_readout_reg;
uint8_t rev;
uint8_t type;
uint8_t func_shift;
@@ -67,7 +66,6 @@ typedef struct _piix_ {
uint8_t pci_slot;
uint8_t no_mirq0;
uint8_t regs[4][256];
uint8_t readout_regs[256];
uint16_t func0_id;
uint16_t nvr_io_base;
uint16_t acpi_io_base;
@@ -1185,31 +1183,6 @@ piix_read(int func, int addr, void *priv)
return ret;
}
static void
board_write(uint16_t port, uint8_t val, void *priv)
{
piix_t *dev = (piix_t *) priv;
if (port == 0x00e0)
dev->cur_readout_reg = val;
else if (port == 0x00e1)
dev->readout_regs[dev->cur_readout_reg] = val;
}
static uint8_t
board_read(uint16_t port, void *priv)
{
const piix_t *dev = (piix_t *) priv;
uint8_t ret = 0x64;
if (port == 0x00e0)
ret = dev->cur_readout_reg;
else if (port == 0x00e1)
ret = dev->readout_regs[dev->cur_readout_reg];
return ret;
}
static void
piix_reset_hard(piix_t *dev)
{
@@ -1624,40 +1597,6 @@ piix_init(const device_t *info)
if (dev->type < 3)
pci_enable_mirq(1);
dev->readout_regs[0] = 0xff;
dev->readout_regs[1] = 0x40;
dev->readout_regs[2] = 0xff;
/* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined):
Bit 6: 1 = can boot, 0 = no;
Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, 10 = 3.0, 11 = 1.5);
Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, 10 = 60 MHz, 11 = ????):
Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, 0100 = 150 MHz, 0110 = ??? MHz;
0001 = 100 MHz, 0011 = 133 MHz, 0101 = 120 MHz, 0111 = ??? MHz;
1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz;
1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */
if (cpu_busspeed <= 40000000)
dev->readout_regs[1] |= 0x30;
else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000))
dev->readout_regs[1] |= 0x00;
else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000))
dev->readout_regs[1] |= 0x20;
else if (cpu_busspeed > 60000000)
dev->readout_regs[1] |= 0x10;
if (cpu_dmulti <= 1.5)
dev->readout_regs[1] |= 0x82;
else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0))
dev->readout_regs[1] |= 0x02;
else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5))
dev->readout_regs[1] |= 0x00;
else if (cpu_dmulti > 2.5)
dev->readout_regs[1] |= 0x80;
io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
#if 0
device_add(&i8254_sec_device);
#endif

View File

@@ -956,8 +956,9 @@ neat_write(uint16_t port, uint8_t val, void *priv)
dev->ems_size);
}
mem_a20_key = !(val & RB12_GA20);
mem_a20_alt = !(val & RB12_GA20);
mem_a20_recalc();
flushmmucache();
break;
default:
@@ -987,7 +988,7 @@ neat_read(uint16_t port, void *priv)
if ((dev->indx >= 0x60) && (dev->indx <= 0x6e))
ret = dev->regs[dev->indx];
else if (dev->indx == 0x6f)
ret = (dev->regs[dev->indx] & 0xfd) | (mem_a20_key & 2);
ret = (dev->regs[dev->indx] & 0xfd) | ~(mem_a20_alt & 0x02);
break;
default:

View File

@@ -259,7 +259,7 @@ sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv)
case 0x7a: /* DRAM Bank Register 2-1 */
case 0x7c: /* DRAM Bank Register 3-0 */
case 0x7e: /* DRAM Bank Register 3-1 */
spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82);
spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x02);
break;
case 0x71: /* DRAM Bank Register 0-0 */

View File

@@ -33,27 +33,384 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pic.h>
#include <86box/plat_fallthrough.h>
#include <86box/keyboard.h>
#include <86box/machine.h>
#include <86box/chipset.h>
typedef struct ram_bank_t {
uint32_t virt_base;
uint32_t virt_size;
uint32_t phys_base;
uint32_t phys_size;
mem_mapping_t mapping;
} ram_bank_t;
typedef struct sis_85c4xx_t {
uint8_t cur_reg;
uint8_t tries;
uint8_t reg_base;
uint8_t reg_last;
uint8_t reg_00;
uint8_t is_471;
uint8_t force_flush;
uint8_t shadowed;
uint8_t smram_enabled;
uint8_t pad;
uint8_t regs[39];
uint8_t scratch[2];
uint32_t mem_state[8];
smram_t *smram;
port_92_t *port_92;
uint8_t cur_reg;
uint8_t tries;
uint8_t reg_base;
uint8_t reg_last;
uint8_t reg_00;
uint8_t is_471;
uint8_t ram_banks_val;
uint8_t force_flush;
uint8_t shadowed;
uint8_t smram_enabled;
uint8_t pad;
uint8_t regs[39];
uint8_t scratch[2];
uint32_t mem_state[8];
ram_bank_t ram_banks[8];
smram_t * smram;
port_92_t * port_92;
} sis_85c4xx_t;
static uint8_t ram_4xx[64] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00,
0x04, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09,
0x04, 0x04, 0x05, 0x05, 0x0b, 0x0b, 0x0b, 0x0b,
0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d,
0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f,
0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d };
static uint8_t ram_asus[64] = { 0x00, 0x00, 0x01, 0x10, 0x10, 0x20, 0x03, 0x11,
0x11, 0x05, 0x05, 0x12, 0x12, 0x13, 0x13, 0x13,
0x13, 0x21, 0x06, 0x14, 0x14, 0x15, 0x15, 0x15,
0x15, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
0x1d, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17,
0x17, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f };
static uint8_t ram_tg486g[64] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11,
0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13,
0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15,
0x15, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
0x1d, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17,
0x17, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f };
static uint32_t banks_471[64][4] = { { 0x00100000, 0x00000000, 0x00000000, 0x00000000 }, /* 0x00 */
{ 0x00100000, 0x00100000, 0x00000000, 0x00000000 },
{ 0x00100000, 0x00100000, 0x00200000, 0x00000000 },
{ 0x00100000, 0x00100000, 0x00400000, 0x00000000 },
{ 0x00100000, 0x00100000, 0x00200000, 0x00400000 },
{ 0x00100000, 0x00100000, 0x00400000, 0x00400000 },
{ 0x00100000, 0x00100000, 0x01000000, 0x00000000 },
{ 0x00200000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00200000, 0x00200000, 0x00000000, 0x00000000 }, /* 0x08 */
{ 0x00200000, 0x00400000, 0x00000000, 0x00000000 },
{ 0x00200000, 0x00200000, 0x00400000, 0x00000000 },
{ 0x00200000, 0x00200000, 0x00400000, 0x00400000 },
{ 0x00200000, 0x01000000, 0x00000000, 0x00000000 },
{ 0x00200000, 0x00200000, 0x01000000, 0x00000000 },
{ 0x00200000, 0x00200000, 0x00400000, 0x01000000 },
{ 0x00200000, 0x00200000, 0x01000000, 0x01000000 },
{ 0x00400000, 0x00000000, 0x00000000, 0x00000000 }, /* 0x10 */
{ 0x00400000, 0x00400000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x00400000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x00400000, 0x00400000 },
{ 0x00400000, 0x01000000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x01000000, 0x00000000 },
{ 0x00400000, 0x01000000, 0x01000000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x01000000, 0x01000000 },
{ 0x00800000, 0x00000000, 0x00000000, 0x00000000 }, /* 0x18 */
{ 0x00800000, 0x00800000, 0x00000000, 0x00000000 },
{ 0x00800000, 0x00800000, 0x00800000, 0x00000000 },
{ 0x00800000, 0x00800000, 0x00800000, 0x00800000 },
{ 0x01000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x01000000, 0x01000000, 0x00000000, 0x00000000 },
{ 0x01000000, 0x01000000, 0x01000000, 0x00000000 },
{ 0x01000000, 0x01000000, 0x01000000, 0x01000000 },
{ 0x00100000, 0x00400000, 0x00000000, 0x00000000 }, /* 0x20 */
{ 0x00100000, 0x01000000, 0x00000000, 0x00000000 },
{ 0x00100000, 0x04000000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x00800000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x04000000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x04000000, 0x00000000 },
{ 0x01000000, 0x04000000, 0x00000000, 0x00000000 },
{ 0x01000000, 0x01000000, 0x04000000, 0x00000000 },
{ 0x04000000, 0x00000000, 0x00000000, 0x00000000 }, /* 0x28 */
{ 0x04000000, 0x04000000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x02000000, 0x00000000, 0x00000000 },
{ 0x00400000, 0x02000000, 0x02000000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x02000000, 0x00000000 },
{ 0x00400000, 0x00400000, 0x02000000, 0x02000000 },
{ 0x01000000, 0x02000000, 0x00000000, 0x00000000 },
{ 0x01000000, 0x02000000, 0x02000000, 0x00000000 },
{ 0x01000000, 0x01000000, 0x02000000, 0x00000000 }, /* 0x30 */
{ 0x01000000, 0x01000000, 0x02000000, 0x02000000 },
{ 0x02000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x02000000, 0x02000000, 0x00000000, 0x00000000 },
{ 0x02000000, 0x02000000, 0x02000000, 0x00000000 },
{ 0x02000000, 0x02000000, 0x02000000, 0x02000000 },
{ 0x00400000, 0x00800000, 0x00800000, 0x00000000 },
{ 0x00400000, 0x00800000, 0x00800000, 0x00800000 },
{ 0x00400000, 0x00400000, 0x00800000, 0x00000000 }, /* 0x38 */
{ 0x00400000, 0x00400000, 0x00800000, 0x00800000 },
{ 0x00800000, 0x01000000, 0x00000000, 0x00000000 },
{ 0x00800000, 0x00800000, 0x00800000, 0x01000000 },
{ 0x00800000, 0x00800000, 0x01000000, 0x00000000 },
{ 0x00800000, 0x00800000, 0x01000000, 0x01000000 },
{ 0x00800000, 0x00800000, 0x02000000, 0x00000000 },
{ 0x00800000, 0x00800000, 0x02000000, 0x02000000 } };
static uint32_t
sis_85c471_get_row(ram_bank_t *dev, uint32_t addr)
{
uint32_t ret = 0x00000000;
switch (dev->virt_size) {
case 0x00100000:
case 0x00200000:
ret |= (addr >> 13) & 0x00000001;
ret |= ((addr >> 12) & 0x00000001) << 1;
ret |= ((addr >> 14) & 0x0000003f) << 2;
ret |= ((addr >> 11) & 0x00000001) << 8;
ret |= ((addr >> 20) & 0x00000001) << 9;
ret |= ((addr >> 22) & 0x00000001) << 10;
ret |= ((addr >> 24) & 0x00000001) << 11;
break;
case 0x00400000:
case 0x00800000:
ret |= (addr >> 13) & 0x00000001;
ret |= ((addr >> 12) & 0x00000001) << 1;
ret |= ((addr >> 14) & 0x000000ff) << 2;
ret |= ((addr >> 22) & 0x00000001) << 10;
ret |= ((addr >> 24) & 0x00000001) << 11;
break;
case 0x01000000:
case 0x02000000:
case 0x04000000:
ret |= (addr >> 13) & 0x00000001;
ret |= ((addr >> 22) & 0x00000001) << 1;
ret |= ((addr >> 14) & 0x000000ff) << 2;
ret |= ((addr >> 23) & 0x00000001) << 10;
ret |= ((addr >> 24) & 0x00000001) << 11;
break;
}
return ret;
}
static uint32_t
sis_85c471_get_col(ram_bank_t *dev, uint32_t addr)
{
uint32_t ret = 0x00000000;
switch (dev->virt_size) {
case 0x00100000:
case 0x00200000:
ret |= (addr >> 3) & 0x00000001;
ret |= ((addr >> 2) & 0x00000001) << 1;
ret |= ((addr >> 4) & 0x0000003f) << 2;
ret |= ((addr >> 10) & 0x00000001) << 8;
ret |= ((addr >> 21) & 0x00000001) << 9;
ret |= ((addr >> 23) & 0x00000001) << 10;
ret |= ((addr >> 25) & 0x00000001) << 11;
break;
case 0x00400000:
case 0x00800000:
ret |= (addr >> 3) & 0x00000001;
ret |= ((addr >> 2) & 0x00000001) << 1;
ret |= ((addr >> 4) & 0x000000ff) << 2;
ret |= ((addr >> 23) & 0x00000001) << 10;
ret |= ((addr >> 25) & 0x00000001) << 11;
break;
case 0x01000000:
case 0x02000000:
case 0x04000000:
ret |= (addr >> 3) & 0x00000001;
ret |= ((addr >> 2) & 0x00000001) << 1;
ret |= ((addr >> 4) & 0x000001ff) << 2;
ret |= ((addr >> 25) & 0x00000001) << 11;
break;
}
return ret;
}
static uint32_t
sis_85c471_set_row(ram_bank_t *dev, uint32_t addr)
{
uint32_t ret = 0x00000000;
switch (dev->phys_size) {
case 0x00100000:
ret = (addr & 0x1ff) << 11;
break;
case 0x00200000:
ret = (addr & 0x3ff) << 11;
break;
case 0x00400000:
ret = (addr & 0x3ff) << 12;
break;
case 0x00800000:
ret = (addr & 0x7ff) << 12;
break;
case 0x01000000:
ret = (addr & 0x7ff) << 13;
break;
case 0x02000000:
ret = (addr & 0xfff) << 13;
break;
case 0x04000000:
ret = (addr & 0xfff) << 14;
break;
}
return ret;
}
static uint32_t
sis_85c471_set_col(ram_bank_t *dev, uint32_t addr)
{
uint32_t ret = 0x00000000;
switch (dev->phys_size) {
case 0x00100000:
case 0x00200000:
ret = (addr & 0x1ff) << 2;
break;
case 0x00400000:
case 0x00800000:
ret = (addr & 0x3ff) << 2;
break;
case 0x01000000:
case 0x02000000:
ret = (addr & 0x7ff) << 2;
break;
case 0x04000000:
ret = (addr & 0xfff) << 2;
break;
}
return ret;
}
uint8_t reg09 = 0x00;
static uint8_t
sis_85c471_read_ram(uint32_t addr, void *priv)
{
ram_bank_t *dev = (ram_bank_t *) priv;
uint32_t rel = addr - dev->virt_base;
uint8_t ret = 0xff;
uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel));
uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel));
uint32_t dw = rel & 0x00000003;
rel = row | col | dw;
addr = (rel + dev->phys_base);
if ((addr < (mem_size << 10)) && (rel < dev->phys_size))
ret = ram[addr];
return ret;
}
static uint16_t
sis_85c471_read_ramw(uint32_t addr, void *priv)
{
ram_bank_t *dev = (ram_bank_t *) priv;
uint32_t rel = addr - dev->virt_base;
uint16_t ret = 0xffff;
uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel));
uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel));
uint32_t dw = rel & 0x00000003;
rel = row | col | dw;
addr = (rel + dev->phys_base);
if ((addr < (mem_size << 10)) && (rel < dev->phys_size))
ret = *(uint16_t *) &(ram[addr]);
return ret;
}
static uint32_t
sis_85c471_read_raml(uint32_t addr, void *priv)
{
ram_bank_t *dev = (ram_bank_t *) priv;
uint32_t rel = addr - dev->virt_base;
uint32_t ret = 0xffffffff;
uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel));
uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel));
uint32_t dw = rel & 0x00000003;
rel = row | col | dw;
addr = (rel + dev->phys_base);
if ((addr < (mem_size << 10)) && (rel < dev->phys_size))
ret = *(uint32_t *) &(ram[addr]);
return ret;
}
static void
sis_85c471_write_ram(uint32_t addr, uint8_t val, void *priv)
{
ram_bank_t *dev = (ram_bank_t *) priv;
uint32_t rel = addr - dev->virt_base;
uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel));
uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel));
uint32_t dw = rel & 0x00000003;
rel = row | col | dw;
addr = (rel + dev->phys_base);
if ((addr < (mem_size << 10)) && (rel < dev->phys_size))
ram[addr] = val;
}
static void
sis_85c471_write_ramw(uint32_t addr, uint16_t val, void *priv)
{
ram_bank_t *dev = (ram_bank_t *) priv;
uint32_t rel = addr - dev->virt_base;
uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel));
uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel));
uint32_t dw = rel & 0x00000003;
rel = row | col | dw;
addr = (rel + dev->phys_base);
if ((addr < (mem_size << 10)) && (rel < dev->phys_size))
*(uint16_t *) &(ram[addr]) = val;
}
static void
sis_85c471_write_raml(uint32_t addr, uint32_t val, void *priv)
{
ram_bank_t *dev = (ram_bank_t *) priv;
uint32_t rel = addr - dev->virt_base;
uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel));
uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel));
uint32_t dw = rel & 0x00000003;
rel = row | col | dw;
addr = (rel + dev->phys_base);
if ((addr < (mem_size << 10)) && (rel < dev->phys_size))
*(uint32_t *) &(ram[addr]) = val;
}
static void
sis_85c4xx_recalcremap(sis_85c4xx_t *dev)
{
@@ -158,6 +515,62 @@ sis_85c4xx_sw_smi_handler(sis_85c4xx_t *dev)
NULL, NULL, NULL, sis_85c4xx_sw_smi_out, NULL, NULL, dev);
}
static void
sis_85c471_banks_split(uint32_t *b_ex, uint32_t *banks)
{
for (uint8_t i = 0; i < 4; i++) {
if ((banks[i] == 0x00200000) || (banks[i] == 0x00800000) ||
(banks[i] == 0x02000000))
b_ex[i << 1] = b_ex[(i << 1) + 1] = banks[i] >> 1;
else {
b_ex[i << 1] = banks[i];
b_ex[(i << 1) + 1] = 0x00000000;
}
}
}
static void
sis_85c471_banks_recalc(sis_85c4xx_t *dev)
{
reg09 = dev->regs[0x09];
for (uint8_t i = 0; i < 8; i++)
mem_mapping_disable(&dev->ram_banks[i].mapping);
mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_high_mapping);
mem_set_mem_state_both(1 << 20, 127 << 20, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
if ((dev->regs[0x09] & 0x3f) == dev->ram_banks_val) {
if (mem_size > 1024) {
mem_mapping_enable(&ram_low_mapping);
mem_mapping_enable(&ram_high_mapping);
mem_set_mem_state_both(1 << 20, (mem_size << 10) - (1 << 20),
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
} else {
uint8_t banks_val = dev->regs[0x09] & 0x3f;
uint32_t *banks = banks_471[banks_val];
uint32_t b_ex[8] = { 0x00000000 };
uint32_t size = 0x00000000;
sis_85c471_banks_split(b_ex, banks);
for (uint8_t i = 0; i < 8; i++) if (b_ex[i] != 0x00000000) {
dev->ram_banks[i].virt_base = size;
dev->ram_banks[i].virt_size = b_ex[i];
mem_mapping_set_addr(&dev->ram_banks[i].mapping, size, b_ex[i]);
size += b_ex[i];
}
mem_set_mem_state_both(1 << 20, 127 << 20, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
}
flushmmucache_nopc();
}
static void
sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
{
@@ -174,12 +587,23 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
case 0x23:
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) {
valxor = val ^ dev->regs[rel_reg];
if (rel_reg == 0x00)
if (!dev->is_471 && (rel_reg == 0x00))
dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0);
else
dev->regs[rel_reg] = val;
switch (rel_reg) {
case 0x00:
if (val & 0x01) {
kbc_at_set_fast_reset(0);
cpu_cpurst_on_sr = 1;
} else {
kbc_at_set_fast_reset(1);
cpu_cpurst_on_sr = 0;
}
break;
case 0x01:
cpu_cache_ext_enabled = ((val & 0x84) == 0x84);
cpu_update_waitstates();
@@ -190,6 +614,13 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
case 0x08:
if (valxor)
sis_85c4xx_recalcmapping(dev);
if (rel_reg == 0x08)
flushmmucache();
break;
case 0x09:
if (dev->is_471)
sis_85c471_banks_recalc(dev);
break;
case 0x0b:
@@ -297,14 +728,6 @@ sis_85c4xx_reset(void *priv)
{
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
int mem_size_mb = mem_size >> 10;
static uint8_t ram_4xx[64] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x04, 0x04, 0x05, 0x05, 0x0b, 0x0b, 0x0b, 0x0b,
0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e };
memset(dev->regs, 0x00, sizeof(dev->regs));
@@ -313,13 +736,44 @@ sis_85c4xx_reset(void *priv)
if (dev->is_471) {
dev->regs[0x09] = 0x40;
if (mem_size_mb >= 64) {
if ((mem_size_mb >= 65) && (mem_size_mb < 68))
dev->regs[0x09] |= 0x22;
if (!strcmp(machine_get_internal_name(), "vli486sv2g")) {
if (mem_size_mb == 64)
dev->regs[0x09] |= 0x1f;
else
dev->regs[0x09] |= 0x24;
} else
dev->regs[0x09] |= ram_asus[mem_size_mb];
} else if (mem_size_mb >= 64) {
if ((mem_size_mb >= 64) && (mem_size_mb < 68))
dev->regs[0x09] |= 0x33;
else if ((mem_size_mb >= 68) && (mem_size_mb < 72))
dev->regs[0x09] |= 0x2b;
else if ((mem_size_mb >= 72) && (mem_size_mb < 80))
dev->regs[0x09] |= 0x2d;
else if ((mem_size_mb >= 80) && (mem_size_mb < 96))
dev->regs[0x09] |= 0x2f;
else if ((mem_size_mb >= 96) && (mem_size_mb < 128))
dev->regs[0x09] |= 0x34;
else
dev->regs[0x09] |= 0x35;
} else if (!strcmp(machine_get_internal_name(), "tg486g"))
dev->regs[0x09] |= ram_tg486g[mem_size_mb];
else
dev->regs[0x09] |= ram_471[mem_size_mb];
dev->ram_banks_val = dev->regs[0x09] & 0x3f;
dev->regs[0x09] = 0x00;
uint32_t *banks = banks_471[dev->ram_banks_val];
uint32_t b_ex[8] = { 0x00000000 };
uint32_t size = 0x00000000;
sis_85c471_banks_split(b_ex, banks);
for (uint8_t i = 0; i < 8; i++) {
dev->ram_banks[i].phys_base = size;
dev->ram_banks[i].phys_size = b_ex[i];
size += b_ex[i];
}
dev->regs[0x11] = 0x09;
dev->regs[0x12] = 0xff;
@@ -332,6 +786,11 @@ sis_85c4xx_reset(void *priv)
port_92_remove(dev->port_92);
soft_reset_mask = 0;
sis_85c471_banks_recalc(dev);
kbc_at_set_fast_reset(1);
cpu_cpurst_on_sr = 0;
} else {
/* Bits 6 and 7 must be clear on the SiS 40x. */
if (dev->reg_base == 0x60)
@@ -375,11 +834,19 @@ sis_85c4xx_init(const device_t *info)
dev->reg_base = info->local & 0xff;
if (dev->is_471) {
dev->reg_last = dev->reg_base + 0x76;
dev->reg_last = 0x76;
dev->smram = smram_add();
dev->port_92 = device_add(&port_92_device);
for (uint8_t i = 0; i < 8; i++) {
mem_mapping_add(&dev->ram_banks[i].mapping, 0x00000000, 0x00000000,
sis_85c471_read_ram, sis_85c471_read_ramw, sis_85c471_read_raml,
sis_85c471_write_ram, sis_85c471_write_ramw, sis_85c471_write_raml,
NULL, MEM_MAPPING_INTERNAL, &(dev->ram_banks[i]));
mem_mapping_disable(&dev->ram_banks[i].mapping);
}
} else
dev->reg_last = dev->reg_base + 0x11;

View File

@@ -493,14 +493,28 @@ pipc_reset_hard(void *priv)
}
dev->ac97_regs[i][0x1c] = 0x01;
if (i == 0) {
dev->ac97_regs[i][0x34] = 0xc0;
dev->ac97_regs[i][0xc0] = 0x01;
dev->ac97_regs[i][0xc1] = 0x00;
dev->ac97_regs[i][0xc2] = 0x03;
dev->ac97_regs[i][0xc3] = 0x00;
dev->ac97_regs[i][0xc4] = 0x00;
dev->ac97_regs[i][0xc5] = 0x00;
dev->ac97_regs[i][0xc6] = 0x00;
dev->ac97_regs[i][0xc7] = 0x00;
}
dev->ac97_regs[i][0x3d] = 0x03;
if (i == 0)
if (i == 0) {
dev->ac97_regs[i][0x40] = 0x01;
dev->ac97_regs[i][0x43] = 0x1c;
dev->ac97_regs[i][0x48] = 0x01;
dev->ac97_regs[i][0x4b] = 0x02;
dev->ac97_regs[i][0x43] = 0x1c;
dev->ac97_regs[i][0x48] = 0x01;
dev->ac97_regs[i][0x4b] = 0x00;
}
pipc_sgd_handlers(dev, i);
pipc_codec_handlers(dev, i);
@@ -742,10 +756,12 @@ pipc_codec_handlers(pipc_t *dev, uint8_t modem)
if (!dev->ac97)
return;
uint32_t base = (dev->ac97_regs[modem][0x1d] << 8);
if (modem)
ac97_via_remap_modem_codec(dev->ac97, dev->ac97_regs[1][0x1d] << 8, dev->ac97_regs[1][0x04] & PCI_COMMAND_IO);
ac97_via_remap_modem_codec(dev->ac97, base, dev->ac97_regs[1][0x04] & PCI_COMMAND_IO);
else
ac97_via_remap_audio_codec(dev->ac97, dev->ac97_regs[0][0x1d] << 8, dev->ac97_regs[0][0x04] & PCI_COMMAND_IO);
ac97_via_remap_audio_codec(dev->ac97, base, dev->ac97_regs[0][0x04] & PCI_COMMAND_IO);
}
static uint8_t
@@ -1204,7 +1220,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x77:
if ((dev->local >= VIA_PIPC_686A) && (val & 0x10))
pclog("PIPC: Warning: Internal I/O APIC enabled.\n");
warning("PIPC: Warning: Internal I/O APIC enabled.\n");
nvr_via_wp_set(!!(val & 0x04), 0x32, dev->nvr);
nvr_via_wp_set(!!(val & 0x02), 0x0d, dev->nvr);
break;
@@ -1488,36 +1504,39 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
break;
}
} else if (func <= pm_func + 2) { /* AC97 / MC97 */
/* Read-only addresses. */
if ((addr < 0x4) || ((addr >= 0x6) && (addr < 0x9)) || ((addr >= 0xc) && (addr < 0x11)) || (addr == 0x16) || (addr == 0x17) || (addr == 0x1a) || (addr == 0x1b) || ((addr >= 0x1e) && (addr < 0x2c)) || ((addr >= 0x30) && (addr < 0x34)) || ((addr >= 0x35) && (addr < 0x3c)) || ((addr >= 0x3d) && (addr < 0x41)) || ((addr >= 0x45) && (addr < 0x4a)) || (addr >= 0x4c))
return;
/* Small shortcut. */
func = func - pm_func - 1;
/* Check disable bits and specific read-only addresses for both controllers. */
if ((func == 0) && (((addr >= 0x09) && (addr < 0xc)) || (addr == 0x44) || (dev->pci_isa_regs[0x85] & 0x04)))
/* Check disable bits. */
if ((func == 0) && (dev->pci_isa_regs[0x85] & 0x04))
return;
if ((func == 1) && ((addr == 0x14) || (addr == 0x15) || (addr == 0x18) || (addr == 0x19) || (addr == 0x42) || (addr == 0x43) || (addr == 0x48) || (addr == 0x4a) || (addr == 0x4b) || (dev->pci_isa_regs[0x85] & 0x08)))
if ((func == 1) && (dev->pci_isa_regs[0x85] & 0x08))
return;
switch (addr) {
case 0x04:
dev->ac97_regs[func][addr] = val;
dev->ac97_regs[func][addr] = val & 0x01;
pipc_sgd_handlers(dev, func);
if (func == 0) {
pipc_fmnmi_handlers(dev, func);
pipc_sb_handlers(dev, func);
}
pipc_codec_handlers(dev, func);
pipc_fmnmi_handlers(dev, func);
break;
case 0x09:
case 0x0a:
case 0x0b:
if (dev->ac97_regs[func][0x44] & 0x20)
/* Not writable on audio, only on modem. */
if ((func == 1) && (dev->ac97_regs[func][0x44] & 0x20))
dev->ac97_regs[func][addr] = val;
break;
case 0x10:
/*
The lowest 10 bytes are always 0x01, indicating
a 256-byte I/O space.
*/
case 0x11:
dev->ac97_regs[func][addr] = val;
pipc_sgd_handlers(dev, func);
@@ -1525,21 +1544,26 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x14:
case 0x15:
if (addr == 0x14)
val = (val & 0xfc) | 1;
dev->ac97_regs[func][addr] = val;
pipc_fmnmi_handlers(dev, func);
/* Not present on modem. */
if (func == 0) {
if (addr == 0x14)
val = (val & 0xfc) | 1;
dev->ac97_regs[func][addr] = val;
pipc_fmnmi_handlers(dev, func);
}
break;
case 0x18:
case 0x19:
if (addr == 0x18)
val = (val & 0xfc) | 1;
dev->ac97_regs[func][addr] = val;
pipc_sb_handlers(dev, func);
/* Not present on modem. */
if (func == 0) {
if (addr == 0x18)
val = (val & 0xfc) | 1;
dev->ac97_regs[func][addr] = val;
pipc_sb_handlers(dev, func);
}
break;
case 0x1c:
case 0x1d:
dev->ac97_regs[func][addr] = val;
pipc_codec_handlers(dev, func);
@@ -1549,39 +1573,84 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x2d:
case 0x2e:
case 0x2f:
if ((func == 0) && (dev->ac97_regs[func][0x42] & 0x20))
if (((func == 0) && (dev->ac97_regs[func][0x42] & 0x20)) ||
((func == 1) && (dev->ac97_regs[func][0x44] & 0x10)))
dev->ac97_regs[func][addr] = val;
break;
case 0x3c:
dev->ac97_regs[func][addr] = val & 0x0f;
break;
case 0x41:
dev->ac97_regs[func][addr] = val;
ac97_via_write_control(dev->ac97, func, val);
break;
case 0x42:
case 0x4a:
case 0x4b:
dev->ac97_regs[0][addr] = dev->ac97_regs[1][addr] = val;
gameport_remap(dev->gameport, (dev->ac97_regs[0][0x42] & 0x08) ? ((dev->ac97_regs[0][0x4b] << 8) | (dev->ac97_regs[0][0x4a] & 0xf8)) : 0);
if (addr == 0x42)
pipc_sb_handlers(dev, func);
case 0x4a ... 0x4b:
if (func == 0) {
dev->ac97_regs[func][addr] = val;
gameport_remap(dev->gameport, (dev->ac97_regs[func][0x42] & 0x08) ?
((dev->ac97_regs[func][0x4b] << 8) |
(dev->ac97_regs[func][0x4a] & 0xf8)) : 0);
if (addr == 0x42)
pipc_sb_handlers(dev, func);
}
break;
case 0x43:
dev->ac97_regs[0][addr] = dev->ac97_regs[1][addr] = val;
if (func == 0)
dev->ac97_regs[func][addr] = val;
break;
case 0x44:
dev->ac97_regs[0][addr] = dev->ac97_regs[1][addr] = val & 0xf0;
if (func == 1)
dev->ac97_regs[func][addr] = val & 0xf0;
break;
case 0x45:
case 0x48:
dev->ac97_regs[0][addr] = dev->ac97_regs[1][addr] = val & 0x0f;
if (func == 0)
dev->ac97_regs[func][addr] = val & 0x0f;
break;
case 0x80:
case 0x81:
case 0x82:
dev->ac97_regs[func][addr] = val;
break;
case 0x83:
dev->ac97_regs[func][addr] = ((dev->ac97_regs[func][addr] & 0x01) |
(val & 0xc0)) & ~(val & 0x0a);
break;
case 0x88:
case 0x89:
dev->ac97_regs[func][addr] = val;
break;
case 0x8a:
case 0x8b:
dev->ac97_regs[func][addr] &= ~val;
break;
case 0x8e:
case 0x8f:
dev->ac97_regs[func][addr] = val;
break;
case 0xc4:
if (func == 0)
dev->ac97_regs[func][addr] = (dev->ac97_regs[func][addr] & 0x0c) |
(val & 0x03);
break;
case 0xc5:
if (func == 0)
dev->ac97_regs[func][addr] = (dev->ac97_regs[func][addr] & 0x60) |
(val & 0x9f);
break;
default:
dev->ac97_regs[func][addr] = val;
break;
}
}

View File

@@ -65,9 +65,10 @@ wd76c10_log(const char *fmt, ...)
#endif
typedef struct {
uint32_t enable;
uint32_t phys_on, enable;
uint32_t virt_addr, phys_addr;
uint32_t virt_size, phys_size;
uint32_t adj_virt_addr, adj_virt_size;
} ram_bank_t;
typedef struct {
@@ -103,6 +104,7 @@ typedef struct
int locked;
uint32_t mem_top, hmwp_base;
uint32_t fast;
ram_bank_t ram_banks[5];
@@ -121,6 +123,40 @@ static uint32_t bank_sizes[4] = { 0x00020000, /* 64 Kbit X 16 = 1024 Kbit
0x00200000, /* 1 Mbit X 16 = 16 Mbit = 2 MB, 10x10 */
0x00800000 }; /* 4 Mbit X 16 = 64 Mbit = 8 MB, 11x11 */
static uint32_t
wd76c10_calc_phys(uint32_t row, uint32_t col, uint32_t size, uint32_t a0)
{
uint32_t ret = WD76C10_ADDR_INVALID;
switch (size) {
default:
ret = WD76C10_ADDR_INVALID;
break;
case 0x00020000:
row = (row & 0x0000ff) << 9;
col = (col & 0x0000ff) << 1;
ret = row | col | a0;
break;
case 0x00080000:
row = (row & 0x0001ff) << 10;
col = (col & 0x0001ff) << 1;
ret = row | col | a0;
break;
case 0x00200000:
row = (row & 0x0003ff) << 11;
col = (col & 0x0003ff) << 1;
ret = row | col | a0;
break;
case 0x00800000:
row = (row & 0x0007ff) << 12;
col = (col & 0x0007ff) << 1;
ret = row | col | a0;
break;
}
return ret;
}
static uint32_t
wd76c10_calc_addr(wd76c10_t *dev, uint32_t addr)
{
@@ -159,20 +195,303 @@ wd76c10_calc_addr(wd76c10_t *dev, uint32_t addr)
ret = WD76C10_ADDR_INVALID;
/* Then, handle the physical memory banks. */
int ilv4 = (dev->mem_ctl >> 8) & 4;
int8_t add = 0;
uint32_t pg = (dev->mem_ctl & 0x0800);
uint32_t nrt = WD76C10_ADDR_INVALID;
if (ret != WD76C10_ADDR_INVALID) {
if (dev->fast) for (int8_t i = 0; i < 4; i++) {
rb = &(dev->ram_banks[i]);
uint32_t ret2 = ret - rb->phys_addr;
if (rb->phys_on && (ret >= rb->phys_addr) &&
(ret < (rb->phys_addr + rb->phys_size))) {
if (ret2 < rb->phys_size)
nrt = ret2 + rb->phys_addr;
break;
}
} else for (int8_t i = 0; i < 4; i++) {
rb = &(dev->ram_banks[i]);
int ilv2 = (dev->mem_ctl >> 8) & (1 << (i >> 1));
uint32_t size = rb->virt_size;
uint32_t ret2 = ret - rb->virt_addr;
uint32_t ret4 = ret2;
uint32_t row = WD76C10_ADDR_INVALID;
uint32_t col = WD76C10_ADDR_INVALID;
uint32_t rb_or = 0;
if (ilv4) {
size <<= 2;
switch (rb->virt_size) {
default:
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00020000:
if (pg) {
row = (ret2 >> 9) & 0x0000fc;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 9) & 0x000003;
} else
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00080000:
if (pg) {
row = (ret2 >> 9) & 0x0000f8;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 21) & 0x000001) << 2;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 10) & 0x000003;
} else
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00200000:
if (pg) {
row = (ret2 >> 9) & 0x0000f0;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 21) & 0x000001) << 2;
row |= ((ret2 >> 23) & 0x000001) << 3;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 11) & 0x000003;
} else
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00800000:
if (pg) {
row = (ret2 >> 9) & 0x0000e0;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 21) & 0x000001) << 2;
row |= ((ret2 >> 23) & 0x000001) << 3;
row |= ((ret2 >> 24) & 0x000001) << 4;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 12) & 0x000003;
} else
ret4 = WD76C10_ADDR_INVALID;
break;
}
add = 3;
} else if (ilv2) {
size <<= 1;
switch (rb->virt_size) {
default:
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00020000:
if (pg) {
row = (ret2 >> 9) & 0x0000fe;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 9) & 0x000001;
} else {
row = (ret2 >> 1) & 0x0007fe;
row |= (ret2 >> 13) & 0x000001;
col = (ret2 >> 9) & 0x0000ef;
col |= ((ret2 >> 17) & 0x000001) << 4;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
rb_or = (ret2 >> 1) & 0x000001;
}
break;
case 0x00080000:
if (pg) {
row = (ret2 >> 9) & 0x0000fc;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 10) & 0x000001;
} else {
row = (ret2 >> 1) & 0x0007fe;
row |= (ret2 >> 13) & 0x000001;
col = (ret2 >> 9) & 0x0000ee;
col |= (ret2 >> 17) & 0x000001;
col |= ((ret2 >> 19) & 0x000001) << 4;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
rb_or = (ret2 >> 1) & 0x000001;
}
break;
case 0x00200000:
if (pg) {
row = (ret2 >> 9) & 0x0000f8;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 21) & 0x000001) << 2;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 11) & 0x000001;
} else {
row = (ret2 >> 1) & 0x0007fe;
row |= (ret2 >> 13) & 0x000001;
col = (ret2 >> 9) & 0x0000ec;
col |= (ret2 >> 17) & 0x000001;
col |= ((ret2 >> 19) & 0x000001) << 1;
col |= ((ret2 >> 21) & 0x000001) << 4;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
rb_or = (ret2 >> 1) & 0x000001;
}
break;
case 0x00800000:
if (pg) {
row = (ret2 >> 9) & 0x0000f0;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 21) & 0x000001) << 2;
row |= ((ret2 >> 23) & 0x000001) << 3;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x000007ff;
rb_or = (ret2 >> 12) & 0x000001;
} else {
row = (ret2 >> 1) & 0x0007fe;
row |= (ret2 >> 13) & 0x000001;
col = (ret2 >> 9) & 0x0000e0;
col |= (ret2 >> 17) & 0x000001;
col |= ((ret2 >> 19) & 0x000001) << 1;
col |= ((ret2 >> 21) & 0x000001) << 2;
col |= ((ret2 >> 23) & 0x000001) << 3;
col |= ((ret2 >> 12) & 0x000001) << 4;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
rb_or = (ret2 >> 1) & 0x000001;
}
break;
}
add = 1;
} else if (pg) switch (rb->virt_size) {
default:
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00020000:
row = (ret2 >> 9) & 0x0000ff;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x0007ff;
break;
case 0x00080000:
row = (ret2 >> 9) & 0x0000fe;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x0007ff;
break;
case 0x00200000:
row = (ret2 >> 9) & 0x0000fc;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x0007ff;
break;
case 0x00800000:
row = (ret2 >> 9) & 0x0000f8;
row |= (ret2 >> 17) & 0x000001;
row |= ((ret2 >> 19) & 0x000001) << 1;
row |= ((ret2 >> 21) & 0x000001) << 2;
row |= ((ret2 >> 18) & 0x000001) << 8;
row |= ((ret2 >> 20) & 0x000001) << 9;
row |= ((ret2 >> 22) & 0x000001) << 10;
col = (ret2 >> 1) & 0x0007ff;
break;
} else switch (rb->virt_size) {
default:
ret4 = WD76C10_ADDR_INVALID;
break;
case 0x00020000:
row = (ret2 >> 1) & 0x0007ff;
col = (ret2 >> 9) & 0x0000ff;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
break;
case 0x00080000:
row = (ret2 >> 1) & 0x0007ff;
col = (ret2 >> 9) & 0x0000fe;
col |= (ret2 >> 17) & 0x000001;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
break;
case 0x00200000:
row = (ret2 >> 1) & 0x0007ff;
col = (ret2 >> 9) & 0x0000fc;
col |= (ret2 >> 17) & 0x000001;
col |= ((ret2 >> 19) & 0x000001) << 1;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
break;
case 0x00800000:
row = (ret2 >> 1) & 0x0007ff;
col = (ret2 >> 9) & 0x0000f8;
col |= (ret2 >> 17) & 0x000001;
col |= ((ret2 >> 19) & 0x000001) << 1;
col |= ((ret2 >> 21) & 0x000001) << 2;
col |= ((ret2 >> 18) & 0x000001) << 8;
col |= ((ret2 >> 20) & 0x000001) << 9;
col |= ((ret2 >> 22) & 0x000001) << 10;
break;
}
if (row != WD76C10_ADDR_INVALID) {
ret4 = wd76c10_calc_phys(row & 0x0007ff, col & 0x0007ff,
rb->phys_size, ret2 & 0x000001);
if (ilv4 || ilv2)
rb = &(dev->ram_banks[i | rb_or]);
i += add;
}
if (rb->enable && (ret >= rb->virt_addr) &&
(ret < (rb->virt_addr + size))) {
if ((ret4 != WD76C10_ADDR_INVALID) && (rb->phys_size > 0x00000000))
nrt = ret4 + rb->phys_addr;
break;
}
}
ret = nrt;
}
if (ret >= (mem_size << 10))
/* The physical memory address is too high or disabled, which is invalid. */
ret = WD76C10_ADDR_INVALID;
/* Otherwise, map it to the correct bank so the BIOS can auto-size it correctly. */
else for (uint8_t i = 0; i < 4; i++) {
rb = &(dev->ram_banks[i]);
if (rb->enable && (ret >= rb->virt_addr) && (ret < (rb->virt_addr + rb->virt_size))) {
if (rb->phys_size == 0x00000000)
ret = WD76C10_ADDR_INVALID;
else
ret = ((ret - rb->virt_addr) % rb->phys_size) + rb->phys_addr;
break;
}
}
return ret;
}
@@ -185,8 +504,12 @@ wd76c10_read_ram(uint32_t addr, void *priv)
addr = wd76c10_calc_addr(dev, addr);
if (addr != WD76C10_ADDR_INVALID)
ret = mem_read_ram(addr, priv);
if (addr != WD76C10_ADDR_INVALID) {
if (dev->fast)
ret = mem_read_ram(addr, priv);
else
ret = ram[addr];
}
return ret;
}
@@ -199,8 +522,12 @@ wd76c10_read_ramw(uint32_t addr, void *priv)
addr = wd76c10_calc_addr(dev, addr);
if (addr != WD76C10_ADDR_INVALID)
ret = mem_read_ramw(addr, priv);
if (addr != WD76C10_ADDR_INVALID) {
if (dev->fast)
ret = mem_read_ramw(addr, priv);
else
ret = *(uint16_t *) &(ram[addr]);
}
return ret;
}
@@ -212,8 +539,12 @@ wd76c10_write_ram(uint32_t addr, uint8_t val, void *priv)
addr = wd76c10_calc_addr(dev, addr);
if (addr != WD76C10_ADDR_INVALID)
mem_write_ram(addr, val, priv);
if (addr != WD76C10_ADDR_INVALID) {
if (dev->fast)
mem_write_ram(addr, val, priv);
else
ram[addr] = val;
}
}
static void
@@ -223,8 +554,12 @@ wd76c10_write_ramw(uint32_t addr, uint16_t val, void *priv)
addr = wd76c10_calc_addr(dev, addr);
if (addr != WD76C10_ADDR_INVALID)
mem_write_ramw(addr, val, priv);
if (addr != WD76C10_ADDR_INVALID) {
if (dev->fast)
mem_write_ramw(addr, val, priv);
else
*(uint16_t *) &(ram[addr]) = val;
}
}
static void
@@ -258,6 +593,9 @@ wd76c10_recalc_exec(wd76c10_t *dev, uint32_t base, uint32_t size)
static void
wd76c10_banks_recalc(wd76c10_t *dev)
{
int match = 0;
dev->fast = 0;
for (uint8_t i = 0; i < 4; i++) {
ram_bank_t *rb = &(dev->ram_banks[i]);
uint8_t bit = i << 1;
@@ -266,8 +604,42 @@ wd76c10_banks_recalc(wd76c10_t *dev)
rb->enable = (dev->split_sa >> bit) & 0x01;
rb->virt_addr = ((uint32_t) dev->bank_bases[i]) << 17;
if (rb->enable) {
rb->adj_virt_addr = rb->virt_addr;
rb->adj_virt_size = rb->virt_size;
if (dev->mem_ctl & 0x0400)
rb->adj_virt_addr += (i * rb->adj_virt_size);
else if ((dev->mem_ctl >> 8) & (1 << (i >> 1)))
rb->adj_virt_addr += ((i & 1) * rb->adj_virt_size);
} else {
rb->adj_virt_addr = WD76C10_ADDR_INVALID;
rb->adj_virt_size = 0x00000000;
}
if ((rb->enable == rb->phys_on) &&
(rb->adj_virt_addr == rb->phys_addr) &&
(rb->adj_virt_size == rb->phys_size))
match++;
}
dev->fast = (match == 4);
for (uint8_t i = 0; i < 4; i++) {
ram_bank_t *rb = &(dev->ram_banks[i]);
if (cpu_use_exec)
wd76c10_recalc_exec(dev, rb->virt_addr, rb->virt_size);
wd76c10_log("Bank %i (%s), physical: %i, %08X-%08X, "
"virtual: %i, %08X-%08X, adj.: %i, %08X-%08X\n",
i, dev->fast ? "FAST" : "SLOW",
rb->phys_on,
rb->phys_addr, rb->phys_addr + rb->phys_size - 1,
rb->enable,
rb->virt_addr, rb->virt_addr + rb->virt_size - 1,
rb->enable,
rb->adj_virt_addr, rb->adj_virt_addr + rb->adj_virt_size - 1);
}
}
@@ -899,11 +1271,22 @@ wd76c10_init(UNUSED(const device_t *info))
}
}
if (size != 0x00000000) {
rb->phys_on = 1;
rb->phys_addr = accum_mem;
rb->phys_size = size;
wd76c10_log("Bank %i size: %5i KiB, starting at %5i KiB\n", i, rb->phys_size >> 10, rb->phys_addr >> 10);
total_mem -= size;
accum_mem += size;
}
} else
rb->phys_addr = WD76C10_ADDR_INVALID;
}
if (mem_size == 3072) {
/* Reorganize the banks a bit so, we have 2048, 0, 512, 512. */
ram_bank_t rt = dev->ram_banks[3];
dev->ram_banks[3] = dev->ram_banks[2];
dev->ram_banks[2] = dev->ram_banks[1];
dev->ram_banks[1] = rt;
}
rb = &(dev->ram_banks[4]);

View File

@@ -152,7 +152,13 @@ ropMOV_b_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t
{
if ((fetchdat & 0xc0) == 0xc0) {
STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff);
} else {
}
/* TODO: Fix the recompilation of that specific case so it no longer breaks NT 3.x NTVDM. */
#ifndef RECOMPILE_MOVB_IMM_MEM_ALWAYS
else if (((fetchdat & 0xfc) == 0x80) && (op_32 & 0x200))
return 0;
#endif
else {
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadb(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
@@ -594,12 +600,12 @@ ropMOV_seg_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t
MEM_LOAD_ADDR_EA_L(target_seg); \
STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, 0); \
LOAD_EA(); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4, op_32); \
} else { \
MEM_LOAD_ADDR_EA_W(target_seg); \
STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, 0); \
LOAD_EA(); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2, op_32); \
} \
LOAD_SEG(0, &rseg); \
if (op_32 & 0x100) { \

View File

@@ -1049,11 +1049,18 @@ MEM_LOAD_ADDR_EA_W(x86seg *seg)
/*done:*/
}
static __inline void
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset, int op_32)
{
addbyte(0x83); /*ADD EAX, offset*/
addbyte(0xc0);
addbyte(offset);
if (!(op_32 & 0x200)) {
addbyte(0x25); /* AND EAX, ffffh */
addbyte(0xff);
addbyte(0xff);
addbyte(0x00);
addbyte(0x00);
}
MEM_LOAD_ADDR_EA_W(seg);
}
static __inline void

View File

@@ -789,7 +789,7 @@ MEM_LOAD_ADDR_EA_W(x86seg *seg)
host_reg_mapping[0] = 8;
}
static __inline void
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset, int op_32)
{
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) {
addbyte(0x31); /*XOR EDX, EDX*/
@@ -802,6 +802,13 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
addbyte(0x83); /*ADD EAX, offset*/
addbyte(0xc0);
addbyte(offset);
if (!(op_32 & 0x200)) {
addbyte(0x25); /* AND EAX, ffffh */
addbyte(0xff);
addbyte(0xff);
addbyte(0x00);
addbyte(0x00);
}
addbyte(0xe8); /*CALL mem_load_addr_ea_w*/
addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4]));

View File

@@ -819,6 +819,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
int pc_off = 0;
int test_modrm = 1;
int c;
uint32_t op87 = 0x00000000;
op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 0;
@@ -872,6 +873,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xd8:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
opcode_shift = 3;
@@ -882,6 +884,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xd9:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
@@ -891,6 +894,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xda:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
opcode_mask = 0xff;
@@ -900,6 +904,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdb:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
opcode_mask = 0xff;
@@ -909,6 +914,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdc:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
opcode_shift = 3;
@@ -919,6 +925,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdd:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
@@ -928,6 +935,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xde:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
opcode_mask = 0xff;
@@ -937,6 +945,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdf:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
opcode_mask = 0xff;
@@ -1000,6 +1009,10 @@ generate_call:
recomp_op_table = recomp_opcodes;
}
if (op87 != 0x0000) {
STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87);
}
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
if (new_pc) {

View File

@@ -1858,6 +1858,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
int pc_off = 0;
int test_modrm = 1;
int c;
uint32_t op87 = 0x00000000;
op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 0;
@@ -1912,6 +1913,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break;
case 0xd8:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
opcode_shift = 3;
@@ -1922,6 +1924,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xd9:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
@@ -1931,6 +1934,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xda:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
opcode_mask = 0xff;
@@ -1940,6 +1944,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdb:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
opcode_mask = 0xff;
@@ -1949,6 +1954,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdc:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
opcode_shift = 3;
@@ -1959,6 +1965,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdd:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
@@ -1968,6 +1975,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xde:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
opcode_mask = 0xff;
@@ -1977,6 +1985,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
block->flags |= CODEBLOCK_HAS_FPU;
break;
case 0xdf:
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
opcode_mask = 0xff;
@@ -2041,6 +2050,10 @@ generate_call:
recomp_op_table = recomp_opcodes;
}
if (op87 != 0x0000) {
STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87);
}
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
if (new_pc) {

View File

@@ -396,6 +396,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
int test_modrm = 1;
int pc_off = 0;
uint32_t next_pc = 0;
uint16_t op87 = 0x0000;
#ifdef DEBUG_EXTRA
uint8_t last_prefix = 0;
#endif
@@ -451,6 +452,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xd8;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
opcode_shift = 3;
@@ -464,6 +466,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xd9;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff;
@@ -476,6 +479,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xda;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
opcode_mask = 0xff;
@@ -488,6 +492,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdb;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
opcode_mask = 0xff;
@@ -500,6 +505,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdc;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
opcode_shift = 3;
@@ -513,6 +519,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdd;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff;
@@ -525,6 +532,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xde;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
opcode_mask = 0xff;
@@ -537,6 +545,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA
last_prefix = 0xdf;
#endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
opcode_mask = 0xff;
@@ -657,6 +666,9 @@ generate_call:
}
}
codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off);
if (op87 != 0x0000) {
uop_MOV_IMM(ir, IREG_x87_op, op87);
}
/* It is apparently a prefixed instruction. */
#if 0
if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48))

View File

@@ -306,6 +306,7 @@ struct ir_data_t;
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset);
extern void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
extern void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
extern void codegen_check_regs(void);
extern int codegen_purge_purgable_list(void);
/*Delete a random code block to free memory. This is obviously quite expensive, and

View File

@@ -931,6 +931,8 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0);
if (uop->imm_data)
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
if (uop->is_a16)
host_arm64_AND_IMM(block, REG_X0, REG_X0, 0xffff);
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) {
host_arm64_call(block, codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -995,6 +995,8 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
if (uop->imm_data)
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
if (uop->is_a16)
host_arm_AND_IMM(block, REG_R0, REG_R0, 0xffff);
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) {
host_arm_BL(block, (uintptr_t) codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -329,7 +329,7 @@ codegen_backend_init(void)
host_x86_POP(block, REG_RSI);
#endif
host_x86_POP(block, REG_RBP);
host_x86_POP(block, REG_RDX);
host_x86_POP(block, REG_RBX);
host_x86_RET(block);
block_write_data = NULL;
@@ -392,7 +392,7 @@ codegen_backend_epilogue(codeblock_t *block)
host_x86_POP(block, REG_RSI);
#endif
host_x86_POP(block, REG_RBP);
host_x86_POP(block, REG_RDX);
host_x86_POP(block, REG_RBX);
host_x86_RET(block);
}
#endif

View File

@@ -997,8 +997,12 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
if (uop->imm_data)
if (uop->imm_data) {
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
if (uop->is_a16) {
host_x86_AND32_REG_IMM(block, REG_ESI, 0x0000ffff);
}
}
if (REG_IS_B(dest_size)) {
host_x86_CALL(block, codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -981,8 +981,12 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
if (uop->imm_data)
if (uop->imm_data) {
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
if (uop->is_a16) {
host_x86_AND32_REG_IMM(block, REG_ESI, 0x0000ffff);
}
}
if (REG_IS_B(dest_size)) {
host_x86_CALL(block, codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -217,6 +217,7 @@ block_free_list_get(void)
void
codegen_init(void)
{
codegen_check_regs();
codegen_allocator_init();
codegen_backend_init();

View File

@@ -340,6 +340,7 @@ typedef struct uop_t {
void *p;
ir_host_reg_t dest_reg_a_real;
ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real;
int is_a16;
int jump_dest_uop;
int jump_list_next;
void *jump_dest;
@@ -364,6 +365,8 @@ uop_alloc(ir_data_t *ir, uint32_t uop_type)
uop = &ir->uops[ir->wr_pos++];
uop->is_a16 = 0;
uop->dest_reg_a = invalid_ir_reg;
uop->src_reg_a = invalid_ir_reg;
uop->src_reg_b = invalid_ir_reg;
@@ -488,8 +491,14 @@ uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src
uop_t *uop = uop_alloc(ir, uop_type);
uop->type = uop_type;
uop->is_a16 = 0;
uop->src_reg_a = codegen_reg_read(src_reg_a);
uop->src_reg_b = codegen_reg_read(src_reg_b);
if (src_reg_b == IREG_eaa16) {
uop->src_reg_b = codegen_reg_read(IREG_eaaddr);
uop->is_a16 = 1;
} else
uop->src_reg_b = codegen_reg_read(src_reg_b);
uop->is_a16 = 0;
uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1);
uop->imm_data = imm;
}

View File

@@ -533,8 +533,8 @@ ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSE
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \
codegen_check_seg_read(block, ir, target_seg); \
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16); \
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 2); \
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \
\
@@ -556,8 +556,8 @@ ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSE
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \
codegen_check_seg_read(block, ir, target_seg); \
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16); \
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 4); \
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \
\

View File

@@ -296,7 +296,13 @@ ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t
imm = fastreadb(cs + op_pc + 1);
uop_MOV_IMM(ir, IREG_8(dest_reg), imm);
} else {
}
/* TODO: Fix the recompilation of that specific case so it no longer breaks NT 3.x NTVDM. */
#ifndef RECOMPILE_MOVB_IMM_MEM_ALWAYS
else if (((fetchdat & 0xfc) == 0x80) && (op_32 & 0x200))
return 0;
#endif
else {
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
codegen_check_seg_write(block, ir, target_seg);

View File

@@ -169,6 +169,9 @@ struct
[IREG_GS_limit_high] = { REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT},
[IREG_eaa16] = { REG_WORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT},
[IREG_x87_op] = { REG_WORD, &x87_op, REG_INTEGER, REG_PERMANENT},
/*Temporary registers are stored on the stack, and are not guaranteed to
be preserved across uOPs. They will not be written back if they will
not be read again.*/
@@ -223,6 +226,20 @@ reg_is_native_size(ir_reg_t ir_reg)
return 0;
}
void
codegen_check_regs(void)
{
int i = 0;
for (i = 0; i < IREG_COUNT; i++) {
if (ireg_data[i].is_volatile == REG_VOLATILE)
continue;
if (ireg_data[i].p && ((uintptr_t)ireg_data[i].p - (uintptr_t)&cpu_state) >= sizeof(cpu_state)) {
fatal("Register number %d outside cpu_state!\n", i);
}
}
}
void
codegen_reg_reset(void)
{

View File

@@ -132,7 +132,10 @@ enum {
IREG_GS_limit_high = 86,
IREG_SS_limit_high = 87,
IREG_COUNT = 88,
IREG_eaa16 = 88,
IREG_x87_op = 89,
IREG_COUNT = 90,
IREG_INVALID = 255,

View File

@@ -107,6 +107,7 @@ config_log(const char *fmt, ...)
# define config_log(fmt, ...)
#endif
/* Load "General" section. */
static void
load_general(void)
@@ -185,6 +186,8 @@ load_general(void)
p = ini_section_get_string(cat, "language", NULL);
if (p != NULL)
lang_id = plat_language_code(p);
else
lang_id = plat_language_code(DEFAULT_LANGUAGE);
mouse_sensitivity = ini_section_get_double(cat, "mouse_sensitivity", 1.0);
if (mouse_sensitivity < 0.1)
@@ -743,7 +746,7 @@ load_ports(void)
char temp[512];
memset(temp, 0, sizeof(temp));
for (int c = 0; c < SERIAL_MAX; c++) {
for (int c = 0; c < (SERIAL_MAX - 1); c++) {
sprintf(temp, "serial%d_enabled", c + 1);
com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1);
@@ -1760,6 +1763,36 @@ load_gl3_shaders(void)
}
#endif
/* Load "Keybinds" section. */
static void
load_keybinds(void)
{
ini_section_t cat = ini_find_section(config, "Keybinds");
char *p;
char temp[512];
memset(temp, 0, sizeof(temp));
/* Now load values from config */
for (int x = 0; x < NUM_ACCELS; x++) {
p = ini_section_get_string(cat, acc_keys[x].name, "default");
/* Check if the binding was marked as cleared */
if (strcmp(p, "none") == 0)
acc_keys[x].seq[0] = '\0';
/* If there's no binding in the file, leave it alone. */
else if (strcmp(p, "default") != 0) {
/*
It would be ideal to validate whether the user entered a
valid combo at this point, but the Qt method for testing that is
not available from C. Fortunately, if you feed Qt an invalid
keysequence string it just assigns nothing, so this won't blow up.
However, to improve the user experience, we should validate keys
and erase any bad combos from config on mainwindow load.
*/
strcpy(acc_keys[x].seq, p);
}
}
}
/* Load the specified or a default configuration file. */
void
config_load(void)
@@ -1806,7 +1839,7 @@ config_load(void)
com_ports[0].enabled = 1;
com_ports[1].enabled = 1;
for (i = 2; i < SERIAL_MAX; i++)
for (i = 2; i < (SERIAL_MAX - 1); i++)
com_ports[i].enabled = 0;
lpt_ports[0].enabled = 1;
@@ -1840,6 +1873,8 @@ config_load(void)
cassette_pcm = 0;
cassette_ui_writeprot = 0;
lang_id = plat_language_code(DEFAULT_LANGUAGE);
config_log("Config file not present or invalid!\n");
} else {
load_general(); /* General */
@@ -1859,6 +1894,7 @@ config_load(void)
#ifndef USE_SDL_UI
load_gl3_shaders(); /* GL3 Shaders */
#endif
load_keybinds(); /* Load shortcut keybinds */
/* Migrate renamed device configurations. */
c = ini_find_section(config, "MDA");
@@ -2025,7 +2061,7 @@ save_general(void)
else
ini_section_delete_var(cat, "mouse_sensitivity");
if (lang_id == DEFAULT_LANGUAGE)
if (lang_id == plat_language_code(DEFAULT_LANGUAGE))
ini_section_delete_var(cat, "language");
else {
plat_language_code_r(lang_id, buffer, 511);
@@ -2423,7 +2459,7 @@ save_ports(void)
ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)");
char temp[512];
for (int c = 0; c < SERIAL_MAX; c++) {
for (int c = 0; c < (SERIAL_MAX - 1); c++) {
sprintf(temp, "serial%d_enabled", c + 1);
if (((c < 2) && com_ports[c].enabled) || ((c >= 2) && !com_ports[c].enabled))
ini_section_delete_var(cat, temp);
@@ -2484,6 +2520,26 @@ save_ports(void)
ini_delete_section_if_empty(config, cat);
}
/* Save "Keybinds" section. */
static void
save_keybinds(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Keybinds");
for (int x = 0; x < NUM_ACCELS; x++) {
/* Has accelerator been changed from default? */
if (strcmp(def_acc_keys[x].seq, acc_keys[x].seq) == 0)
ini_section_delete_var(cat, acc_keys[x].name);
/* Check for a cleared binding to avoid saving it as an empty string */
else if (acc_keys[x].seq[0] == '\0')
ini_section_set_string(cat, acc_keys[x].name, "none");
else
ini_section_set_string(cat, acc_keys[x].name, acc_keys[x].seq);
}
ini_delete_section_if_empty(config, cat);
}
/* Save "Storage Controllers" section. */
static void
save_storage_controllers(void)
@@ -3094,6 +3150,7 @@ config_save(void)
#ifndef USE_SDL_UI
save_gl3_shaders(); /* GL3 Shaders */
#endif
save_keybinds(); /* Key bindings */
ini_write(config, cfg_path);
}

View File

@@ -277,6 +277,19 @@ int checkio(uint32_t port, int mask);
#define CHECK_WRITE(chseg, low, high) \
CHECK_WRITE_COMMON(chseg, low, high)
#define CHECK_WRITE_2OP(chseg, low, high, low2, high2) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || (low2 < (chseg)->limit_low) || (high2 > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \
x86gpf("Limit check (WRITE)", 0); \
return 1; \
} \
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
if ((chseg) == &cpu_state.seg_ss) \
x86ss(NULL, (chseg)->seg & 0xfffc); \
else \
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
return 1; \
}
#define CHECK_WRITE_REP(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
x86gpf("Limit check (WRITE REP)", 0); \

View File

@@ -38,6 +38,7 @@
#include <86box/ppi.h>
#include <86box/timer.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
/* Is the CPU 8088 or 8086. */
@@ -3438,10 +3439,13 @@ execx86(int cycs)
set_pzs(8);
break;
case 0xD6: /*SALC*/
wait(1, 0);
AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00;
wait(1, 0);
break;
if (!is_nec) {
wait(1, 0);
AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00;
wait(1, 0);
break;
}
fallthrough;
case 0xD7: /*XLATB*/
cpu_state.eaaddr = (BX + AL) & 0xffff;
access(4, 8);

View File

@@ -2448,11 +2448,6 @@ cpu_CPUID(void)
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
/*
Return anything non-zero in bits 32-63 of the BIOS signature MSR
to indicate there has been an update.
*/
msr.bbl_cr_dx[3] = 0xffffffff00000000ULL;
} else
EAX = EBX = ECX = EDX = 0;
break;
@@ -2467,6 +2462,11 @@ cpu_CPUID(void)
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
/*
Return anything non-zero in bits 32-63 of the BIOS signature MSR
to indicate there has been an update.
*/
msr.bbl_cr_dx[3] = 0xffffffff00000000ULL;
} else if (EAX == 2) {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries
@@ -2649,6 +2649,12 @@ cpu_ven_reset(void)
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
msr.mtrr_cap = 0x00000508ULL;
/* 4 GB cacheable space on Deschutes 651h and later (including the 1632h
Overdrive) according to the Pentium II Processor Specification Update.
Covington 651h (no L2 cache) reports the same 512 MB value as Klamath. */
if (CPUID >= (!strncmp(cpu_f->internal_name, "celeron", 7) ? 0x660 : 0x651))
msr.bbl_cr_ctl3 |= 0x00300000;
break;
case CPU_CYRIX3S:
@@ -3295,7 +3301,6 @@ pentium_invalid_rdmsr:
case 0x88 ... 0x8b:
EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff;
EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32;
// EDX |= 0xffffffff;
break;
/* Unknown */
case 0xae:
@@ -4103,7 +4108,7 @@ pentium_invalid_wrmsr:
break;
/* BBL_CR_CTL3 - L2 Cache Control Register 3 */
case 0x11e:
msr.bbl_cr_ctl3 = EAX | ((uint64_t) EDX << 32);
msr.bbl_cr_ctl3 = (msr.bbl_cr_ctl3 & 0x02f00000) | (EAX & ~0x02f00000) | ((uint64_t) EDX << 32);
break;
/* Unknown */
case 0x131:

View File

@@ -335,7 +335,10 @@ typedef struct {
uint8_t tag[8];
x86seg *ea_seg;
uint32_t eaaddr;
union {
uint32_t eaaddr;
uint16_t eaa16[2];
};
int flags_op;
uint32_t flags_res;
@@ -413,6 +416,8 @@ typedef struct {
uint16_t eflags;
uint32_t _smbase;
uint32_t x87_op;
} cpu_state_t;
#define in_smm cpu_state._in_smm
@@ -781,6 +786,8 @@ typedef struct {
uint32_t smhr;
} cyrix_t;
#define x87_op cpu_state.x87_op
extern uint32_t addr64;
extern uint32_t addr64_2;
extern uint32_t addr64a[8];

View File

@@ -7793,7 +7793,7 @@ const cpu_family_t cpu_families[] = {
{
.package = CPU_PKG_SOCKET370,
.manufacturer = "VIA",
.name = "Cyrix III",
.name = "Cyrix III (Samuel)",
.internal_name = "c3_samuel",
.cpus = (const CPU[]) {
{ /* out of multiplier range */

View File

@@ -272,6 +272,7 @@ reset_common(int hard)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
msw = 0;
new_ne = 0;
x87_op = 0;
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = ccr7 = 0;
ccr4 = 0x85;
@@ -325,7 +326,6 @@ reset_common(int hard)
resetreadlookup();
makemod1table();
cpu_set_edx();
mmu_perm = 4;
}
x86seg_reset();
#ifdef USE_DYNAREC

View File

@@ -4,88 +4,104 @@
static int
opESCAPE_d8_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_d8_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_d9_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_d9_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_da_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_da_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_db_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_db_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_dc_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_dc_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_dd_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_dd_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_de_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_de_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_df_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_df_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
}

View File

@@ -4,88 +4,104 @@
static int
opESCAPE_d8_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_d8_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_d9_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_d9_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_da_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_da_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_db_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_db_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_dc_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_dc_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int
opESCAPE_dd_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_dd_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_de_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_de_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_df_a16(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat);
}
static int
opESCAPE_df_a32(uint32_t fetchdat)
{
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat);
}

View File

@@ -46,8 +46,6 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
if (CPUID < 0x650)
return ILLEGAL(fetchdat);
FP_ENTER();
if (bits == 32) {
fetch_ea_32(fetchdat);
} else {
@@ -82,12 +80,18 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */
fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF;
fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8);
if (bits == 32)
fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8);
else
fpu_state.fip = readmemw(easeg, cpu_state.eaaddr + 8);
fpu_state.fcs = readmemw(easeg, cpu_state.eaaddr + 12);
tag_byte = readmemb(easeg, cpu_state.eaaddr + 4);
fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16);
if (bits == 32)
fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16);
else
fpu_state.fdp = readmemw(easeg, cpu_state.eaaddr + 16);
fpu_state.fds = readmemw(easeg, cpu_state.eaaddr + 20);
/* load i387 register file */
@@ -110,7 +114,6 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
CLOCK_CYCLES(1);
} else {
/* FXSAVE */
@@ -132,7 +135,10 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
* x87 CS FPU IP Selector
* + 16 bit, in 16/32 bit mode only
*/
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip);
if (bits == 32)
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip);
else
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip & 0xffff);
writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs);
/*
@@ -145,7 +151,10 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
* x87 DS FPU Instruction Operand (Data) Pointer Selector
* + 16 bit, in 16/32 bit mode only
*/
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp);
if (bits == 32)
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp);
else
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp & 0xffff);
writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds);
/* store i387 register file */
@@ -256,8 +265,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
return cpu_state.abrt;
}
FP_ENTER();
old_eaaddr = cpu_state.eaaddr;
if (fxinst == 1) {
@@ -269,13 +276,19 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
cpu_state.TOP = (fpus >> 11) & 7;
cpu_state.npxs &= fpus & ~0x3800;
x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8);
if (bits == 32)
x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8);
else
x87_pc_off = readmemw(easeg, cpu_state.eaaddr + 8);
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12);
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
x87_op = readmemw(easeg, cpu_state.eaaddr + 6) & 0x07ff;
x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16);
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
if (bits == 32)
x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16);
else
x87_op_off = readmemw(easeg, cpu_state.eaaddr +16);
x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20);
for (i = 0; i <= 7; i++) {
@@ -320,7 +333,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
}
}
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
CLOCK_CYCLES(1);
} else {
/* FXSAVE */
@@ -345,11 +357,17 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs);
writememb(easeg, cpu_state.eaaddr + 4, ftwb);
writememw(easeg, cpu_state.eaaddr + 6, (x87_op_off >> 16) << 12);
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off);
writememw(easeg, cpu_state.eaaddr + 6, x87_op);
if (bits == 32)
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off);
else
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off & 0xffff);
writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg);
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off);
if (bits == 32)
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off);
else
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off & 0xffff);
writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg);
if (cpu_state.ismmx) {

View File

@@ -22,12 +22,12 @@
}
#define MMX_ENTER() \
if (!cpu_has_feature(CPU_FEATURE_MMX)) { \
if (!cpu_has_feature(CPU_FEATURE_MMX) || (cr0 & 0x4)) { \
cpu_state.pc = cpu_state.oldpc; \
x86illegal(); \
return 1; \
} \
if (cr0 & 0xc) { \
if (cr0 & 0x8) { \
x86_int(7); \
return 1; \
} \

View File

@@ -201,8 +201,6 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (hascache && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else
@@ -267,8 +265,6 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (hascache && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else

View File

@@ -193,8 +193,6 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (hascache && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else
@@ -255,8 +253,6 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
mmu_perm = 4;
if (hascache && !(cr0 & (1 << 30)))
cpu_cache_int_enabled = 1;
else

View File

@@ -272,9 +272,13 @@ opLDS_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff));
addr = readmemw(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
cpu_state.eaa16[0] += 2;
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff));
seg = readmemw(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ds);
@@ -318,9 +322,13 @@ opLDS_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 3) & 0xffff));
addr = readmeml(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
cpu_state.eaa16[0] += 4;
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff));
seg = readmemw(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ds);
@@ -365,9 +373,13 @@ opLSS_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff));
addr = readmemw(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
cpu_state.eaa16[0] += 2;
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff));
seg = readmemw(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ss);
@@ -411,9 +423,13 @@ opLSS_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 3) & 0xffff));
addr = readmeml(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
cpu_state.eaa16[0] += 4;
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff));
seg = readmemw(easeg, cpu_state.eaa16[0]);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ss);
@@ -457,9 +473,13 @@ opLSS_l_a32(uint32_t fetchdat)
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff)); \
addr = readmemw(easeg, cpu_state.eaa16[0]); \
if (cpu_state.abrt) \
return 1; \
cpu_state.eaa16[0] += 2; \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff)); \
seg = readmemw(easeg, cpu_state.eaa16[0]); \
if (cpu_state.abrt) \
return 1; \
op_loadseg(seg, &sel); \
@@ -502,9 +522,13 @@ opLSS_l_a32(uint32_t fetchdat)
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 3) & 0xffff)); \
addr = readmeml(easeg, cpu_state.eaa16[0]); \
if (cpu_state.abrt) \
return 1; \
cpu_state.eaa16[0] += 4; \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 1) & 0xffff)); \
seg = readmemw(easeg, cpu_state.eaa16[0]); \
if (cpu_state.abrt) \
return 1; \
op_loadseg(seg, &sel); \

View File

@@ -15,7 +15,7 @@
op_loadcs(readmemw(ss, ESP + 2)); \
} else { \
cpu_state.pc = readmemw(ss, SP); \
op_loadcs(readmemw(ss, SP + 2)); \
op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \
} \
if (cpu_state.abrt) \
return 1; \

View File

@@ -15,7 +15,7 @@
op_loadcs(readmemw(ss, ESP + 2)); \
} else { \
cpu_state.pc = readmemw(ss, SP); \
op_loadcs(readmemw(ss, SP + 2)); \
op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \
} \
if (cpu_state.abrt) \
return 1; \

View File

@@ -84,7 +84,10 @@ static uint8_t bug_spcfg; /* serial port configuration */
#define FIFO_LEN 256
static uint8_t bug_buff[FIFO_LEN]; /* serial port data buffer */
static uint8_t *bug_bptr;
#define UISTR_LEN 24
static char LED_R[] = "<font color=\"#EE0000\">R</font>";
static char LED_G[] = "<font color=\"#00CC00\">G</font>";
#define UISTR_LEN (17 + 8 * sizeof(LED_G) + 8 * sizeof(LED_R))
static char bug_str[UISTR_LEN]; /* UI output string */
extern void ui_sb_bugui(char *__str);
@@ -112,16 +115,16 @@ static void
bug_setui(void)
{
/* Format all current info in a string. */
sprintf(bug_str, "%02X:%02X %c%c%c%c%c%c%c%c-%c%c%c%c%c%c%c%c",
sprintf(bug_str, "<tt>%02X:%02X %s%s%s%s%s%s%s%s-%s%s%s%s%s%s%s%s</tt>",
bug_seg2, bug_seg1,
(bug_ledg & 0x80) ? 'G' : 'g', (bug_ledg & 0x40) ? 'G' : 'g',
(bug_ledg & 0x20) ? 'G' : 'g', (bug_ledg & 0x10) ? 'G' : 'g',
(bug_ledg & 0x08) ? 'G' : 'g', (bug_ledg & 0x04) ? 'G' : 'g',
(bug_ledg & 0x02) ? 'G' : 'g', (bug_ledg & 0x01) ? 'G' : 'g',
(bug_ledr & 0x80) ? 'R' : 'r', (bug_ledr & 0x40) ? 'R' : 'r',
(bug_ledr & 0x20) ? 'R' : 'r', (bug_ledr & 0x10) ? 'R' : 'r',
(bug_ledr & 0x08) ? 'R' : 'r', (bug_ledr & 0x04) ? 'R' : 'r',
(bug_ledr & 0x02) ? 'R' : 'r', (bug_ledr & 0x01) ? 'R' : 'r');
(bug_ledg & 0x80) ? LED_G : "g", (bug_ledg & 0x40) ? LED_G : "g",
(bug_ledg & 0x20) ? LED_G : "g", (bug_ledg & 0x10) ? LED_G : "g",
(bug_ledg & 0x08) ? LED_G : "g", (bug_ledg & 0x04) ? LED_G : "g",
(bug_ledg & 0x02) ? LED_G : "g", (bug_ledg & 0x01) ? LED_G : "g",
(bug_ledr & 0x80) ? LED_R : "r", (bug_ledr & 0x40) ? LED_R : "r",
(bug_ledr & 0x20) ? LED_R : "r", (bug_ledr & 0x10) ? LED_R : "r",
(bug_ledr & 0x08) ? LED_R : "r", (bug_ledr & 0x04) ? LED_R : "r",
(bug_ledr & 0x02) ? LED_R : "r", (bug_ledr & 0x01) ? LED_R : "r");
/* Send formatted string to the UI. */
ui_sb_bugui(bug_str);

View File

@@ -509,9 +509,6 @@ kbc_scan_kbd_at(atkbc_t *dev)
}
}
static void
write_p2(atkbc_t *dev, uint8_t val);
static void
kbc_at_poll_at(atkbc_t *dev)
{
@@ -778,6 +775,7 @@ static void
write_p2(atkbc_t *dev, uint8_t val)
{
uint8_t old = dev->p2;
kbc_at_log("ATkbc: write P2: %02X (old: %02X)\n", val, dev->p2);
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
@@ -851,6 +849,25 @@ write_p2(atkbc_t *dev, uint8_t val)
}
}
uint8_t
kbc_at_read_p(void *priv, uint8_t port, uint8_t mask)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t *p = (port == 2) ? &dev->p2 : &dev->p1;
uint8_t ret = *p & mask;
return ret;
}
void
kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t val)
{
atkbc_t *dev = (atkbc_t *) priv;
uint8_t *p = (port == 2) ? &dev->p2 : &dev->p1;
*p = (*p & mask) | val;
}
static void
write_p2_fast_a20(atkbc_t *dev, uint8_t val)
{
@@ -1070,10 +1087,14 @@ write64_generic(void *priv, uint8_t val)
fixed_bits |= 8;
/* (B0 or F0) | (0x04 or 0x0c) */
kbc_delay_to_ob(dev, dev->p1 | fixed_bits, 0, 0x00);
} else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN))
} else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) {
/* (B0 or F0) | (0x08 or 0x0c) */
kbc_delay_to_ob(dev, ((dev->p1 | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00);
else if (kbc_ven == KBC_VEN_COMPAQ)
uint8_t p1_out = ((dev->p1 | fixed_bits) & 0xf0) |
(((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c);
if (!strcmp(machine_get_internal_name(), "alfredo"))
p1_out &= 0xef;
kbc_delay_to_ob(dev, p1_out, 0, 0x00);
} else if (kbc_ven == KBC_VEN_COMPAQ)
kbc_delay_to_ob(dev, dev->p1 | (hasfpu ? 0x00 : 0x04), 0, 0x00);
else
/* (B0 or F0) | (0x04 or 0x44) */
@@ -1578,8 +1599,13 @@ write64_phoenix(void *priv, uint8_t val)
case 0xd5: /* Read MultiKey code revision level */
kbc_at_log("ATkbc: Phoenix - Read MultiKey code revision level\n");
if (dev->misc_flags & FLAG_PS2) {
kbc_at_queue_add(dev, 0x04);
kbc_at_queue_add(dev, 0x16);
if (dev->flags & DEVICE_PCI) {
kbc_at_queue_add(dev, 0x04);
kbc_at_queue_add(dev, 0x16);
} else {
kbc_at_queue_add(dev, 0x01);
kbc_at_queue_add(dev, 0x38);
}
} else {
kbc_at_queue_add(dev, 0x01);
kbc_at_queue_add(dev, 0x29);
@@ -1598,9 +1624,15 @@ write64_phoenix(void *priv, uint8_t val)
case 0xd7: /* Read MultiKey model numbers */
kbc_at_log("ATkbc: Phoenix - Read MultiKey model numbers\n");
if (dev->misc_flags & FLAG_PS2) {
kbc_at_queue_add(dev, 0x02);
kbc_at_queue_add(dev, 0x87);
kbc_at_queue_add(dev, 0x02);
if (dev->flags & DEVICE_PCI) {
kbc_at_queue_add(dev, 0x02);
kbc_at_queue_add(dev, 0x87);
kbc_at_queue_add(dev, 0x02);
} else {
kbc_at_queue_add(dev, 0x99);
kbc_at_queue_add(dev, 0x75);
kbc_at_queue_add(dev, 0x01);
}
} else {
kbc_at_queue_add(dev, 0x90);
kbc_at_queue_add(dev, 0x88);
@@ -2608,6 +2640,20 @@ const device_t keyboard_ps2_ami_device = {
.config = NULL
};
const device_t keyboard_ps2_compaq_device = {
.name = "PS/2 Keyboard (Compaq)",
.internal_name = "keyboard_at_compaq",
.flags = DEVICE_KBC,
.local = KBC_TYPE_PS2_1 | KBC_VEN_COMPAQ,
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_ps2_holtek_device = {
.name = "PS/2 Keyboard (Holtek)",
.internal_name = "keyboard_ps2_holtek",
@@ -2775,3 +2821,17 @@ const device_t keyboard_ps2_acer_pci_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_ps2_phoenix_pci_device = {
.name = "PS/2 Keyboard (Phoenix)",
.internal_name = "keyboard_ps2_phoenix_pci",
.flags = DEVICE_KBC | DEVICE_PCI,
.local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX,
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -36,14 +36,6 @@ uint16_t scancode_map[768] = { 0 };
int keyboard_scan;
/* F8+F12 */
uint16_t key_prefix_1_1 = 0x042; /* F8 */
uint16_t key_prefix_1_2 = 0x000; /* Invalid */
uint16_t key_prefix_2_1 = 0x000; /* Invalid */
uint16_t key_prefix_2_2 = 0x000; /* Invalid */
uint16_t key_uncapture_1 = 0x058; /* F12 */
uint16_t key_uncapture_2 = 0x000; /* Invalid */
#ifdef ENABLE_KBC_AT_LOG
int kbc_at_do_log = ENABLE_KBC_AT_LOG;
@@ -484,19 +476,6 @@ keyboard_isfsexit_up(void)
return (!recv_key_ui[0x01d] && !recv_key_ui[0x11d] && !recv_key_ui[0x038] && !recv_key_ui[0x138] && !recv_key_ui[0x051] && !recv_key_ui[0x151]);
}
/* Do we have the mouse uncapture combination in the keyboard buffer? */
int
keyboard_ismsexit(void)
{
if ((key_prefix_2_1 != 0x000) || (key_prefix_2_2 != 0x000))
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
(recv_key_ui[key_prefix_2_1] || recv_key_ui[key_prefix_2_2]) &&
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
else
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
}
/* This is so we can disambiguate scan codes that would otherwise conflict and get
passed on incorrectly. */
uint16_t

View File

@@ -1312,7 +1312,6 @@ const device_t keyboard_xt_t1x00_device = {
.config = NULL
};
#ifdef USE_LASERXT
const device_t keyboard_xt_lxt3_device = {
.name = "VTech Laser Turbo XT Keyboard",
.internal_name = "keyboard_xt_lxt",
@@ -1326,7 +1325,6 @@ const device_t keyboard_xt_lxt3_device = {
.force_redraw = NULL,
.config = NULL
};
#endif /* USE_LASERXT */
const device_t keyboard_xt_olivetti_device = {
.name = "Olivetti XT Keyboard",

View File

@@ -83,23 +83,24 @@ static const device_t mouse_internal_device = {
static mouse_t mouse_devices[] = {
// clang-format off
{ &mouse_none_device },
{ &mouse_internal_device },
{ &mouse_logibus_device },
{ &mouse_msinport_device },
{ &mouse_none_device },
{ &mouse_internal_device },
{ &mouse_logibus_device },
{ &mouse_msinport_device },
#ifdef USE_GENIBUS
{ &mouse_genibus_device },
{ &mouse_genibus_device },
#endif
{ &mouse_mssystems_device },
{ &mouse_msserial_device },
{ &mouse_ltserial_device },
{ &mouse_ps2_device },
{ &mouse_mssystems_device },
{ &mouse_mssystems_bus_device },
{ &mouse_msserial_device },
{ &mouse_ltserial_device },
{ &mouse_ps2_device },
#ifdef USE_WACOM
{ &mouse_wacom_device },
{ &mouse_wacom_artpad_device },
{ &mouse_wacom_device },
{ &mouse_wacom_artpad_device },
#endif
{ &mouse_mtouch_device },
{ NULL }
{ &mouse_mtouch_device },
{ NULL }
// clang-format on
};

View File

@@ -146,7 +146,11 @@ sermouse_transmit_byte(mouse_t *dev, int do_next)
serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]);
if (do_next) {
dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len;
/* If we have a buffer length of 0, pretend the state is STATE_SKIP_PACKET. */
if (dev->buf_len == 0)
dev->buf_pos = 0;
else
dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len;
if (dev->buf_pos != 0)
sermouse_set_period(dev, dev->transmit_period);
@@ -747,7 +751,7 @@ sermouse_timer(void *priv)
if (!dev->prompt && !dev->continuous)
sermouse_transmit_report(dev, (dev->state == STATE_TRANSMIT_REPORT));
else
dev->state = STATE_IDLE;
dev->state = STATE_IDLE;
break;
case STATE_TRANSMIT_REPORT:
case STATE_TRANSMIT:
@@ -829,10 +833,6 @@ sermouse_close(void *priv)
{
mouse_t *dev = (mouse_t *) priv;
/* Detach serial port from the mouse. */
if (dev && dev->serial && dev->serial->sd)
memset(dev->serial->sd, 0, sizeof(serial_device_t));
free(dev);
}
@@ -843,7 +843,15 @@ sermouse_init(const device_t *info)
mouse_t *dev;
void (*rcr_callback)(struct serial_s *serial, void *priv);
void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data);
void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period);
void (*transmit_period_callback)(struct serial_s *serial, void *priv,
double transmit_period);
if (info->local == MOUSE_TYPE_MSYSTEMSB) {
uintptr_t irqbase = ((device_get_config_int("irq") << 16) |
(device_get_config_hex16("addr") << 20)) |
ns16450_device.local;
device_add_params(&ns16450_device, (void*)irqbase);
}
dev = (mouse_t *) calloc(1, sizeof(mouse_t));
dev->name = info->name;
@@ -858,7 +866,7 @@ sermouse_init(const device_t *info)
if (dev->but > 2)
dev->flags |= FLAG_3BTN;
if (info->local == MOUSE_TYPE_MSYSTEMS) {
if (info->local == MOUSE_TYPE_MSYSTEMS || info->local == MOUSE_TYPE_MSYSTEMSB) {
dev->format = 0;
dev->type = info->local;
dev->id_len = 1;
@@ -889,7 +897,7 @@ sermouse_init(const device_t *info)
}
}
dev->port = device_get_config_int("port");
dev->port = (info->local == MOUSE_TYPE_MSYSTEMSB) ? (SERIAL_MAX - 1) : device_get_config_int("port");
/* Attach a serial port to the mouse. */
rcr_callback = dev->rts_toggle ? sermouse_callback : NULL;
@@ -964,6 +972,78 @@ static const device_config_t msssermouse_config[] = {
// clang-format on
};
static const device_config_t mssbusmouse_config[] = {
// clang-format off
{
.name = "addr",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x238,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "0x338", .value = 0x338 },
{ .description = "0x238", .value = 0x238 },
{ .description = "0x3f8", .value = 0x3f8 },
{ .description = "0x2f8", .value = 0x2f8 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 5,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "IRQ 2", .value = 2 },
{ .description = "IRQ 3", .value = 3 },
{ .description = "IRQ 4", .value = 4 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "IRQ 7", .value = 7 },
{ .description = "IRQ 10", .value = 10 },
{ .description = "IRQ 11", .value = 11 },
{ .description = "IRQ 12", .value = 12 },
{ .description = "IRQ 15", .value = 15 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "buttons",
.description = "Buttons",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 2,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Two", .value = 2 },
{ .description = "Three", .value = 3 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "rts_toggle",
.description = "RTS toggle",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
static const device_config_t mssermouse_config[] = {
// clang-format off
{
@@ -1083,6 +1163,20 @@ const device_t mouse_mssystems_device = {
.config = msssermouse_config
};
const device_t mouse_mssystems_bus_device = {
.name = "Mouse Systems Bus Mouse",
.internal_name = "mssystems_bus",
.flags = DEVICE_ISA,
.local = MOUSE_TYPE_MSYSTEMSB,
.init = sermouse_init,
.close = sermouse_close,
.reset = NULL,
.available = NULL,
.speed_changed = sermouse_speed_changed,
.force_redraw = NULL,
.config = mssbusmouse_config
};
const device_t mouse_msserial_device = {
.name = "Microsoft Serial Mouse",
.internal_name = "msserial",

View File

@@ -884,10 +884,10 @@ serial_close(void *priv)
{
serial_t *dev = (serial_t *) priv;
next_inst--;
if (com_ports[dev->inst].enabled)
if (dev->sd) {
memset(dev->sd, 0, sizeof(serial_device_t));
fifo_close(dev->rcvr_fifo);
}
free(dev);
}
@@ -897,7 +897,7 @@ serial_reset(void *priv)
{
serial_t *dev = (serial_t *) priv;
if (com_ports[dev->inst].enabled) {
if (dev->sd) {
timer_disable(&dev->transmit_timer);
timer_disable(&dev->timeout_timer);
timer_disable(&dev->receive_timer);
@@ -930,16 +930,26 @@ static void *
serial_init(const device_t *info)
{
serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t));
int orig_inst = next_inst;
if (info->local & 0xFFF00000)
next_inst = SERIAL_MAX - 1;
dev->inst = next_inst;
if (com_ports[next_inst].enabled) {
if (com_ports[next_inst].enabled || (info->local & 0xFFF00000)) {
serial_log("Adding serial port %i...\n", next_inst);
dev->type = info->local;
memset(&(serial_devices[next_inst]), 0, sizeof(serial_device_t));
dev->sd = &(serial_devices[next_inst]);
dev->sd->serial = dev;
if (next_inst == 6)
if (info->local & 0xfff00000) {
dev->base_address = info->local >> 20;
dev->irq = (info->local >> 16) & 0xF;
io_sethandler(dev->base_address, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, dev);
next_inst = orig_inst;
} else if (next_inst == 6)
serial_setup(dev, COM7_ADDR, COM7_IRQ);
else if (next_inst == 5)
serial_setup(dev, COM6_ADDR, COM6_IRQ);
@@ -984,7 +994,8 @@ serial_init(const device_t *info)
serial_reset_port(dev);
}
next_inst++;
if (!(info->local & 0xfff00000))
next_inst++;
return dev;
}
@@ -998,9 +1009,8 @@ serial_set_next_inst(int ni)
void
serial_standalone_init(void)
{
while (next_inst < SERIAL_MAX)
device_add_inst(!strcmp(machine_get_internal_name(), "if386sx") ? &ns16450_device :
&ns8250_device, next_inst + 1);
while (next_inst < (SERIAL_MAX - 1))
device_add_inst(&ns8250_device, next_inst + 1);
};
const device_t ns8250_device = {

View File

@@ -54,7 +54,7 @@ serial_passthrough_log(const char *fmt, ...)
void
serial_passthrough_init(void)
{
for (uint8_t c = 0; c < SERIAL_MAX; c++) {
for (uint8_t c = 0; c < (SERIAL_MAX - 1); c++) {
if (serial_passthrough_enabled[c]) {
/* Instance n for COM n */
device_add_inst(&serial_passthrough_device, c + 1);

View File

@@ -31,6 +31,7 @@ add_library(hdd OBJECT
hdc_ide_opti611.c
hdc_ide_cmd640.c
hdc_ide_cmd646.c
hdc_ide_rz1000.c
hdc_ide_sff8038i.c
hdc_ide_um8673f.c
hdc_ide_w83769f.c

View File

@@ -395,7 +395,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
fatal("Write with ECC\n");
esdi->status = STAT_READY | STAT_DRQ | STAT_DSC;
esdi->pos = 0;
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 1);
break;
case CMD_VERIFY:
@@ -412,7 +412,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
case CMD_FORMAT:
esdi->status = STAT_DRQ;
esdi->pos = 0;
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 1);
break;
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
@@ -593,6 +593,7 @@ esdi_callback(void *priv)
esdi->reset = 0;
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
return;
}
@@ -650,7 +651,7 @@ read_error:
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
esdi->error = ERR_ABRT;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
} else {
if (get_sector(esdi, &addr)) {
@@ -658,7 +659,7 @@ read_error:
write_error:
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
}
@@ -672,10 +673,10 @@ write_error:
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
esdi->pos = 0;
next_sector(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 1);
} else {
esdi->status = STAT_READY | STAT_DSC;
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
}
break;
@@ -718,7 +719,7 @@ verify_error:
break;
case CMD_FORMAT:
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
if (!drive->present) {
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
esdi->error = ERR_ABRT;
@@ -752,10 +753,12 @@ format_error:
esdi->status = STAT_READY | STAT_DSC;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
if (!drive->present) {
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
esdi->error = ERR_ABRT;
@@ -778,10 +781,12 @@ format_error:
esdi->error = ERR_ABRT;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
case 0xe0:
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
if (!drive->present) {
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
esdi->error = ERR_ABRT;
@@ -825,6 +830,7 @@ format_error:
}
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
case CMD_READ_PARAMETERS:
@@ -869,6 +875,7 @@ format_error:
irq_raise(esdi);
}
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
default:
@@ -880,6 +887,7 @@ format_error:
esdi->error = ERR_ABRT;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
}
}
@@ -954,6 +962,7 @@ wd1007vse1_init(UNUSED(const device_t *info))
timer_add(&esdi->callback_timer, esdi_callback, esdi, 0);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
return esdi;
}
@@ -973,6 +982,7 @@ wd1007vse1_close(void *priv)
free(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
static int

View File

@@ -288,6 +288,7 @@ cmd_unsupported(esdi_t *dev)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
static void
@@ -309,6 +310,7 @@ device_not_present(esdi_t *dev)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
static void
@@ -330,6 +332,7 @@ rba_out_of_range(esdi_t *dev)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
static void
@@ -351,6 +354,7 @@ defective_block(esdi_t *dev)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
static void
@@ -368,6 +372,7 @@ complete_command_status(esdi_t *dev)
dev->status_data[5] = (dev->rba - 1) >> 8;
dev->status_data[6] = 0; /*Number of blocks requiring error recovery*/
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
}
#define ESDI_ADAPTER_ONLY() \
@@ -696,6 +701,7 @@ esdi_callback(void *priv)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
case CMD_GET_DEV_CONFIG:
@@ -744,6 +750,7 @@ esdi_callback(void *priv)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
case CMD_GET_POS_INFO:
@@ -764,6 +771,7 @@ esdi_callback(void *priv)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
case 0x10:
@@ -817,6 +825,7 @@ esdi_callback(void *priv)
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_ESDI, 0);
break;
default:

View File

@@ -1208,7 +1208,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide->tf->atastat = BSY_STAT;
if (ide->tf->pos >= dev->packet_len) {
ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
// ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
ide_log("%i bytes %s, command done, %i sectors left\n", ide->tf->pos, out ? "written" : "read",
dev->sector_len);
ide->tf->pos = dev->request_pos = 0;
@@ -1262,13 +1264,12 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide_atapi_callback(ide);
ide_set_callback(ide, 0.0);
} else {
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if (ide->phase_data_out != NULL)
(void) ide->phase_data_out(dev);
ide_atapi_callback(ide);
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
(ide->sc->callback == 0.0))
ide_atapi_callback(ide);
}
}
} else {
@@ -1280,10 +1281,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
if (ide->command_stop != NULL)
ide->command_stop(dev);
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
ide_atapi_callback(ide);
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
(ide->sc->callback == 0.0))
ide_atapi_callback(ide);
}
} else if (ide->read != NULL)
ide->read(dev);
@@ -1299,8 +1299,8 @@ ide_atapi_packet_read(ide_t *ide)
uint16_t ret = 0;
if (dev && dev->temp_buffer && (dev->packet_status == PHASE_DATA_IN)) {
ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n",
dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len);
/* ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n",
dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len); */
bufferw = (uint16_t *) dev->temp_buffer;
@@ -1722,7 +1722,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
break;
case 0x7: /* Command register */
if (ide->tf->atastat & (BSY_STAT | DRQ_STAT))
if ((ide->tf->atastat & (BSY_STAT | DRQ_STAT)) &&
((val != WIN_SRST) || (ide->type != IDE_ATAPI)))
break;
if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS)))
@@ -1826,7 +1827,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide->blockcount = 0;
/* Turn on the activity indicator *here* so that it gets turned on
less times. */
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
ui_sb_update_icon_write(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
fallthrough;
case WIN_WRITE:
@@ -2158,7 +2159,8 @@ ide_read_alt_status(UNUSED(const uint16_t addr), void *priv)
if (!(addr & 0x0001))
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
// ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
// ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
return ret;
}
@@ -2470,6 +2472,7 @@ ide_callback(void *priv)
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
ui_sb_update_icon_write(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
ide_irq_raise(ide);
ide->tf->secount--;
@@ -2477,10 +2480,8 @@ ide_callback(void *priv)
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
ide->tf->pos = 0;
ide_next_sector(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
} else {
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
}
if (ret < 0)
err = UNC_ERR;
@@ -2512,6 +2513,7 @@ ide_callback(void *priv)
return;
} else if (ret & 1) {
/* DMA successful */
ui_sb_update_icon_write(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide),
ide->sector_pos, ide->sector_buffer);
@@ -2522,7 +2524,6 @@ ide_callback(void *priv)
err = UNC_ERR;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
} else {
/* Bus master DMA error, abort the command. */
ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel);
@@ -2560,7 +2561,7 @@ ide_callback(void *priv)
ide_next_sector(ide);
} else {
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
ui_sb_update_icon_write(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
}
if (ret < 0)
err = UNC_ERR;
@@ -2594,7 +2595,7 @@ ide_callback(void *priv)
err = UNC_ERR;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
ui_sb_update_icon_write(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
}
break;
@@ -3159,6 +3160,13 @@ ide_init(const device_t *info)
ide_board_init(1, HDC_SECONDARY_IRQ, HDC_SECONDARY_BASE, HDC_SECONDARY_SIDE, info->local, info->flags);
break;
case 8 ... 0x0d:
ide_board_init(2, -1, 0, 0, info->local, info->flags);
if (info->local & 1)
ide_board_init(3, -1, 0, 0, info->local, info->flags);
break;
default:
break;
}
@@ -3540,7 +3548,7 @@ const device_t mcide_device = {
.name = "MCA McIDE Controller",
.internal_name = "ide_mcide",
.flags = DEVICE_MCA,
.local = 3,
.local = 1,
.init = mcide_init,
.close = mcide_close,
.reset = mcide_reset,
@@ -3661,3 +3669,17 @@ const device_t ide_qua_pnp_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t ide_pci_ter_qua_2ch_device = {
.name = "PCI IDE Controller (Dual-Channel Tertiary/Quaternary)",
.internal_name = "ide_pci_ter_qua_2ch",
.flags = DEVICE_PCI,
.local = 0x0d,
.init = ide_init,
.close = ide_close,
.reset = ide_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

322
src/disk/hdc_ide_rz1000.c Normal file
View File

@@ -0,0 +1,322 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the PC Technology RZ-1000 controller.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2025 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/cdrom.h>
#include <86box/scsi_device.h>
#include <86box/scsi_cdrom.h>
#include <86box/dma.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
#include <86box/zip.h>
#include <86box/mo.h>
typedef struct rz1000_t {
uint8_t vlb_idx;
uint8_t id;
uint8_t in_cfg;
uint8_t channels;
uint8_t pci;
uint8_t irq_state;
uint8_t pci_slot;
uint8_t pad0;
uint8_t regs[256];
uint32_t local;
int irq_mode[2];
int irq_pin;
int irq_line;
} rz1000_t;
static int next_id = 0;
#define ENABLE_RZ1000_LOG 1
#ifdef ENABLE_RZ1000_LOG
int rz1000_do_log = ENABLE_RZ1000_LOG;
static void
rz1000_log(const char *fmt, ...)
{
va_list ap;
if (rz1000_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define rz1000_log(fmt, ...)
#endif
static void
rz1000_ide_handlers(rz1000_t *dev)
{
uint16_t main;
uint16_t side;
if (dev->channels & 0x01) {
ide_pri_disable();
main = 0x1f0;
side = 0x3f6;
ide_set_base(0, main);
ide_set_side(0, side);
if (dev->regs[0x04] & 0x01)
ide_pri_enable();
}
if (dev->channels & 0x02) {
ide_sec_disable();
main = 0x170;
side = 0x376;
ide_set_base(1, main);
ide_set_side(1, side);
if (dev->regs[0x04] & 0x01)
ide_sec_enable();
}
}
static void
rz1000_pci_write(int func, int addr, uint8_t val, void *priv)
{
rz1000_t *dev = (rz1000_t *) priv;
rz1000_log("rz1000_pci_write(%i, %02X, %02X)\n", func, addr, val);
if (func == 0x00)
switch (addr) {
case 0x04:
dev->regs[addr] = (val & 0x41);
rz1000_ide_handlers(dev);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0x80);
break;
case 0x09:
if ((dev->regs[addr] & 0x0a) == 0x0a) {
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
dev->irq_mode[0] = !!(val & 0x01);
dev->irq_mode[1] = !!(val & 0x04);
rz1000_ide_handlers(dev);
}
break;
case 0x10:
dev->regs[0x10] = (val & 0xf8) | 1;
rz1000_ide_handlers(dev);
break;
case 0x11:
dev->regs[0x11] = val;
rz1000_ide_handlers(dev);
break;
case 0x14:
dev->regs[0x14] = (val & 0xfc) | 1;
rz1000_ide_handlers(dev);
break;
case 0x15:
dev->regs[0x15] = val;
rz1000_ide_handlers(dev);
break;
case 0x18:
dev->regs[0x18] = (val & 0xf8) | 1;
rz1000_ide_handlers(dev);
break;
case 0x19:
dev->regs[0x19] = val;
rz1000_ide_handlers(dev);
break;
case 0x1c:
dev->regs[0x1c] = (val & 0xfc) | 1;
rz1000_ide_handlers(dev);
break;
case 0x1d:
dev->regs[0x1d] = val;
rz1000_ide_handlers(dev);
break;
case 0x40 ... 0x4f:
dev->regs[addr] = val;
break;
}
}
static uint8_t
rz1000_pci_read(int func, int addr, void *priv)
{
rz1000_t *dev = (rz1000_t *) priv;
uint8_t ret = 0xff;
if (func == 0x00)
ret = dev->regs[addr];
rz1000_log("rz1000_pci_read(%i, %02X, %02X)\n", func, addr, ret);
return ret;
}
static void
rz1000_reset(void *priv)
{
rz1000_t *dev = (rz1000_t *) priv;
int i = 0;
int min_channel;
int max_channel;
switch (dev->channels) {
default:
case 0x00:
min_channel = max_channel = 0;
break;
case 0x01:
min_channel = 0;
max_channel = 1;
break;
case 0x02:
min_channel = 2;
max_channel = 3;
break;
case 0x03:
min_channel = 0;
max_channel = 3;
break;
}
for (i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) &&
(cdrom[i].ide_channel <= max_channel) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
}
for (i = 0; i < ZIP_NUM; i++) {
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) &&
(zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
}
for (i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) &&
(mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}
memset(dev->regs, 0x00, sizeof(dev->regs));
rz1000_log("dev->local = %08X\n", dev->local);
dev->regs[0x00] = 0x42; /* PC Technology */
dev->regs[0x01] = 0x10;
dev->regs[0x02] = 0x00; /* RZ-1000 */
dev->regs[0x03] = 0x10;
dev->regs[0x04] = 0x01;
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
dev->regs[0x08] = 0x02; /* Revision 02 */
dev->regs[0x09] = dev->local; /* Programming interface */
dev->regs[0x0a] = 0x01; /* IDE controller */
dev->regs[0x0b] = 0x01; /* Mass storage controller */
dev->regs[0x3c] = 0x14; /* IRQ 14 */
dev->regs[0x3d] = 0x01; /* INTA */
dev->irq_mode[0] = dev->irq_mode[1] = 0;
dev->irq_pin = PCI_INTA;
dev->irq_line = 14;
rz1000_ide_handlers(dev);
}
static void
rz1000_close(void *priv)
{
rz1000_t *dev = (rz1000_t *) priv;
free(dev);
next_id = 0;
}
static void *
rz1000_init(const device_t *info)
{
rz1000_t *dev = (rz1000_t *) calloc(1, sizeof(rz1000_t));
dev->id = next_id | 0x60;
dev->pci = !!(info->flags & DEVICE_PCI);
dev->local = info->local;
dev->channels = ((info->local & 0x60000) >> 17) & 0x03;
device_add(&ide_pci_2ch_device);
if (info->local & 0x80000)
pci_add_card(PCI_ADD_NORMAL, rz1000_pci_read, rz1000_pci_write, dev, &dev->pci_slot);
else
pci_add_card(PCI_ADD_IDE, rz1000_pci_read, rz1000_pci_write, dev, &dev->pci_slot);
if (dev->channels & 0x01)
ide_board_set_force_ata3(0, 1);
if (dev->channels & 0x02)
ide_board_set_force_ata3(1, 1);
next_id++;
rz1000_reset(dev);
return dev;
}
const device_t ide_rz1000_pci_device = {
.name = "PC Technology RZ-1000 PCI",
.internal_name = "ide_rz1000_pci",
.flags = DEVICE_PCI,
.local = 0x6000a,
.init = rz1000_init,
.close = rz1000_close,
.reset = rz1000_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t ide_rz1000_pci_single_channel_device = {
.name = "PC Technology RZ-1000 PCI",
.internal_name = "ide_rz1000_pci_single_channel",
.flags = DEVICE_PCI,
.local = 0x2000a,
.init = rz1000_init,
.close = rz1000_close,
.reset = rz1000_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -557,6 +557,7 @@ do_callback(void *priv)
mfm->reset = 0;
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
return;
}
@@ -627,9 +628,9 @@ write_error:
mfm->status |= STAT_DRQ;
mfm->pos = 0;
next_sector(mfm);
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 1);
} else
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
break;
case CMD_VERIFY:
@@ -657,7 +658,7 @@ write_error:
mfm->status = STAT_READY | STAT_DSC;
irq_raise(mfm);
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 1);
break;
case CMD_DIAGNOSE:
@@ -772,6 +773,7 @@ mfm_init(UNUSED(const device_t *info))
timer_add(&mfm->callback_timer, do_callback, mfm, 0);
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
return mfm;
}
@@ -790,6 +792,7 @@ mfm_close(void *priv)
free(mfm);
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
}
const device_t st506_at_wd1003_device = {

View File

@@ -580,14 +580,14 @@ st506_callback(void *priv)
(void) get_chs(dev, drive);
st506_xt_log("ST506: FORMAT_DRIVE(%i) interleave=%i\n",
dev->drive_sel, dev->command[4]);
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 1);
timer_advance_u64(&dev->timer, ST506_TIME);
dev->state = STATE_SEND_DATA;
break;
case STATE_SEND_DATA: /* wrong, but works */
if (!get_sector(dev, drive, &addr)) {
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
st506_error(dev, dev->error);
st506_complete(dev);
return;
@@ -604,7 +604,7 @@ st506_callback(void *priv)
break;
case STATE_SENT_DATA:
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
st506_complete(dev);
break;
@@ -663,14 +663,14 @@ st506_callback(void *priv)
st506_xt_log("ST506: FORMAT_%sTRACK(%i, %i/%i)\n",
(dev->command[0] == CMD_FORMAT_BAD_TRACK) ? "BAD_" : "",
dev->drive_sel, dev->cylinder, dev->head);
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 1);
timer_advance_u64(&dev->timer, ST506_TIME);
dev->state = STATE_SEND_DATA;
break;
case STATE_SEND_DATA: /* wrong, but works */
if (!get_sector(dev, drive, &addr)) {
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
st506_error(dev, dev->error);
st506_complete(dev);
return;
@@ -686,7 +686,7 @@ st506_callback(void *priv)
break;
case STATE_SENT_DATA:
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
st506_complete(dev);
break;
@@ -828,7 +828,7 @@ read_error_sent:
return;
}
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 1);
/* Set up the data transfer. */
dev->buff_pos = 0;
@@ -865,7 +865,7 @@ read_error_sent:
case STATE_RECEIVED_DATA:
if (!get_sector(dev, drive, &addr)) {
write_error:
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
st506_error(dev, dev->error);
st506_complete(dev);
return;
@@ -879,7 +879,7 @@ write_error:
}
if (--dev->count == 0) {
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_MFM, 0);
st506_complete(dev);
break;
}

View File

@@ -385,7 +385,7 @@ do_format(hdc_t *dev, drive_t *drive, dcb_t *dcb)
dev->sector = 0;
/* Activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_XTA, 1);
do_fmt:
/*
@@ -426,7 +426,7 @@ do_fmt:
}
/* De-activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_XTA, 0);
}
/* Execute the DCB we just received. */
@@ -631,7 +631,7 @@ read_error:
case STATE_RECV:
/* Activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_XTA, 1);
do_recv:
/* Ready to transfer the data in. */
dev->state = STATE_RDATA;
@@ -680,7 +680,7 @@ do_recv:
if (get_sector(dev, drive, &addr)) {
write_error:
/* De-activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_XTA, 0);
dev->comp |= COMP_ERR;
set_intr(dev);
@@ -697,7 +697,7 @@ write_error:
dev->buf_idx = 0;
if (--dev->count == 0) {
/* De-activate the status icon. */
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
ui_sb_update_icon_write(SB_HDD | HDD_BUS_XTA, 0);
set_intr(dev);
return;

View File

@@ -407,14 +407,14 @@ hdd_zones_init(hard_disk_t *hdd)
static hdd_preset_t hdd_speed_presets[] = {
// clang-format off
{ .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .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 },
{ .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .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 },
{ .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .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 },
{ .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .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 },
{ .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .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 },
{ .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .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 },
{ .name = "[Generic] RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[Generic] 1989 (3500 RPM)", .internal_name = "1989_3500rpm", .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 },
{ .name = "[Generic] 1992 (3600 RPM)", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[Generic] 1994 (4500 RPM)", .internal_name = "1994_4500rpm", .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 },
{ .name = "[Generic] 1996 (5400 RPM)", .internal_name = "1996_5400rpm", .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 },
{ .name = "[Generic] 1997 (5400 RPM)", .internal_name = "1997_5400rpm", .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 },
{ .name = "[Generic] 1998 (5400 RPM)", .internal_name = "1998_5400rpm", .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 },
{ .name = "[Generic] 2000 (7200 RPM)", .internal_name = "2000_7200rpm", .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 },
{ .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "WDA-L42", .zones = 1, .avg_spt = 85, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 2.5, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 },
{ .name = "[ATA-1] Conner CP3024", .internal_name = "CP3024", .model = "Conner Peripherals 20MB - CP3024", .zones = 1, .avg_spt = 33, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
{ .name = "[ATA-1] Conner CP3044", .internal_name = "CP3044", .model = "Conner Peripherals 40MB - CP3044", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
@@ -469,7 +469,7 @@ static hdd_preset_t hdd_speed_presets[] = {
{ .name = "[ATA-2] Western Digital Caviar 22000", .internal_name = "AC22000", .model = "WDC AC22000LA", .zones = 8, .avg_spt = 130, .heads = 3, .rpm = 5200, .full_stroke_ms = 33, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 22100", .internal_name = "AC22100", .model = "WDC AC22100H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Western Digital Caviar 31200", .internal_name = "AC31200", .model = "WDC AC31200F", .zones = 8, .avg_spt = 210, .heads = 4, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[ATA-3] Connor CFS1275A", .internal_name = "CFS1275A", .model = "Connor Peripherals 1275MB - CFS1275A", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.8, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, // Either ATA-2 or ATA-3
{ .name = "[ATA-3] Conner CFS1275A", .internal_name = "CFS1275A", .model = "Conner Peripherals 1275MB - CFS1275A", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.8, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, // Either ATA-2 or ATA-3
{ .name = "[ATA-3] Fujitsu MPA3017AT", .internal_name = "MPA3017AT", .model = "FUJITSU MPA3017AT", .zones = 5, .avg_spt = 195, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3026AT", .internal_name = "MPA3026AT", .model = "FUJITSU MPA3026AT", .zones = 8, .avg_spt = 195, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3035AT", .internal_name = "MPA3035AT", .model = "FUJITSU MPA3035AT", .zones = 11, .avg_spt = 195, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },

View File

@@ -584,7 +584,10 @@ mo_data_command_finish(mo_t *dev, int len, const int block_len,
mo_command_write_dma(dev);
} else {
mo_update_request_length(dev, len, block_len);
if (direction == 0)
if ((dev->drv->bus_type != MO_BUS_SCSI) &&
(dev->tf->request_length == 0))
mo_command_complete(dev);
else if (direction == 0)
mo_command_read(dev);
else
mo_command_write(dev);
@@ -625,6 +628,7 @@ mo_cmd_error(mo_t *dev)
dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev);
ui_sb_update_icon(SB_MO | dev->id, 0);
ui_sb_update_icon_write(SB_MO | dev->id, 0);
mo_log(dev->log, "[%02X] ERROR: %02X/%02X/%02X\n", dev->current_cdb[0], mo_sense_key,
mo_asc, mo_ascq);
}
@@ -641,6 +645,7 @@ mo_unit_attention(mo_t *dev)
dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev);
ui_sb_update_icon(SB_MO | dev->id, 0);
ui_sb_update_icon_write(SB_MO | dev->id, 0);
mo_log(dev->log, "UNIT ATTENTION\n");
}
@@ -1459,7 +1464,7 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
mo_data_command_finish(dev, dev->packet_len, dev->drv->sector_size,
dev->packet_len, 1);
ui_sb_update_icon(SB_MO | dev->id,
ui_sb_update_icon_write(SB_MO | dev->id,
dev->packet_status != PHASE_COMPLETE);
} else {
mo_set_phase(dev, SCSI_PHASE_STATUS);
@@ -1498,7 +1503,7 @@ mo_command(scsi_common_t *sc, const uint8_t *cdb)
dev->drv->sector_size,
alloc_length, 1);
ui_sb_update_icon(SB_MO | dev->id,
ui_sb_update_icon_write(SB_MO | dev->id,
dev->packet_status != PHASE_COMPLETE);
} else {
mo_set_phase(dev, SCSI_PHASE_STATUS);

View File

@@ -665,7 +665,10 @@ zip_data_command_finish(zip_t *dev, int len, const int block_len,
zip_command_write_dma(dev);
} else {
zip_update_request_length(dev, len, block_len);
if (direction == 0)
if ((dev->drv->bus_type != ZIP_BUS_SCSI) &&
(dev->tf->request_length == 0))
zip_command_complete(dev);
else if (direction == 0)
zip_command_read(dev);
else
zip_command_write(dev);
@@ -706,6 +709,7 @@ zip_cmd_error(zip_t *dev)
dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev);
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon_write(SB_ZIP | dev->id, 0);
zip_log(dev->log, "[%02X] ERROR: %02X/%02X/%02X\n", dev->current_cdb[0], zip_sense_key,
zip_asc, zip_ascq);
}
@@ -722,6 +726,7 @@ zip_unit_attention(zip_t *dev)
dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev);
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon_write(SB_ZIP | dev->id, 0);
zip_log(dev->log, "UNIT ATTENTION\n", dev->id);
}
@@ -1482,7 +1487,7 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb)
zip_data_command_finish(dev, dev->packet_len, 512,
dev->packet_len, 1);
ui_sb_update_icon(SB_ZIP | dev->id,
ui_sb_update_icon_write(SB_ZIP | dev->id,
dev->packet_status != PHASE_COMPLETE);
} else {
zip_set_phase(dev, SCSI_PHASE_STATUS);
@@ -1523,7 +1528,7 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb)
zip_data_command_finish(dev, 512, 512,
alloc_length, 1);
ui_sb_update_icon(SB_ZIP | dev->id,
ui_sb_update_icon_write(SB_ZIP | dev->id,
dev->packet_status != PHASE_COMPLETE);
} else {
zip_set_phase(dev, SCSI_PHASE_STATUS);

View File

@@ -79,6 +79,9 @@ int floppyrate[4];
int fdc_current[FDC_MAX] = { 0, 0 };
volatile int fdcinited = 0;
// #define ENABLE_FDC_LOG 1
#ifdef ENABLE_FDC_LOG
int fdc_do_log = ENABLE_FDC_LOG;
@@ -393,6 +396,20 @@ fdc_update_rwc(fdc_t *fdc, int drive, int rwc)
fdc_rate(fdc, drive);
}
uint8_t
fdc_get_media_id(fdc_t *fdc, int id)
{
uint8_t ret = fdc->media_id & (1 << id);
return ret;
}
void
fdc_set_media_id(fdc_t *fdc, int id, int set)
{
fdc->media_id = (fdc->media_id & ~(1 << id)) | (set << id);
}
int
fdc_get_boot_drive(fdc_t *fdc)
{
@@ -613,7 +630,10 @@ fdc_io_command_phase1(fdc_t *fdc, int out)
}
}
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
if (fdc->processed_cmd == 0x05 || fdc->processed_cmd == 0x09)
ui_sb_update_icon_write(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
else
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
fdc->stat = out ? 0x10 : 0x50;
if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) {
fdc->stat |= 0x20;
@@ -669,8 +689,10 @@ fdc_soft_reset(fdc_t *fdc)
fdc->perp &= 0xfc;
for (int i = 0; i < FDD_NUM; i++)
ui_sb_update_icon(SB_FLOPPY | i, 0);
for (int i = 0; i < FDD_NUM; i++) {
ui_sb_update_icon(SB_FLOPPY | i, 0);
ui_sb_update_icon_write(SB_FLOPPY | i, 0);
}
fdc_ctrl_reset(fdc);
}
@@ -704,6 +726,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC);
fdc->interrupt = -1;
ui_sb_update_icon(SB_FLOPPY | 0, 0);
ui_sb_update_icon_write(SB_FLOPPY | 0, 0);
fdc_ctrl_reset(fdc);
}
if (!fdd_get_flags(0))
@@ -1361,7 +1384,7 @@ fdc_read(uint16_t addr, void *priv)
} else if (!fdc->enh_mode)
ret = 0x20;
else
ret = fdc->rwc[drive] << 4;
ret = (fdc->rwc[drive] << 4) | (fdc->media_id << 6);
break;
case 4: /*Status*/
ret = fdc->stat;
@@ -1500,6 +1523,7 @@ fdc_poll_common_finish(fdc_t *fdc, int compare, int st5)
fdc->res[10] = fdc->params[4];
fdc_log("Read/write finish (%02X %02X %02X %02X %02X %02X %02X)\n", fdc->res[4], fdc->res[5], fdc->res[6], fdc->res[7], fdc->res[8], fdc->res[9], fdc->res[10]);
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 0);
ui_sb_update_icon_write(SB_FLOPPY | real_drive(fdc, fdc->drive), 0);
fdc->paramstogo = 7;
dma_set_drq(fdc->dma_ch, 0);
}
@@ -1543,8 +1567,10 @@ fdc_callback(void *priv)
case -5: /*Reset in power down mode */
fdc->perp &= 0xfc;
for (uint8_t i = 0; i < FDD_NUM; i++)
for (uint8_t i = 0; i < FDD_NUM; i++) {
ui_sb_update_icon(SB_FLOPPY | i, 0);
ui_sb_update_icon_write(SB_FLOPPY | i, 0);
}
fdc_ctrl_reset(fdc);
@@ -1692,7 +1718,10 @@ fdc_callback(void *priv)
fdc->sector++;
else if (fdc->params[5] == 0)
fdc->sector++;
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
if (fdc->interrupt == 0x05 || fdc->interrupt == 0x09)
ui_sb_update_icon_write(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
else
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1);
switch (fdc->interrupt) {
case 5:
case 9:
@@ -1883,6 +1912,7 @@ fdc_error(fdc_t *fdc, int st5, int st6)
break;
}
ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 0);
ui_sb_update_icon_write(SB_FLOPPY | real_drive(fdc, fdc->drive), 0);
fdc->paramstogo = 7;
}
@@ -2268,10 +2298,21 @@ fdc_reset(void *priv)
fdc_update_rwc(fdc, 1, default_rwc);
fdc_update_rwc(fdc, 2, default_rwc);
fdc_update_rwc(fdc, 3, default_rwc);
fdc_update_drvrate(fdc, 0, 0);
fdc_update_drvrate(fdc, 1, 0);
fdc_update_drvrate(fdc, 2, 0);
fdc_update_drvrate(fdc, 3, 0);
/*
The OKI IF386SX natively supports the Japanese 1.25 MB floppy format,
since it can read such images just fine, it also attempts to use data
rate 01 on a 3.5" MB drive (which is the only kind it can physically
take, anyway), and rate 01 on a 3.5" MB drive is usually used by 3-mode
drives to switch to 360 RPM. Hence why I'm switching DRVDEN to 1, so
rate 01 becomes 500 kbps, so on a 3-mode 3.5" drive, 1.25 MB floppies
can be read. The side effect is that to read 5.25" 360k drives, you
need to use a dual-RPM 5.25" drive - but hey, that finally gets those
drives some usage as well.
*/
fdc_update_drvrate(fdc, 0, !strcmp(machine_get_internal_name(), "if386sx"));
fdc_update_drvrate(fdc, 1, !strcmp(machine_get_internal_name(), "if386sx"));
fdc_update_drvrate(fdc, 2, !strcmp(machine_get_internal_name(), "if386sx"));
fdc_update_drvrate(fdc, 3, !strcmp(machine_get_internal_name(), "if386sx"));
fdc_update_drv2en(fdc, 1);
fdc_update_rates(fdc);
@@ -2320,10 +2361,14 @@ fdc_reset(void *priv)
current_drive = 0;
for (uint8_t i = 0; i < FDD_NUM; i++)
for (uint8_t i = 0; i < FDD_NUM; i++) {
ui_sb_update_icon(SB_FLOPPY | i, 0);
ui_sb_update_icon_write(SB_FLOPPY | i, 0);
}
fdc->power_down = 0;
fdc->media_id = 0;
}
static void
@@ -2337,6 +2382,8 @@ fdc_close(void *priv)
fifo_close(fdc->fifo_p);
fdcinited = 0;
free(fdc);
}
@@ -2382,6 +2429,8 @@ fdc_init(const device_t *info)
fdc_reset(fdc);
fdcinited = 1;
return fdc;
}

View File

@@ -3452,6 +3452,7 @@ d86f_common_handlers(int drive)
drives[drive].poll = d86f_poll;
drives[drive].format = d86f_proxy_format;
drives[drive].stop = d86f_stop;
drives[drive].hole = d86f_hole;
}
int

View File

@@ -62,13 +62,18 @@ joystick_standard_read(UNUSED(void *priv))
{
uint8_t ret = 0xf0;
for (int js = 0; js < 2; js++) {
if (JOYSTICK_PRESENT(0, js)) {
if (joystick_state[0][js].button[0])
ret &= ~0x10;
if (joystick_state[0][js].button[1])
ret &= ~0x20;
}
if (JOYSTICK_PRESENT(0, 0)) {
if (joystick_state[0][0].button[0])
ret &= ~0x10;
if (joystick_state[0][0].button[1])
ret &= ~0x20;
}
if (JOYSTICK_PRESENT(0, 1)) {
if (joystick_state[0][1].button[0])
ret &= ~0x40;
if (joystick_state[0][1].button[1])
ret &= ~0x80;
}
return ret;

View File

@@ -27,7 +27,7 @@
/* Configuration values. */
#define GFXCARD_MAX 2
#define SERIAL_MAX 7
#define SERIAL_MAX 8
#define PARALLEL_MAX 4
#define SCREEN_RES_X 640
#define SCREEN_RES_Y 480
@@ -44,8 +44,8 @@
/* Max UUID Length */
#define MAX_UUID_LEN 64
/* Default language 0xFFFF = from system, 0x409 = en-US */
#define DEFAULT_LANGUAGE 0x0409
/* Default language code */
#define DEFAULT_LANGUAGE "system"
#define POSTCARDS_NUM 4
#define POSTCARD_MASK (POSTCARDS_NUM - 1)
@@ -84,8 +84,6 @@ extern "C" {
#endif
/* Global variables. */
extern uint32_t lang_sys; /* (-) system language code */
extern int dump_on_exit; /* (O) dump regs on exit*/
extern int start_in_fullscreen; /* (O) start in fullscreen */
#ifdef _WIN32
@@ -117,7 +115,7 @@ extern int window_remember;
extern int vid_resize; /* (C) allow resizing */
extern int invert_display; /* (C) invert the display */
extern int suppress_overscan; /* (C) suppress overscans */
extern uint32_t lang_id; /* (C) language code identifier */
extern int lang_id; /* (C) language id */
extern int scale; /* (C) screen scale factor */
extern int dpi_scale; /* (C) DPI scaling of the emulated screen */
extern int vid_api; /* (C) video renderer */
@@ -174,14 +172,6 @@ extern int pit_mode; /* (C) force setting PIT mode */
extern int fm_driver; /* (C) select FM sound driver */
extern int hook_enabled; /* (C) Keyboard hook is enabled */
/* Keyboard variables for future key combination redefinition. */
extern uint16_t key_prefix_1_1;
extern uint16_t key_prefix_1_2;
extern uint16_t key_prefix_2_1;
extern uint16_t key_prefix_2_2;
extern uint16_t key_uncapture_1;
extern uint16_t key_uncapture_2;
extern char exe_path[2048]; /* path (dir) of executable */
extern char usr_path[1024]; /* path (dir) of user data */
extern char cfg_path[1024]; /* full path of config file */
@@ -246,6 +236,17 @@ extern int framecountx;
extern volatile int cpu_thread_run;
extern uint8_t postcard_codes[POSTCARDS_NUM];
// Accelerator key structure, defines, helper functions
struct accelKey {
char name[64];
char desc[64];
char seq[64];
};
#define NUM_ACCELS 8
extern struct accelKey acc_keys[NUM_ACCELS];
extern struct accelKey def_acc_keys[NUM_ACCELS];
extern int FindAccelerator(const char *name);
#ifdef __cplusplus
}
#endif

View File

@@ -425,6 +425,8 @@ extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint
#endif
extern uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, uint8_t *b,
const uint8_t track, const int type);
extern int cdrom_is_track_audio(cdrom_t *dev, const int sector, const int ismsf,
int cdrom_sector_type, const uint8_t vendor_type);
extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int ismsf,
int cdrom_sector_type, const int cdrom_sector_flags,
int *len, const uint8_t vendor_type);

View File

@@ -119,6 +119,8 @@ typedef struct fdc_t {
uint8_t lock;
uint8_t dsr;
uint8_t media_id;
uint8_t params[15];
uint8_t specify[2];
uint8_t res[11];
@@ -166,6 +168,9 @@ extern void fdc_3f1_enable(fdc_t *fdc, int enable);
extern int fdc_get_bit_rate(fdc_t *fdc);
extern int fdc_get_bitcell_period(fdc_t *fdc);
extern uint8_t fdc_get_media_id(fdc_t *fdc, int id);
extern void fdc_set_media_id(fdc_t *fdc, int id, int set);
/* A few functions to communicate between Super I/O chips and the FDC. */
extern void fdc_update_enh_mode(fdc_t *fdc, int enh_mode);
extern int fdc_get_rwc(fdc_t *fdc, int drive);

View File

@@ -60,6 +60,8 @@ extern const device_t ide_pci_device; /* pci_ide */
extern const device_t ide_pci_sec_device; /* pci_ide sec */
extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */
extern const device_t ide_pci_ter_qua_2ch_device; /* pci_ide_ter_qua_2ch */
extern const device_t ide_ali1489_device; /* ALi M1489 */
extern const device_t ide_ali5213_device; /* ALi M5213 */
@@ -76,10 +78,14 @@ extern const device_t ide_cmd640_pci_single_channel_sec_device; /* CMD PCI-640B
extern const device_t ide_cmd646_device; /* CMD PCI-646 */
extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */
extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */
extern const device_t ide_cmd646_ter_qua_device; /* CMD PCI-646 (Tertiary and quaternary channels) */
extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */
extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */
extern const device_t ide_rz1000_pci_device; /* PC Technology RZ-1000 PCI */
extern const device_t ide_rz1000_pci_single_channel_device; /* PC Technology RZ-1000 PCI (Only primary channel) */
extern const device_t ide_um8673f_device; /* UMC UM8673F */
extern const device_t ide_um8886af_device; /* UMC UM8886AF */

View File

@@ -224,9 +224,7 @@ extern const device_t keyboard_xt86_device;
extern const device_t keyboard_xt_compaq_device;
extern const device_t keyboard_xt_t1x00_device;
extern const device_t keyboard_tandy_device;
# ifdef USE_LASERXT
extern const device_t keyboard_xt_lxt3_device;
# endif /* USE_LASERXT */
extern const device_t keyboard_xt_olivetti_device;
extern const device_t keyboard_xt_zenith_device;
extern const device_t keyboard_xt_hyundai_device;
@@ -245,6 +243,7 @@ extern const device_t keyboard_ps2_ps1_device;
extern const device_t keyboard_ps2_ps1_pci_device;
extern const device_t keyboard_ps2_xi8088_device;
extern const device_t keyboard_ps2_ami_device;
extern const device_t keyboard_ps2_compaq_device;
extern const device_t keyboard_ps2_holtek_device;
extern const device_t keyboard_ps2_mca_1_device;
extern const device_t keyboard_ps2_mca_2_device;
@@ -258,6 +257,7 @@ extern const device_t keyboard_ps2_ami_pci_device;
extern const device_t keyboard_ps2_intel_ami_pci_device;
extern const device_t keyboard_ps2_acer_pci_device;
extern const device_t keyboard_ps2_ali_pci_device;
extern const device_t keyboard_ps2_phoenix_pci_device;
extern const device_t keyboard_ps2_tg_ami_pci_device;
extern const device_t keyboard_at_generic_device;
@@ -281,9 +281,10 @@ extern int keyboard_isfsenter(void);
extern int keyboard_isfsenter_up(void);
extern int keyboard_isfsexit(void);
extern int keyboard_isfsexit_up(void);
extern int keyboard_ismsexit(void);
extern void keyboard_set_is_amstrad(int ams);
extern void kbc_at_set_ps2(void *priv, uint8_t ps2);
extern uint8_t kbc_at_read_p(void *priv, uint8_t port, uint8_t mask);
extern void kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t val);
extern void kbc_at_set_fast_reset(uint8_t new_fast_reset);
extern void kbc_at_handler(int set, void *priv);

View File

@@ -441,6 +441,8 @@ extern int machine_at_ibmatquadtel_init(const machine_t *); // IBM AT with Quadt
extern int machine_at_ibmxt286_init(const machine_t *);
extern int machine_at_pb286_init(const machine_t *);
extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places
extern int machine_at_wellamerastar_init(const machine_t *); // Wells American A*Star with custom award BIOS
@@ -569,6 +571,7 @@ extern int machine_at_r418_init(const machine_t *);
extern int machine_at_ls486e_init(const machine_t *);
extern int machine_at_4dps_init(const machine_t *);
extern int machine_at_ms4144_init(const machine_t *);
extern int machine_at_acerp3_init(const machine_t *);
extern int machine_at_4saw2_init(const machine_t *);
extern int machine_at_m4li_init(const machine_t *);
extern int machine_at_alfredo_init(const machine_t *);
@@ -779,6 +782,7 @@ extern int machine_at_ax59pro_init(const machine_t *);
extern int machine_at_mvp3_init(const machine_t *);
extern int machine_at_ficva503a_init(const machine_t *);
extern int machine_at_5emapro_init(const machine_t *);
extern int machine_at_delhi3_init(const machine_t *);
extern int machine_at_5sg100_init(const machine_t *);
@@ -803,6 +807,7 @@ extern int machine_at_p65up5_cp6nd_init(const machine_t *);
/* m_at_slot1.c */
extern int machine_at_m729_init(const machine_t *);
extern int machine_at_acerv62x_init(const machine_t *);
extern int machine_at_p65up5_cpknd_init(const machine_t *);
extern int machine_at_kn97_init(const machine_t *);
@@ -966,10 +971,14 @@ extern int machine_xt_compaq_deskpro_init(const machine_t *);
extern int machine_xt_compaq_portable_init(const machine_t *);
/* m_xt_laserxt.c */
#ifdef USE_LASERXT
extern int machine_xt_laserxt_init(const machine_t *);
#ifdef EMU_DEVICE_H
extern const device_t laserxt_device;
#endif
extern int machine_xt_lxt3_init(const machine_t *);
#endif /* USE_LASERXT */
#ifdef EMU_DEVICE_H
extern const device_t lxt3_device;
#endif
/* m_xt_philips.c */
extern int machine_xt_p3105_init(const machine_t *);

View File

@@ -4,10 +4,12 @@
typedef struct dev_status_empty_active_t {
atomic_bool_t empty;
atomic_bool_t active;
atomic_bool_t write_active;
} dev_status_empty_active_t;
typedef struct dev_status_active_t {
atomic_bool_t active;
atomic_bool_t write_active;
} dev_status_active_t;
typedef struct dev_status_empty_t {

View File

@@ -300,7 +300,6 @@ extern int writelnum;
extern int memspeed[11];
extern int mmu_perm;
extern uint8_t high_page; /* if a high (> 4 gb) page was detected */
extern uint8_t *_mem_exec[MEM_MAPPINGS_NO];
@@ -459,6 +458,7 @@ extern void mem_a20_recalc(void);
extern void mem_init(void);
extern void mem_close(void);
extern void mem_zero(void);
extern void mem_reset(void);
extern void mem_remap_top_ex(int kb, uint32_t start);
extern void mem_remap_top_ex_nomid(int kb, uint32_t start);

View File

@@ -41,6 +41,7 @@
#define MOUSE_TYPE_PS2 11 /* PS/2 series Bus Mouse */
#define MOUSE_TYPE_WACOM 12 /* WACOM tablet */
#define MOUSE_TYPE_WACOMARTP 13 /* WACOM tablet (ArtPad) */
#define MOUSE_TYPE_MSYSTEMSB 14 /* Mouse Systems bus mouse */
#define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */
@@ -68,6 +69,7 @@ extern const device_t mouse_msinport_device;
extern const device_t mouse_genibus_device;
# endif
extern const device_t mouse_mssystems_device;
extern const device_t mouse_mssystems_bus_device;
extern const device_t mouse_msserial_device;
extern const device_t mouse_ltserial_device;
extern const device_t mouse_ps2_device;

View File

@@ -160,8 +160,8 @@ extern int plat_vidapi(const char *name);
extern char *plat_vidapi_name(int api);
extern void plat_resize(int x, int y, int monitor_index);
extern void plat_resize_request(int x, int y, int monitor_index);
extern uint32_t plat_language_code(char *langcode);
extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len);
extern int plat_language_code(char *langcode);
extern void plat_language_code_r(int id, char *outbuf, int len);
extern void plat_get_cpu_string(char *outbuf, uint8_t len);
extern void plat_set_thread_name(void *thread, const char *name);
extern void plat_break(void);

View File

@@ -70,6 +70,7 @@ typedef struct scsi_cdrom_t {
int was_cached;
int toc_cached;
int media_access;
int sectors_num;
uint8_t vendor_type;
uint8_t ven_cmd_is_data[256];

View File

@@ -467,9 +467,10 @@ typedef struct scsi_bus_t {
int msgout_pos;
int is_msgout;
int state;
int dma_on_pio_enabled;
uint32_t bus_phase;
uint32_t total_len;
uint32_t data_repeat;
double period;
double speed;

View File

@@ -30,7 +30,7 @@ typedef struct t128_t {
uint8_t status;
uint8_t buffer[512];
uint8_t ext_ram[0x80];
uint8_t block_count;
uint32_t block_count;
int block_loaded;
int pos, host_pos;
@@ -39,6 +39,7 @@ typedef struct t128_t {
int bios_enabled;
uint8_t pos_regs[8];
int type;
pc_timer_t timer;
} t128_t;

View File

@@ -55,7 +55,7 @@ typedef struct serial_passthrough_s {
void *backend_priv; /* Private platform backend data */
} serial_passthrough_t;
extern bool serial_passthrough_enabled[SERIAL_MAX];
extern bool serial_passthrough_enabled[SERIAL_MAX - 1];
extern const device_t serial_passthrough_device;
extern void serial_passthrough_init(void);

View File

@@ -48,14 +48,22 @@ extern const device_t fdc37c669_370_device;
extern const device_t fdc37c67x_device;
extern const device_t fdc37c931apm_device;
extern const device_t fdc37c931apm_compaq_device;
extern const device_t fdc37c932fr_device;
extern const device_t fdc37c932qf_device;
extern const device_t fdc37c932_device;
extern const device_t fdc37c935_device;
extern const device_t fdc37c935_370_device;
extern const device_t fdc37c935_no_nvr_device;
#define FDC37C93X_NORMAL 0x0002
#define FDC37C93X_FR 0x0003
#define FDC37C93X_APM 0x0030
#define FDC37C93X_CHIP_ID 0x00ff
#define FDC37C931 0x0100 /* Compaq KBC firmware and configuration registers on GPIO ports. */
#define FDC37C932 0x0200 /* AMI '5' Megakey KBC firmware. */
#define FDC37C933 0x0300 /* IBM KBC firmware. */
#define FDC37C935 0x0500 /* Phoenix Multikey/42 1.38 KBC firmware. */
#define FDC37C937 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */
#define FDC37C93X_KBC 0x0f00
#define FDC37C93X_NO_NVR 0x1000
#define FDC37C93X_370 0x2000
extern const device_t fdc37c93x_device;
extern const device_t fdc37m60x_device;
extern const device_t fdc37m60x_370_device;

View File

@@ -7,23 +7,20 @@
#define MASTER_CLOCK 7159090
typedef struct cms_t {
int addrs[2];
uint8_t regs[2][32];
uint16_t latch[2][6];
int freq[2][6];
float count[2][6];
int vol[2][6][2];
int stat[2][6];
uint16_t noise[2][2];
uint16_t noisefreq[2][2];
int noisecount[2][2];
int noisetype[2][2];
#ifdef SAASOUND_H_INCLUDED
SAASND saasound;
SAASND saasound2;
#else
void* saasound;
void* saasound2;
#endif
uint8_t latched_data;
int16_t buffer[SOUNDBUFLEN * 2];
int16_t buffer[WTBUFLEN * 2];
int16_t buffer2[WTBUFLEN * 2];
int pos;
int pos, pos2;
} cms_t;
extern void cms_update(cms_t *cms);

View File

@@ -65,6 +65,7 @@ extern void ui_sb_update_panes(void);
extern void ui_sb_update_text(void);
extern void ui_sb_update_tip(int meaning);
extern void ui_sb_update_icon(int tag, int active);
extern void ui_sb_update_icon_write(int tag, int write);
extern void ui_sb_update_icon_state(int tag, int state);
extern void ui_sb_set_text_w(wchar_t *wstr);
extern void ui_sb_set_text(char *str);

View File

@@ -18,6 +18,12 @@
#ifndef VIDEO_8514A_H
#define VIDEO_8514A_H
#define INT_VSY (1 << 0)
#define INT_GE_BSY (1 << 1)
#define INT_FIFO_OVR (1 << 2)
#define INT_FIFO_EMP (1 << 3)
#define INT_MASK 0xf
typedef struct hwcursor8514_t {
int ena;
int x;
@@ -61,6 +67,7 @@ typedef struct ibm8514_t {
uint32_t vram_mask;
uint32_t pallook[512];
uint32_t bios_addr;
uint32_t ma_latch;
PALETTE vgapal;
uint8_t hwcursor_oddeven;
@@ -83,6 +90,7 @@ typedef struct ibm8514_t {
uint16_t subsys_cntl;
uint16_t setup_md;
uint16_t advfunc_cntl;
uint16_t advfunc_cntl_old;
uint16_t cur_y;
uint16_t cur_x;
int16_t destx;
@@ -100,8 +108,10 @@ typedef struct ibm8514_t {
uint16_t wrt_mask;
uint16_t rd_mask;
uint16_t color_cmp;
uint16_t bkgd_mix;
uint16_t frgd_mix;
uint8_t bkgd_mix;
uint8_t frgd_mix;
uint8_t bkgd_sel;
uint8_t frgd_sel;
uint16_t multifunc_cntl;
uint16_t multifunc[16];
uint16_t clip_right;
@@ -117,6 +127,8 @@ typedef struct ibm8514_t {
int y1;
int y2;
int temp_cnt;
int16_t dx_ibm;
int16_t dy_ibm;
int16_t cx;
int16_t cx_back;
int16_t cy;
@@ -150,6 +162,14 @@ typedef struct ibm8514_t {
int ydir;
int linedraw;
uint32_t ge_offset;
uint32_t src_ge_offset;
uint32_t dst_ge_offset;
uint16_t src_pitch;
uint16_t dst_pitch;
int64_t cur_x_24bpp;
int64_t cur_y_24bpp;
int64_t dest_x_24bpp;
int64_t dest_y_24bpp;
} accel;
uint16_t test;
@@ -216,10 +236,9 @@ typedef struct ibm8514_t {
uint16_t subsys_cntl;
uint8_t subsys_stat;
atomic_int fifo_idx;
atomic_int ext_fifo_idx;
atomic_int force_busy;
atomic_int force_busy2;
atomic_int fifo_idx;
int blitter_busy;
uint64_t blitter_time;
@@ -232,9 +251,21 @@ typedef struct ibm8514_t {
uint32_t vram_amount;
int vram_512k_8514;
int vendor_mode;
int _8514on;
int _8514crt;
PALETTE _8514pal;
latch8514_t latch;
void (*vblank_start)(void *priv);
void (*accel_out_fifo)(void *priv, uint16_t port, uint16_t val, int len);
void (*update_irqs)(void *priv);
} ibm8514_t;
#define IBM_8514A (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x00))
#define ATI_8514A_ULTRA (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x01))
#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == 0x01)
#define ATI_MACH32 ((dev->local & 0xff) == 0x02)
#endif /*VIDEO_8514A_H*/

View File

@@ -25,6 +25,7 @@ typedef struct mach_t {
rom_t bios_rom;
rom_t bios_rom2;
mem_mapping_t mmio_linear_mapping;
mem_mapping_t banked_mapping;
int mca_bus;
int pci_bus;
@@ -71,7 +72,14 @@ typedef struct mach_t {
uint8_t bank_r;
uint16_t shadow_set;
uint16_t shadow_cntl;
int override_resolution;
uint8_t overscan_col_8;
uint8_t overscan_b_col_24;
uint8_t overscan_g_col_24;
uint8_t overscan_r_col_24;
uint16_t fifo_test_data[17];
uint8_t old_on1;
uint8_t old_on2;
int crt_resolution;
struct {
uint8_t line_idx;
@@ -79,9 +87,9 @@ typedef struct mach_t {
uint8_t patt_idx;
uint8_t patt_len;
uint8_t pix_trans[2];
uint8_t eeprom_control;
uint8_t alu_bg_fn;
uint8_t alu_fg_fn;
uint16_t eeprom_control;
uint16_t clip_left;
uint16_t clip_right;
uint16_t clip_top;
@@ -97,9 +105,13 @@ typedef struct mach_t {
uint16_t clock_sel;
uint16_t crt_pitch;
uint16_t ge_pitch;
uint16_t src_pitch;
uint16_t dst_pitch;
uint16_t dest_cmp_fn;
uint16_t dp_config;
uint16_t ext_ge_config;
uint16_t crt_offset_lo;
uint16_t crt_offset_hi;
uint16_t ge_offset_lo;
uint16_t ge_offset_hi;
uint16_t linedraw_opt;
@@ -148,17 +160,22 @@ typedef struct mach_t {
int src_stepx;
uint8_t mono_pattern_normal[16];
uint8_t color_pattern[32];
uint16_t color_pattern_hicol[8];
int mono_pattern[8][8];
uint32_t ge_offset;
uint32_t src_ge_offset;
uint32_t dst_ge_offset;
uint32_t crt_offset;
uint32_t patt_len_reg;
int poly_fill;
uint16_t dst_clr_cmp_mask;
int clip_overrun;
int color_pattern_idx;
int64_t src_x_scan;
int64_t src_y_scan;
} accel;
atomic_int force_busy;
atomic_int fifo_test_idx;
} mach_t;
#endif /*VIDEO_ATI_MACH8_H*/

View File

@@ -171,11 +171,11 @@ typedef struct svga_t {
latch_t latch;
pc_timer_t timer;
pc_timer_t timer8514;
pc_timer_t timer_8514;
pc_timer_t timer_xga;
double clock;
double clock8514;
double clock_8514;
double clock_xga;
double multiplier;
@@ -315,6 +315,8 @@ typedef struct svga_t {
card should not attempt to display anything. */
void (*render_override)(void *priv);
void * priv_parent;
void * local;
} svga_t;
extern void ibm8514_set_poll(svga_t *svga);

View File

@@ -583,6 +583,7 @@ extern const device_t ps1vga_mca_device;
extern const device_t voodoo_device;
extern const device_t voodoo_banshee_device;
extern const device_t creative_voodoo_banshee_device;
extern const device_t quantum3d_raven_device;
extern const device_t voodoo_3_1000_device;
extern const device_t voodoo_3_1000_agp_device;
extern const device_t voodoo_3_2000_device;

View File

@@ -20,6 +20,7 @@ add_library(mch OBJECT
machine_table.c
m_xt.c
m_xt_compaq.c
m_xt_laserxt.c
m_xt_philips.c
m_xt_t1000.c
m_xt_t1000_vid.c
@@ -64,11 +65,6 @@ if(DESKPRO386)
target_compile_definitions(mch PRIVATE USE_DESKPRO386)
endif()
if(LASERXT)
target_sources(mch PRIVATE m_xt_laserxt.c)
target_compile_definitions(mch PRIVATE USE_LASERXT)
endif()
if(OLIVETTI)
target_compile_definitions(mch PRIVATE USE_OLIVETTI)
endif()

View File

@@ -187,7 +187,7 @@ static const device_config_t ibmat_config[] = {
};
const device_t ibmat_device = {
.name = " IBM AT Devices",
.name = "IBM AT",
.internal_name = "ibmat_device",
.flags = 0,
.local = 0,
@@ -294,7 +294,7 @@ static const device_config_t ibmxt286_config[] = {
};
const device_t ibmxt286_device = {
.name = "IBM XT Model 286 Devices",
.name = "IBM XT Model 286",
.internal_name = "ibmxt286_device",
.flags = 0,
.local = 0,
@@ -332,6 +332,23 @@ machine_at_ibmxt286_init(const machine_t *model)
return ret;
}
int
machine_at_pb286_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/pb286/LB_V332P.BIN",
"roms/machines/pb286/HB_V332P.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_ibm_common_init(model);
return ret;
}
int
machine_at_siemens_init(const machine_t *model)
{

View File

@@ -653,7 +653,9 @@ machine_at_if386sx_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */
device_add(&keyboard_at_phoenix_device);
device_add(&neat_sx_device);
@@ -663,6 +665,12 @@ machine_at_if386sx_init(const machine_t *model)
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
/*
One serial port - on the real hardware IF386AX, it is on the VL 16C451,
alognside the bidirectional parallel port.
*/
device_add_inst(&ns16450_device, 1);
return ret;
}

View File

@@ -691,15 +691,17 @@ static const device_config_t pb450_config[] = {
.name = "bios",
.description = "BIOS Version",
.type = CONFIG_BIOS,
.default_string = "pci10a",
.default_string = "pb450a",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.bios = {
{ .name = "PCI 1.0A", .internal_name = "pb450" /*"pci10a"*/, .bios_type = BIOS_NORMAL,
{ .name = "PCI 1.0A", .internal_name = "pb450a" /*"pci10a"*/, .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/OPTI802.bin", "" } },
{ .name = "PNP 1.1A", .internal_name = "pnp11a", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/PNP11A.bin", "" } },
{ .name = "P4HS20 (Micro Firmware/Phoenix 4.05)", .internal_name = "p4hs20", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/p4hs20.bin", "" } },
{ .files_no = 0 }
},
},
@@ -708,7 +710,7 @@ static const device_config_t pb450_config[] = {
};
const device_t pb450_device = {
.name = "Packard Bell PB450 Devices",
.name = "Packard Bell PB450",
.internal_name = "pb450_device",
.flags = 0,
.local = 0,
@@ -732,7 +734,7 @@ machine_at_pb450_init(const machine_t *model)
return ret;
device_context(model->device);
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
device_context_restore();
@@ -1182,6 +1184,39 @@ machine_at_ms4144_init(const machine_t *model)
return ret;
}
int
machine_at_acerp3_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/acerp3/Acer Mate 600 P3 BIOS U13 V2.0R02-J3 ACR8DE00-S00-950911-R02-J3.bin",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
machine_at_sis_85c496_common_init(model);
device_add(&sis_85c496_device);
pci_register_slot(0x09, PCI_CARD_VIDEO, 0, 0, 0, 0);
pci_register_slot(0x0A, PCI_CARD_IDE, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&fdc37c665_ide_device);
device_add(&keyboard_ps2_acer_pci_device);
device_add(&ide_cmd640_pci_legacy_only_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5434_onboard_pci_device);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_486sp3c_init(const machine_t *model)
{
@@ -1248,7 +1283,9 @@ machine_at_alfredo_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device);
device_add(&ide_pci_device);
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
@@ -1258,7 +1295,7 @@ machine_at_alfredo_init(const machine_t *model)
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&keyboard_ps2_pci_device);
device_add(&keyboard_ps2_phoenix_device);
device_add(&sio_device);
device_add(&fdc37c663_device);
device_add(&intel_flash_bxt_ami_device);
@@ -1279,14 +1316,15 @@ machine_at_ninja_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 1, 2);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 1, 2, 1);
device_add(&keyboard_ps2_intel_ami_pci_device);
device_add(&keyboard_ps2_phoenix_device);
device_add(&intel_flash_bxt_ami_device);
device_add(&i420ex_device);
@@ -2280,7 +2318,8 @@ machine_at_tg486g_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device);
device_add(&sis_85c471_device);
device_add(&ide_isa_device);
device_add(&fdc37c651_ide_device);

Some files were not shown because too many files have changed in this diff Show More