Merge remote-tracking branch 'upstream/master' into feature/mtrr

This commit is contained in:
Jasmine Iwanek
2022-10-26 13:32:20 -04:00
26 changed files with 629 additions and 229 deletions

View File

@@ -72,19 +72,22 @@ AppDir:
files:
exclude:
- etc
- lib/udev
- opt/libc/usr/share
- usr/[a-km-rt-zA-Z]*
- usr/lib/*/libasound.so.*
- usr/lib/*.a
- usr/lib/cmake
- usr/lib/pkgconfig
- usr/s[a-gi-zA-Z]*
- usr/share/[a-hj-ln-zA-Z]*
- usr/share/i[a-bd-zA-Z]*
- usr/share/m[a-df-zA-Z]*
- usr/share/metainfo/*.metainfo.xml
- usr/[!ls]* # * except lib, local, share
- usr/lib/*/libasound.so.* # using our own ALSA can cause issues, and the API is pretty stable anyway
- usr/lib/*.a # produced by library compilation
- usr/lib/cmake # produced by library compilation
- usr/lib/pkgconfig # produced by library compilation
- usr/s[!h]* # s* except share
- usr/share/[!aim]* # * except applications, icons, metainfo
- usr/share/a[!p]* # a* except applications
- usr/share/ap[!p]* # ap* except applications
- usr/share/app[!l]* # app* except applications
- usr/share/i[!c]* # i* except icons
- usr/share/icons/[!h]* # * except hicolor
- usr/share/icons/h[!i]* # h* except hicolor
- usr/share/m[!e]* # m* except metainfo
- usr/share/metainfo/*.metainfo.xml # metainfo for libraries
- var
AppImage:
arch: !ENV '${arch_appimage}'
file_name: '-n' # nasty hack to disable metainfo validation
file_name: !ENV '${appimage_path}'

View File

@@ -136,6 +136,7 @@ package_name=
arch=
tarball_name=
skip_archive=0
dep_report=0
strip=0
cmake_flags=
while [ $# -gt 0 ]
@@ -154,6 +155,11 @@ do
skip_archive=1
;;
-p)
shift
dep_report=1
;;
-s)
shift
tarball_name="$1"
@@ -166,19 +172,23 @@ do
;;
*)
if echo $1 | grep -q " "
then
cmake_flag="\"$1\""
else
cmake_flag="$1"
fi
if [ -z "$cmake_flags" ]
then
cmake_flags="$cmake_flag"
else
cmake_flags="$cmake_flags $cmake_flag"
fi
shift
# Consume remaining arguments as CMake flags.
while [ $# -gt 0 ]
do
if echo $1 | grep -q " "
then
cmake_flag="\"$1\""
else
cmake_flag="$1"
fi
if [ -z "$cmake_flags" ]
then
cmake_flags="$cmake_flag"
else
cmake_flags="$cmake_flags $cmake_flag"
fi
shift
done
;;
esac
done
@@ -545,8 +555,8 @@ then
# Switch into the correct architecture if required.
case $arch in
x86_64*) arch_mac="i386";;
*) arch_mac="$arch";;
x86_64*) arch_mac="i386"; arch_cmd="x86_64";;
*) arch_mac="$arch"; arch_cmd="$arch";;
esac
if [ "$(arch)" != "$arch" -a "$(arch)" != "$arch_mac" ]
then
@@ -556,7 +566,7 @@ then
args=
[ $strip -ne 0 ] && args="-t $args"
[ $skip_archive -ne 0 ] && args="-n $args"
arch -"$arch" zsh -lc 'exec "'"$0"'" -b "'"$package_name"'" "'"$arch"'" '"$args""$cmake_flags"
arch -"$arch_cmd" zsh -lc 'exec "'"$0"'" -b "'"$package_name"'" "'"$arch"'" '"$args""$cmake_flags"
exit $?
fi
echo [-] Using architecture [$(arch)]
@@ -589,7 +599,21 @@ then
sudo sed -i -e 's/-no-feature-vulkan/-feature-vulkan/g' "$qt5_portfile"
sudo sed -i -e 's/configure.env-append MAKE=/configure.env-append VULKAN_SDK=${prefix} MAKE=/g' "$qt5_portfile"
fi
sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt)
while :
do
# Attempt to install dependencies.
sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) 2>&1 | tee macports.log
# Stop if no port version activation errors were found.
stuck_dep=$(grep " cannot be built while another version of " macports.log | cut -d" " -f10)
[ -z $stuck_dep ] && break
# Deactivate the stuck dependency and try again.
sudo "$macports/bin/port" -f deactivate $stuck_dep
done
# Remove MacPorts error detection log.
rm -f macports.log
# Save build tag to skip this later. Doing it here (once everything is
# in place) is important to avoid potential issues with retried builds.
@@ -609,6 +633,7 @@ else
# Establish general dependencies.
pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream"
[ $dep_report -ne 0 ] && pkgs="$pkgs pax-utils"
if [ "$(dpkg --print-architecture)" = "$arch_deb" ]
then
pkgs="$pkgs build-essential"
@@ -957,7 +982,7 @@ else
sdl_ss=ON
fi
# Build SDL2 with video systems (and some dependencies) only if the SDL interface is used.
# Build SDL2 with video systems (and dependencies) only if the SDL interface is used.
sdl_ui=OFF
grep -qiE "^QT:BOOL=ON" build/CMakeCache.txt || sdl_ui=ON
@@ -1024,11 +1049,18 @@ else
metainfo_base=archive_tmp/usr/share/metainfo
mkdir -p "$metainfo_base"
cp -p "src/unix/assets/$project_id."*".xml" "$metainfo_base/$project_id.appdata.xml"
applications_base=archive_tmp/usr/share/applications
mkdir -p "$applications_base"
cp -p "src/unix/assets/$project_id.desktop" "$applications_base/"
# Archive icons.
icon_base=archive_tmp/usr/share/icons
mkdir -p "$icon_base"
cp -rp src/unix/assets/[0-9]*x[0-9]* "$icon_base/"
icon_base=archive_tmp/usr/share/icons/hicolor
for icon_size in src/unix/assets/[0-9]*x[0-9]*
do
icon_dir="$icon_base/$(basename "$icon_size")"
mkdir -p "$icon_dir"
cp -rp "$icon_size" "$icon_dir/apps"
done
project_icon=$(ls "$icon_base/"[0-9]*x[0-9]*/* | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)')
# Archive executable, while also stripping it if requested.
@@ -1088,7 +1120,7 @@ else
# Generate modified AppImage metadata to suit build requirements.
cat << EOF > AppImageBuilder-generated.yml
# This file is generated automatically by .ci/build.sh and will be
# This file is automatically generated by .ci/build.sh and will be
# overwritten if edited. Please edit .ci/AppImageBuilder.yml instead.
EOF
while IFS= read line
@@ -1096,7 +1128,7 @@ EOF
# Skip blank or comment lines.
echo "$line" | grep -qE '^(#|$)' && continue
# Parse "# if OPTION VALUE" condition lines.
# Parse "# if OPTION:TYPE=VALUE" CMake condition lines.
condition=$(echo "$line" | grep -oP '# if \K(.+)')
if [ -n "$condition" ]
then
@@ -1109,7 +1141,7 @@ EOF
done < .ci/AppImageBuilder.yml
# Download appimage-builder if necessary.
appimage_builder_url="https://github.com/AppImageCrafters/appimage-builder/releases/download/v0.9.2/appimage-builder-0.9.2-35e3eab-x86_64.AppImage"
appimage_builder_url="https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-$(uname -m).AppImage"
appimage_builder_binary="$cache_dir/$(basename "$appimage_builder_url")"
if [ ! -e "$appimage_builder_binary" ]
then
@@ -1125,18 +1157,23 @@ EOF
ln -s "$cache_dir/appimage-builder-cache" appimage-builder-cache
# Run appimage-builder in extract-and-run mode for Docker compatibility.
# --appdir is a workaround for https://github.com/AppImageCrafters/appimage-builder/issues/270
project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \
arch_appimage="$arch_appimage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage --recipe AppImageBuilder-generated.yml
arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \
--recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)"
status=$?
# Rename AppImage to the final name if the build succeeded.
if [ $status -eq 0 ]
# Remove appimage-builder binary on failure, just in case it's corrupted.
[ $status -ne 0 ] && rm -f "$appimage_builder_binary"
# Generate library dependency report if requested.
if [ $dep_report -ne 0 ]
then
mv "$project-"*".AppImage" "$cwd/$package_name.AppImage"
status=$?
else
# Remove appimage-builder binary just in case it's corrupted.
rm -f "$appimage_builder_binary"
echo '[-] Library dependency report:'
# Run lddtree with AppImage lib directories included in the search path.
LD_LIBRARY_PATH=$(find "$(pwd)/archive_tmp" -type d -name lib -o -name lib64 | while read dir; do find "$dir" -type d; done | tr '\n' ':') \
lddtree "archive_tmp/usr/local/bin/$project" 2>&1 | tee depreport.txt
fi
fi

View File

@@ -417,9 +417,36 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
{
uint8_t *p = data;
struct tm *time_s = localtime(&time);
if (!time_s)
fatal("VISO: localtime(%d) = NULL\n", time);
if (!time_s) {
/* localtime will return NULL if the time_t is negative (Windows)
or way too far into 64-bit space (Linux). Fall back to epoch. */
time_t epoch = 0;
time_s = localtime(&epoch);
if (!time_s)
fatal("VISO: localtime(0) = NULL\n");
/* Force year clamping if the timestamp is known to be outside the supported ranges. */
if (time < (longform ? -62135596800LL : -2208988800LL)) /* 0001-01-01 00:00:00 : 1900-01-01 00:00:00 */
time_s->tm_year = -1901;
else if (time > (longform ? 253402300799LL : 5869583999LL)) /* 9999-12-31 23:59:59 : 2155-12-31 23:59:59 */
time_s->tm_year = 8100;
}
/* Clamp year to the supported ranges, and assume the
OS returns valid numbers in the other struct fields. */
if (time_s->tm_year < (longform ? -1900 : 0)) {
time_s->tm_year = longform ? -1900 : 0;
time_s->tm_mon = time_s->tm_hour = time_s->tm_min = time_s->tm_sec = 0;
time_s->tm_mday = 1;
} else if (time_s->tm_year > (longform ? 8099 : 255)) {
time_s->tm_year = longform ? 8099 : 255;
time_s->tm_mon = 12;
time_s->tm_mday = 31;
time_s->tm_hour = 23;
time_s->tm_min = time_s->tm_sec = 59;
}
/* Convert timestamp. */
if (longform) {
p += sprintf((char *) p, "%04u%02u%02u%02u%02u%02u00",
1900 + time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday,
@@ -443,10 +470,14 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
{
uint8_t *p = data, *q, *r;
*p++ = 0; /* size (filled in later) */
*p++ = 0; /* extended attribute length */
VISO_SKIP(p, 8); /* sector offset */
VISO_LBE_32(p, entry->stats.st_size); /* size (filled in later if this is a directory) */
*p++ = 0; /* size (filled in later) */
*p++ = 0; /* extended attribute length */
VISO_SKIP(p, 8); /* sector offset */
VISO_LBE_32(p, entry->stats.st_size); /* size (filled in later if this is a directory) */
#ifdef _WIN32
if (entry->stats.st_mtime < 0)
pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path);
#endif
p += viso_fill_time(p, entry->stats.st_mtime, format, 0); /* time */
*p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */
@@ -848,7 +879,7 @@ viso_init(const char *dirname, int *error)
/* Handle file size and El Torito boot code. */
if (!S_ISDIR(entry->stats.st_mode)) {
/* Limit to 4 GB - 1 byte. */
/* Clamp to 4 GB - 1 byte. */
if (entry->stats.st_size > ((uint32_t) -1))
entry->stats.st_size = (uint32_t) -1;

View File

@@ -751,9 +751,15 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
/* Bus Mastering Base Address */
case 0x20:
case 0x21:
case 0x22:
case 0x23:
dev->ide_conf[addr] = val;
/* Datasheet erratum: the PCI BAR's actually have different sizes. */
if (addr == 0x20)
dev->ide_conf[addr] = (val & 0xe0) | 0x01;
else if ((addr & 0x43) == 0x00)
dev->ide_conf[addr] = (val & 0xf8) | 0x01;
else if ((addr & 0x43) == 0x40)
dev->ide_conf[addr] = (val & 0xfc) | 0x01;
else
dev->ide_conf[addr] = val;
ali5229_ide_handler(dev);
break;
@@ -1568,7 +1574,7 @@ ali1543_init(const device_t *info)
dev->offset = (info->local >> 8) & 0x7f;
if (info->local & 0x8000)
dev->offset = -dev->offset;
pclog("Offset = %i\n", dev->offset);
ali1543_log("Offset = %i\n", dev->offset);
pci_enable_mirq(0);
pci_enable_mirq(1);

View File

@@ -1697,6 +1697,20 @@ const device_t piix_device = {
.config = NULL
};
const device_t piix_no_mirq_device = {
.name = "Intel 82371FB (PIIX) (No MIRQ)",
.internal_name = "piix_no_mirq",
.flags = DEVICE_PCI,
.local = 0x122e1101,
.init = piix_init,
.close = piix_close,
.reset = piix_reset,
{ .available = NULL },
.speed_changed = piix_speed_changed,
.force_redraw = NULL,
.config = NULL
};
const device_t piix_rev02_device = {
.name = "Intel 82371FB (PIIX) (Faulty BusMastering!!)",
.internal_name = "piix_rev02",

View File

@@ -47,8 +47,6 @@ void codegen_accumulate(int acc_reg, int delta)
void codegen_accumulate_flush(void)
{
intptr_t rip;
if (acc_regs[0].count) {
/* To reduce the size of the generated code, we take advantage of
the fact that the target offset points to _cycles within cpu_state,

View File

@@ -313,7 +313,7 @@ readmemw(uint32_t s, uint16_t a)
else {
wait(4, 1);
ret = read_mem_b(s + a);
ret |= read_mem_b(s + (is186 ? (a + 1) : (a + 1) & 0xffff)) << 8;
ret |= read_mem_b(s + ((is186 && !is_nec) ? (a + 1) : (a + 1) & 0xffff)) << 8;
}
return ret;
@@ -385,7 +385,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
else {
write_mem_b(addr, v & 0xff);
wait(4, 1);
addr = s + (is186 ? (a + 1) : ((a + 1) & 0xffff));
addr = s + ((is186 && !is_nec) ? (a + 1) : ((a + 1) & 0xffff));
write_mem_b(addr, v >> 8);
}
@@ -794,7 +794,7 @@ seteaq(uint64_t val)
static void
push(uint16_t *val)
{
if (is186 && SP == 1) {
if ((is186 && !is_nec) && (SP == 1)) {
writememw(ss - 1, 0, *val);
SP = cpu_state.eaaddr = 0xFFFF;
return;
@@ -963,7 +963,7 @@ interrupt(uint16_t addr)
pfq_clear();
ovr_seg = NULL;
access(39, 16);
tempf = cpu_state.flags & (is_nec && cpu_state.inside_emulation_mode ? 0x8fd7 : 0x0fd7);
tempf = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? 0x8fd7 : 0x0fd7);
push(&tempf);
cpu_state.flags &= ~(I_FLAG | T_FLAG);
access(40, 16);
@@ -1405,8 +1405,7 @@ set_co_mul(int bits, int carry)
{
set_cf(carry);
set_of(carry);
if (!is_nec)
set_zf_ex(!carry);
set_zf_ex(!carry);
if (!carry)
wait(1, 0);
}
@@ -1653,7 +1652,8 @@ execx86(int cycs)
int8_t nibble_result_s;
uint16_t addr, tempw, new_cs, new_ip;
uint16_t tempw_int, size, tempbp, lowbound;
uint16_t highbound, regval;
uint16_t highbound, regval, orig_sp, wordtopush;
uint16_t immediate, old_flags;
int bits;
uint32_t dest_seg, i, carry, nibble;
uint32_t srcseg, byteaddr;
@@ -1666,6 +1666,7 @@ execx86(int cycs)
if (!repeating) {
cpu_state.oldpc = cpu_state.pc;
opcode = pfq_fetchb();
handled = 0;
oldc = cpu_state.flags & C_FLAG;
if (clear_lock) {
in_lock = 0;
@@ -1678,6 +1679,97 @@ execx86(int cycs)
// pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode);
if (is186) {
switch (opcode) {
case 0x60: /*PUSHA/PUSH R*/
orig_sp = SP;
wait(1, 0);
push(&AX);
push(&CX);
push(&DX);
push(&BX);
push(&orig_sp);
push(&BP);
push(&SI);
push(&DI);
handled = 1;
break;
case 0x61: /*POPA/POP R*/
wait(9, 0);
DI = pop();
SI = pop();
BP = pop();
(void) pop(); /* former orig_sp */
BX = pop();
DX = pop();
CX = pop();
AX = pop();
handled = 1;
break;
case 0x62: /* BOUND r/m */
lowbound = 0;
highbound = 0;
regval = 0;
do_mod_rm();
lowbound = readmemw(easeg, cpu_state.eaaddr);
highbound = readmemw(easeg, cpu_state.eaaddr + 2);
regval = get_reg(cpu_reg);
if (lowbound > regval || highbound < regval) {
cpu_state.pc = cpu_state.oldpc;
interrupt(5);
}
handled = 1;
break;
case 0x64:
case 0x65:
if (is_nec) {
/* REPC/REPNC */
wait(1, 0);
in_rep = (opcode == 0x64 ? 1 : 2);
rep_c_flag = 1;
completed = 0;
handled = 1;
}
break;
case 0x68:
wordtopush = pfq_fetchw();
wait(1, 0);
push(&wordtopush);
handled = 1;
break;
case 0x69:
immediate = 0;
bits = 16;
do_mod_rm();
read_ea(0, 16);
immediate = pfq_fetchw();
mul(cpu_data & 0xFFFF, immediate);
set_reg(cpu_reg, cpu_data);
set_co_mul(16, cpu_dest != 0);
handled = 1;
break;
case 0x6a:
wordtopush = sign_extend(pfq_fetchb());
push(&wordtopush);
handled = 1;
break;
case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */
immediate = 0;
bits = 16;
do_mod_rm();
read_ea(0, 16);
immediate = pfq_fetchb();
mul(cpu_data & 0xFFFF, immediate);
set_reg(cpu_reg, cpu_data);
set_co_mul(16, cpu_dest != 0);
handled = 1;
break;
case 0x6c:
case 0x6d: /* INM dst, DW/INS dst, DX */
bits = 8 << (opcode & 1);
@@ -1756,28 +1848,6 @@ execx86(int cycs)
handled = 1;
break;
case 0xc9: /* LEAVE/DISPOSE */
SP = BP;
BP = pop();
handled = 1;
break;
case 0x62: /* BOUND r/m */
lowbound = 0;
highbound = 0;
regval = 0;
do_mod_rm();
lowbound = readmemw(easeg, cpu_state.eaaddr);
highbound = readmemw(easeg, cpu_state.eaaddr + 2);
regval = get_reg(cpu_reg);
if (lowbound > regval || highbound < regval) {
cpu_state.pc = cpu_state.oldpc;
interrupt(5);
}
handled = 1;
break;
case 0xc0:
case 0xc1: /*rot imm8 */
bits = 8 << (opcode & 1);
@@ -1867,6 +1937,12 @@ execx86(int cycs)
set_ea(cpu_data);
handled = 1;
break;
case 0xc9: /* LEAVE/DISPOSE */
SP = BP;
BP = pop();
handled = 1;
break;
}
}
if (!handled) {
@@ -1882,7 +1958,7 @@ execx86(int cycs)
case 0x0F:
case 0x17:
case 0x1F: /* POP seg */
if (is_nec && opcode == 0x0F) {
if (is_nec && (opcode == 0x0F)) {
uint8_t orig_opcode = opcode;
opcode = pfq_fetchb();
switch (opcode) {
@@ -2422,34 +2498,8 @@ execx86(int cycs)
break;
case 0x60: /*JO alias*/
if (is186) { /* PUSHA/PUSH R*/
uint16_t orig_sp = SP;
wait(1, 0);
push(&AX);
push(&CX);
push(&DX);
push(&BX);
push(&orig_sp);
push(&BP);
push(&SI);
push(&DI);
} else
jcc(opcode, cpu_state.flags & V_FLAG);
break;
case 0x70: /*JO*/
case 0x61: /*JNO alias*/
if (is186) { /* POPA/POP R*/
wait(9, 0);
DI = pop();
SI = pop();
BP = pop();
(void) pop(); /* former orig_sp */
BX = pop();
DX = pop();
CX = pop();
AX = pop();
break;
}
case 0x71: /*JNO*/
jcc(opcode, cpu_state.flags & V_FLAG);
break;
@@ -2463,14 +2513,7 @@ execx86(int cycs)
case 0x74: /*JE*/
case 0x65: /*JNE alias*/
case 0x75: /*JNE*/
if (is_nec && (opcode & 0xFE) == 0x64) {
/* REPC/REPNC */
wait(1, 0);
in_rep = (opcode == 0x64 ? 1 : 2);
rep_c_flag = 1;
completed = 0;
} else
jcc(opcode, cpu_state.flags & Z_FLAG);
jcc(opcode, cpu_state.flags & Z_FLAG);
break;
case 0x66: /*JBE alias*/
case 0x76: /*JBE*/
@@ -2479,47 +2522,14 @@ execx86(int cycs)
jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG));
break;
case 0x68: /*JS alias*/
if (is186) { /* PUSH imm16 */
uint16_t wordtopush = pfq_fetchw();
wait(1, 0);
push(&wordtopush);
break;
}
case 0x78: /*JS*/
case 0x69: /*JNS alias*/
if (is186 && opcode == 0x69) { /* IMUL reg16,reg16/mem16,imm16 */
uint16_t immediate = 0;
bits = 16;
do_mod_rm();
read_ea(0, 16);
immediate = pfq_fetchw();
mul(cpu_data & 0xFFFF, immediate);
set_reg(cpu_reg, cpu_data);
set_co_mul(16, cpu_dest != 0);
break;
}
case 0x79: /*JNS*/
jcc(opcode, cpu_state.flags & N_FLAG);
break;
case 0x6A: /*JP alias*/
if (is186) { /* PUSH imm8 */
uint16_t wordtopush = sign_extend(pfq_fetchb());
push(&wordtopush);
break;
}
case 0x7A: /*JP*/
case 0x6B: /*JNP alias*/
if (is186 && opcode == 0x6B) { /* IMUL reg16,reg16/mem16,imm8 */
uint16_t immediate = 0;
bits = 16;
do_mod_rm();
read_ea(0, 16);
immediate = pfq_fetchb();
mul(cpu_data & 0xFFFF, immediate);
set_reg(cpu_reg, cpu_data);
set_co_mul(16, cpu_dest != 0);
break;
}
case 0x7B: /*JNP*/
jcc(opcode, cpu_state.flags & P_FLAG);
break;
@@ -2733,7 +2743,7 @@ execx86(int cycs)
break;
case 0x9C: /*PUSHF*/
access(33, 16);
tempw = cpu_state.flags & (is_nec && cpu_state.inside_emulation_mode ? MD_FLAG | 0x0fd7 : 0x0fd7);
tempw = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? (MD_FLAG | 0x0fd7) : 0x0fd7);
push(&tempw);
break;
case 0x9D: /*POPF*/
@@ -3108,13 +3118,21 @@ execx86(int cycs)
case 0xD4: /*AAM*/
wait(1, 0);
cpu_src = pfq_fetchb();
if (is_nec) {
(void) pfq_fetchb();
cpu_src = 10;
} else
cpu_src = pfq_fetchb();
if (x86_div(AL, 0))
set_pzs(16);
break;
case 0xD5: /*AAD*/
wait(1, 0);
mul(pfq_fetchb(), AH);
if (is_nec) {
(void) pfq_fetchb();
mul(10, AH);
} else
mul(pfq_fetchb(), AH);
cpu_dest = AL;
cpu_src = cpu_data;
add(8);
@@ -3340,6 +3358,7 @@ execx86(int cycs)
break;
case 0x20: /* MUL */
case 0x28: /* IMUL */
old_flags = cpu_state.flags;
wait(1, 0);
mul(get_accum(bits), cpu_data);
if (opcode & 1) {
@@ -3354,12 +3373,14 @@ execx86(int cycs)
if (!is_nec)
cpu_data = AH;
}
/* NOTE: When implementing the V20, care should be taken to not change
the zero flag. */
set_sf(bits);
set_pf();
if (cpu_mod != 3)
wait(1, 0);
/* NOTE: When implementing the V20, care should be taken to not change
the zero flag. */
if (is_nec)
cpu_state.flags = (cpu_state.flags & ~Z_FLAG) | (old_flags & Z_FLAG);
break;
case 0x30: /* DIV */
case 0x38: /* IDIV */

View File

@@ -367,7 +367,7 @@ cpu_set(void)
unmask_a20_in_smm = 0;
CPUID = cpu_s->cpuid_model;
is8086 = (cpu_s->cpu_type > CPU_8088) && !(cpu_s->cpu_type == CPU_V20);
is8086 = (cpu_s->cpu_type > CPU_8088) && (cpu_s->cpu_type != CPU_V20) && (cpu_s->cpu_type != CPU_188);
is_nec = (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
is186 = (cpu_s->cpu_type == CPU_186) || (cpu_s->cpu_type == CPU_188) || (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30);
is286 = (cpu_s->cpu_type >= CPU_286);

View File

@@ -165,7 +165,7 @@ const cpu_family_t cpu_families[] = {
{"", 0}
}
}, {
.package = CPU_PKG_186,
.package = CPU_PKG_8086,
.manufacturer = "NEC",
.name = "V30",
.internal_name = "necv30",

View File

@@ -72,7 +72,7 @@ typedef struct {
int blocked;
int tandy;
uint8_t pa, pb, pd;
uint8_t pa, pb, pd, clock;
uint8_t key_waiting;
uint8_t type, pravetz_flags;
@@ -514,17 +514,22 @@ static void
kbd_write(uint16_t port, uint8_t val, void *priv)
{
xtkbd_t *kbd = (xtkbd_t *) priv;
uint8_t bit, set;
uint8_t bit, set, new_clock;
switch (port) {
case 0x61: /* Keyboard Control Register (aka Port B) */
if (!(kbd->pb & 0x40) && (val & 0x40)) {
key_queue_start = key_queue_end = 0;
kbd->want_irq = 0;
kbd->blocked = 0;
kbd_adddata(0xaa);
if (!(val & 0x80)) {
new_clock = !!(val & 0x40);
if (!kbd->clock && new_clock) {
key_queue_start = key_queue_end = 0;
kbd->want_irq = 0;
kbd->blocked = 0;
kbd_adddata(0xaa);
}
}
kbd->pb = val;
if (!(kbd->pb & 0x80))
kbd->clock = !!(kbd->pb & 0x40);
ppi.pb = val;
timer_process();

View File

@@ -887,6 +887,9 @@ ide_atapi_attach(ide_t *ide)
ide->mdma_mode = (1 << ide->get_max(ide_boards[ide->board]->force_ata3 || !ide_bm[ide->board], TYPE_PIO));
ide->error = 1;
ide->cfg_spt = ide->cfg_hpc = 0;
#ifndef EARLY_ATAPI
ide->sc->status = 0;
#endif
}
void
@@ -1628,12 +1631,16 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
wait_time = seek_time > xfer_time ? seek_time : xfer_time;
} else if (val == WIN_READ_MULTIPLE) {
sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize;
} else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) {
sec_count = ide->secount ? ide->secount : 256;
if (sec_count > ide->blocksize)
sec_count = ide->blocksize;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
wait_time = seek_time + xfer_time;
} else {
} else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize == 0))
wait_time = 200.0;
else {
sec_count = 1;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
@@ -1684,9 +1691,10 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
double wait_time = seek_time > xfer_time ? seek_time : xfer_time;
ide_set_callback(ide, wait_time);
} else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) {
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), ide->secount);
uint32_t sec_count = ide->secount ? ide->secount : 256;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2));
} else if (val == WIN_IDENTIFY)
} else if ((val == WIN_IDENTIFY) || (val == WIN_SET_FEATURES))
ide_callback(ide);
else
ide_set_callback(ide, 200.0 * IDE_TIME);
@@ -1854,7 +1862,9 @@ ide_read_data(ide_t *ide, int length)
ide->atastat = BSY_STAT | READY_STAT | DSC_STAT;
if (ide->command == WIN_READ_MULTIPLE) {
if (!ide->blockcount) {
uint32_t sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize;
uint32_t sec_count = ide->secount ? ide->secount : 256;
if (sec_count > ide->blocksize)
sec_count = ide->blocksize;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
ide_set_callback(ide, seek_time + xfer_time);
@@ -2147,7 +2157,11 @@ ide_callback(void *priv)
ide_set_signature(ide);
if (ide->type == IDE_ATAPI) {
#ifdef EARLY_ATAPI
ide->sc->status = DRDY_STAT | DSC_STAT;
#else
ide->sc->status = 0;
#endif
ide->sc->error = 1;
if (ide->device_reset)
ide->device_reset(ide->sc);
@@ -2443,6 +2457,8 @@ ide_callback(void *priv)
case WIN_SET_MULTIPLE_MODE:
if (ide->type == IDE_ATAPI)
goto abort_cmd;
if ((ide->secount < 2) || (ide->secount > hdd[ide->hdd_num].max_multiple_block))
goto abort_cmd;
ide->blocksize = ide->secount;
ide->atastat = DRDY_STAT | DSC_STAT;
ide_irq_raise(ide);
@@ -2787,6 +2803,8 @@ ide_board_setup(int board)
dev->error = 1;
if (dev->type != IDE_HDD)
dev->cfg_spt = dev->cfg_hpc = 0;
if (dev->type == IDE_HDD)
dev->blocksize = hdd[dev->hdd_num].max_multiple_block;
}
}

View File

@@ -91,6 +91,7 @@ extern const device_t sio_device;
extern const device_t sio_zb_device;
extern const device_t piix_device;
extern const device_t piix_no_mirq_device;
extern const device_t piix_old_device;
extern const device_t piix_rev02_device;
extern const device_t piix3_device;

View File

@@ -2410,6 +2410,7 @@ machine_amstrad_init(const machine_t *model, int type)
if (mouse_type == MOUSE_TYPE_INTERNAL) {
/* Tell mouse driver about our internal mouse. */
mouse_reset();
mouse_set_buttons(2);
mouse_set_poll(ms_poll, ams);
}

View File

@@ -265,7 +265,7 @@ machine_at_mb500n_init(const machine_t *model)
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&keyboard_ps2_pci_device);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&piix_no_mirq_device);
device_add(&fdc37c665_device);
device_add(&intel_flash_bxt_device);

View File

@@ -287,8 +287,8 @@ machine_at_fmb_init(const machine_t *model)
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 3, 2, 1);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&piix_no_mirq_device);
device_add(&keyboard_at_ami_device);
device_add(&w83787f_device);
device_add(&intel_flash_bxt_device);

View File

@@ -42,6 +42,7 @@
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/keyboard.h>
#include <86box/chipset.h>
#include <86box/sio.h>
@@ -92,5 +93,8 @@ machine_v86p_init(const machine_t *model)
if (gfxcard == VID_INTERNAL)
device_add(&f82c425_video_device);
if (hdc_current <= 1)
device_add(&st506_xt_victor_v86p_device);
return ret;
}

View File

@@ -8,7 +8,7 @@
*
* Emulation of the Olivetti XT-compatible machines.
*
*
* - Supports MM58174 real-time clock emulation
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -69,6 +69,28 @@
#define CGA_RGB 0
#define CGA_COMPOSITE 1
enum MM58174_ADDR {
/* Registers */
MM58174_TEST, /* TEST register, write only */
MM58174_TENTHS, /* Tenths of second, read only */
MM58174_SECOND1, /* Units of seconds, read only */
MM58174_SECOND10, /* Tens of seconds, read only */
MM58174_MINUTE1,
MM58174_MINUTE10,
MM58174_HOUR1,
MM58174_HOUR10,
MM58174_DAY1,
MM58174_DAY10,
MM58174_WEEKDAY,
MM58174_MONTH1,
MM58174_MONTH10,
MM58174_LEAPYEAR, /* Leap year status, write only */
MM58174_RESET, /* RESET register, write only */
MM58174_IRQ /* Interrupt register, read / write */
};
static struct tm intclk;
typedef struct {
/* Keyboard stuff. */
int wantirq;
@@ -120,6 +142,170 @@ m24_log(const char *fmt, ...)
# define m24_log(fmt, ...)
#endif
/* Set the chip time. */
static void
mm58174_time_set(uint8_t *regs, struct tm *tm)
{
regs[MM58174_SECOND1] = (tm->tm_sec % 10);
regs[MM58174_SECOND10] = (tm->tm_sec / 10);
regs[MM58174_MINUTE1] = (tm->tm_min % 10);
regs[MM58174_MINUTE10] = (tm->tm_min / 10);
regs[MM58174_HOUR1] = (tm->tm_hour % 10);
regs[MM58174_HOUR10] = (tm->tm_hour / 10);
regs[MM58174_WEEKDAY] = (tm->tm_wday + 1);
regs[MM58174_DAY1] = (tm->tm_mday % 10);
regs[MM58174_DAY10] = (tm->tm_mday / 10);
regs[MM58174_MONTH1] = ((tm->tm_mon + 1) % 10);
regs[MM58174_MONTH10] = ((tm->tm_mon + 1) / 10);
/* MM87174 does not store the year, M24 uses the IRQ register to count 8 years from leap year */
regs[MM58174_IRQ] = ((tm->tm_year + 1900) % 8);
regs[MM58174_LEAPYEAR] = 8 >> ((regs[MM58174_IRQ] & 0x07) & 0x03);
}
/* Get the chip time. */
#define nibbles(a) (regs[(a##1)] + 10 * regs[(a##10)])
static void
mm58174_time_get(uint8_t *regs, struct tm *tm)
{
tm->tm_sec = nibbles(MM58174_SECOND);
tm->tm_min = nibbles(MM58174_MINUTE);
tm->tm_hour = nibbles(MM58174_HOUR);
tm->tm_wday = (regs[MM58174_WEEKDAY] - 1);
tm->tm_mday = nibbles(MM58174_DAY);
tm->tm_mon = (nibbles(MM58174_MONTH) - 1);
/* MM87174AN does not store the year */
tm->tm_year = (1984 + (regs[MM58174_IRQ] & 0x07) - 1900);
}
/* One more second has passed, update the internal clock. */
static void
mm58174_recalc()
{
/* Ping the internal clock. */
if (++intclk.tm_sec == 60) {
intclk.tm_sec = 0;
if (++intclk.tm_min == 60) {
intclk.tm_min = 0;
if (++intclk.tm_hour == 24) {
intclk.tm_hour = 0;
if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon, intclk.tm_year) + 1)) {
intclk.tm_mday = 1;
if (++intclk.tm_mon == 13) {
intclk.tm_mon = 1;
intclk.tm_year++;
}
}
}
}
}
}
/* This is called every second through the NVR/RTC hook. */
static void
mm58174_tick(nvr_t *nvr)
{
mm58174_recalc();
mm58174_time_set(nvr->regs, &intclk);
}
static void
mm58174_start(nvr_t *nvr)
{
struct tm tm;
/* Initialize the internal and chip times. */
if (time_sync & TIME_SYNC_ENABLED) {
/* Use the internal clock's time. */
nvr_time_get(&tm);
mm58174_time_set(nvr->regs, &tm);
} else {
/* Set the internal clock from the chip time. */
mm58174_time_get(nvr->regs, &tm);
nvr_time_set(&tm);
}
mm58174_time_get(nvr->regs, &intclk);
}
/* Write to one of the chip registers. */
static void
mm58174_write(uint16_t addr, uint8_t val, void *priv)
{
nvr_t *nvr = (nvr_t *) priv;
addr &= 0x0f;
val &= 0x0f;
/* Update non-read-only changed values if not synchronizing time to host */
if ((addr != MM58174_TENTHS) && (addr != MM58174_SECOND1) && (addr != MM58174_SECOND10))
if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED))
nvr_dosave = 1;
if ((addr == MM58174_RESET) && (val & 0x01)) {
/* When timer starts, MM58174 sets seconds and tenths of second to 0 */
nvr->regs[MM58174_TENTHS] = 0;
if (!(time_sync & TIME_SYNC_ENABLED)) {
/* Only set seconds to 0 if not synchronizing time to host clock */
nvr->regs[MM58174_SECOND1] = 0;
nvr->regs[MM58174_SECOND10] = 0;
}
}
/* Store the new value */
nvr->regs[addr] = val;
/* Update internal clock with MM58174 time */
mm58174_time_get(nvr->regs, &intclk);
}
/* Read from one of the chip registers. */
static uint8_t
mm58174_read(uint16_t addr, void *priv)
{
nvr_t *nvr = (nvr_t *) priv;
addr &= 0x0f;
/* Set IRQ control bit to 0 upon read */
if (addr == 0x0f)
nvr->regs[addr] &= 0x07;
/* Grab and return the desired value */
return (nvr->regs[addr]);
}
/* Reset the MM58174 to a default state. */
static void
mm58174_reset(nvr_t *nvr)
{
/* Clear the NVRAM. */
memset(nvr->regs, 0xff, nvr->size);
/* Reset the RTC registers. */
memset(nvr->regs, 0x00, 16);
nvr->regs[MM58174_WEEKDAY] = 0x01;
nvr->regs[MM58174_DAY1] = 0x01;
nvr->regs[MM58174_MONTH1] = 0x01;
}
static void
mm58174_init(nvr_t *nvr, int size)
{
/* This is machine specific. */
nvr->size = size;
nvr->irq = -1;
/* Set up any local handlers here. */
nvr->reset = mm58174_reset;
nvr->start = mm58174_start;
nvr->tick = mm58174_tick;
/* Initialize the actual NVR. */
nvr_init(nvr);
io_sethandler(0x0070, 16,
mm58174_read, NULL, NULL, mm58174_write, NULL, NULL, nvr);
}
static void
m24_kbd_poll(void *priv)
{
@@ -426,6 +612,7 @@ m24_kbd_init(m24_kbd_t *kbd)
/* Tell mouse driver about our internal mouse. */
mouse_reset();
mouse_set_buttons(2);
mouse_set_poll(ms_poll, kbd);
keyboard_set_table(scancode_xt);
@@ -667,7 +854,7 @@ m24_read(uint16_t port, void *priv)
ret |= 0x1;
break;
case 256:
ret |= 0x2 | 0x80;
ret |= 0x2;
break;
case 384:
ret |= 0x1 | 0x2 | 0x80;
@@ -676,10 +863,12 @@ m24_read(uint16_t port, void *priv)
ret |= 0x8;
break;
case 640:
default:
ret |= 0x1 | 0x8 | 0x80;
break;
default:
break;
}
break;
/*
* port 67:
* DIPSW-1 on mainboard (off=present=1)
@@ -721,6 +910,8 @@ m24_read(uint16_t port, void *priv)
/* Switch 2 - Set fast startup */
ret |= 0x2;
break;
}
return (ret);
@@ -731,6 +922,7 @@ machine_xt_m24_init(const machine_t *model)
{
int ret;
m24_kbd_t *m24_kbd;
nvr_t *nvr;
ret = bios_load_interleaved("roms/machines/m24/olivetti_m24_bios_version_1.44_low_even.bin",
"roms/machines/m24/olivetti_m24_bios_version_1.44_high_odd.bin",
@@ -751,13 +943,18 @@ machine_xt_m24_init(const machine_t *model)
/* Address 66-67 = mainboard dip-switch settings */
io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL);
/* FIXME: make sure this is correct?? */
device_add(&at_nvr_device);
standalone_gameport_type = &gameport_device;
nmi_init();
/* Allocate an NVR for this machine. */
nvr = (nvr_t *) malloc(sizeof(nvr_t));
if (nvr == NULL)
return (0);
memset(nvr, 0x00, sizeof(nvr_t));
mm58174_init(nvr, model->nvrmask + 1);
video_reset(gfxcard);
if (gfxcard == VID_INTERNAL)

View File

@@ -103,6 +103,7 @@
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/gameport.h>
#include <86box/hdc.h>
#include <86box/video.h>
#include <86box/plat.h>
#include <86box/machine.h>
@@ -959,6 +960,9 @@ machine_xt_t1200_init(const machine_t *model)
if (gfxcard == VID_INTERNAL)
device_add(&t1200_video_device);
if (hdc_current <= 1)
device_add(&st506_xt_victor_v86p_device);
return ret;
}

View File

@@ -2066,7 +2066,7 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_PC,
.flags = MACHINE_VIDEO,
.flags = MACHINE_VIDEO | MACHINE_MFM,
.ram = {
.min = 512,
.max = 1024,
@@ -2102,7 +2102,7 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_PC,
.flags = MACHINE_VIDEO,
.flags = MACHINE_VIDEO | MACHINE_MFM,
.ram = {
.min = 1024,
.max = 2048,
@@ -8263,7 +8263,7 @@ const machine_t machines[] = {
.min_multi = 1.5,
.max_multi = 3.0
},
.bus_flags = MACHINE_PS2_PCI,
.bus_flags = MACHINE_PCI,
.flags = MACHINE_IDE_DUAL,
.ram = {
.min = 8192,

View File

@@ -1247,29 +1247,31 @@ const device_t piix4_nvr_device = {
};
const device_t ps_no_nmi_nvr_device = {
"PS/1 or PS/2 NVRAM (No NMI)",
"ps1_nvr",
DEVICE_PS2,
10,
nvr_at_init,
nvr_at_close,
nvr_at_reset,
{ NULL },
nvr_at_speed_changed,
NULL
.name = "PS/1 or PS/2 NVRAM (No NMI)",
.internal_name = "ps1_nvr",
.flags = DEVICE_PS2,
.local = 0x10 | 2,
.init = nvr_at_init,
.close = nvr_at_close,
.reset = nvr_at_reset,
{ .available = NULL },
.speed_changed = nvr_at_speed_changed,
.force_redraw = NULL,
.config = NULL
};
const device_t amstrad_no_nmi_nvr_device = {
"Amstrad NVRAM (No NMI)",
"amstrad_nvr",
DEVICE_ISA | DEVICE_AT,
11,
nvr_at_init,
nvr_at_close,
nvr_at_reset,
{ NULL },
nvr_at_speed_changed,
NULL
.name = "Amstrad NVRAM (No NMI)",
.internal_name = "amstrad_nvr",
.flags = DEVICE_ISA | DEVICE_AT,
.local = 0x10 | 3,
.init = nvr_at_init,
.close = nvr_at_close,
.reset = nvr_at_reset,
{ .available = NULL },
.speed_changed = nvr_at_speed_changed,
.force_redraw = NULL,
.config = NULL
};
const device_t ami_1992_nvr_device = {

View File

@@ -1620,7 +1620,18 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
if (send_keyboard_input && !(kbd_req_capture && !mouse_capture && !video_fullscreen))
{
// Windows keys in Qt have one-to-one mapping.
if (event->key() == Qt::Key_Super_L || event->key() == Qt::Key_Super_R) {
if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) {
if ((keyboard_recv(0x1D) || keyboard_recv(0x11D))) {
keyboard_input(1, 0x46);
} else {
keyboard_input(0, 0xE1);
keyboard_input(0, 0x1D);
keyboard_input(0, 0x45);
keyboard_input(0, 0xE1);
keyboard_input(1, 0x1D);
keyboard_input(1, 0x45);
}
} else if (event->key() == Qt::Key_Super_L || event->key() == Qt::Key_Super_R) {
keyboard_input(1, event->key() == Qt::Key_Super_L ? 0x15B : 0x15C);
} else
#ifdef Q_OS_MACOS
@@ -1637,6 +1648,12 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
if (keyboard_ismsexit()) {
plat_mouse_capture(0);
}
if ((video_fullscreen > 0) && (keyboard_recv(0x1D) || keyboard_recv(0x11D))) {
if (keyboard_recv(0x57)) ui->actionTake_screenshot->trigger();
else if (keyboard_recv(0x58)) pc_send_cad();
}
event->accept();
}
@@ -1651,6 +1668,11 @@ void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index)
void MainWindow::keyReleaseEvent(QKeyEvent* event)
{
if (event->key() == Qt::Key_Pause) {
if (keyboard_recv(0x38) && keyboard_recv(0x138)) {
plat_pause(dopause ^ 1);
}
}
if (!send_keyboard_input)
return;

View File

@@ -19,13 +19,15 @@
* Copyright 2021-2022 Teemu Korhonen
*/
#include "qt_mediamenu.hpp"
#include "qt_progsettings.hpp"
#include "qt_machinestatus.hpp"
#include <QMenu>
#include <QFileDialog>
#include <QMessageBox>
#include <QStringBuilder>
#include <QApplication>
#include <QStyle>
extern "C" {
#include <86box/86box.h>
@@ -123,10 +125,10 @@ void MediaMenu::refresh(QMenu *parentMenu) {
MachineStatus::iterateCDROM([this, parentMenu](int i) {
auto* menu = parentMenu->addMenu("");
cdromMutePos = menu->children().count();
menu->addAction(tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true);
menu->addAction(QApplication::style()->standardIcon(QStyle::SP_MediaVolumeMuted), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true);
menu->addSeparator();
menu->addAction(tr("&Image..."), [this, i]() { cdromMount(i, 0); })->setCheckable(false);
menu->addAction(tr("&Folder..."), [this, i]() { cdromMount(i, 1); })->setCheckable(false);
menu->addAction(ProgSettings::loadIcon("/cdrom.ico"), tr("&Image..."), [this, i]() { cdromMount(i, 0); })->setCheckable(false);
menu->addAction(QApplication::style()->standardIcon(QStyle::SP_DirIcon), tr("&Folder..."), [this, i]() { cdromMount(i, 1); })->setCheckable(false);
menu->addSeparator();
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
cdromImageHistoryPos[slot] = menu->children().count();
@@ -478,8 +480,9 @@ void MediaMenu::cdromReload(int index, int slot) {
void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) {
QMenu* menu;
QAction* imageHistoryUpdatePos;
QString image_path;
QObjectList children;
QFileInfo fi;
QIcon menu_icon;
switch (type) {
case ui::MediaType::Optical:
@@ -488,7 +491,9 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) {
menu = cdromMenus[index];
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction*>(children[cdromImageHistoryPos[slot]]);
image_path = mhm.getImageForSlot(index, slot, type);
fi.setFile(mhm.getImageForSlot(index, slot, type));
menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico");
imageHistoryUpdatePos->setIcon(menu_icon);
break;
case ui::MediaType::Floppy:
if (!floppyMenus.contains(index))
@@ -496,15 +501,15 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) {
menu = floppyMenus[index];
children = menu->children();
imageHistoryUpdatePos = dynamic_cast<QAction*>(children[floppyImageHistoryPos[slot]]);
image_path = mhm.getImageForSlot(index, slot, type);
fi.setFile(mhm.getImageForSlot(index, slot, type));
break;
default:
pclog("History not yet implemented for media type %s\n", qPrintable(mhm.mediaTypeToString(type)));
return;
}
QFileInfo fi(image_path);
imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData()));
QString menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData();
imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData()));
imageHistoryUpdatePos->setVisible(!fi.fileName().isEmpty());
}
@@ -527,7 +532,10 @@ void MediaMenu::cdromUpdateMenu(int i) {
auto* imageMenu = dynamic_cast<QAction*>(childs[cdromImagePos]);
imageMenu->setEnabled(!name.isEmpty());
imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData()));
QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData();
auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico");
imageMenu->setIcon(menu_icon);
imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), menu_item_name.toUtf8().constData()));
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) {
updateImageHistory(i, slot, ui::MediaType::Optical);

View File

@@ -166,7 +166,7 @@ int ignoreNextMouseEvent = 1;
void
RendererStack::mouseReleaseEvent(QMouseEvent *event)
{
if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1) && mouse_get_buttons() != 0) {
if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture && (isMouseDown & 1) && (mouse_get_buttons() != 0)) {
plat_mouse_capture(1);
this->setCursor(Qt::BlankCursor);
if (!ignoreNextMouseEvent)
@@ -174,7 +174,7 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event)
isMouseDown &= ~1;
return;
}
if (mouse_capture && event->button() == Qt::MiddleButton && mouse_get_buttons() < 3) {
if (mouse_capture && (event->button() == Qt::MiddleButton) && (mouse_get_buttons() < 3)) {
plat_mouse_capture(0);
this->setCursor(Qt::ArrowCursor);
isMouseDown &= ~1;

View File

@@ -349,7 +349,11 @@ scsi_cdrom_init(scsi_cdrom_t *dev)
dev->sense[0] = 0xf0;
dev->sense[7] = 10;
#ifdef POSSIBLE_EARLY_ATAPI
dev->status = READY_STAT | DSC_STAT;
#else
dev->status = 0;
#endif
dev->pos = 0;
dev->packet_status = PHASE_NONE;
scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0;
@@ -685,6 +689,7 @@ scsi_cdrom_command_complete(scsi_cdrom_t *dev)
ui_sb_update_icon(SB_CDROM | dev->id, 0);
dev->packet_status = PHASE_COMPLETE;
scsi_cdrom_command_common(dev);
dev->phase = 3;
}
static void
@@ -692,6 +697,7 @@ scsi_cdrom_command_read(scsi_cdrom_t *dev)
{
dev->packet_status = PHASE_DATA_IN;
scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1;
}
static void
@@ -706,6 +712,7 @@ scsi_cdrom_command_write(scsi_cdrom_t *dev)
{
dev->packet_status = PHASE_DATA_OUT;
scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1;
}
static void
@@ -1352,8 +1359,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
int toc_format, block_desc = 0;
int ret, format = 0;
int real_pos, track = 0;
#ifdef USE_86BOX_CD
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
#endif
int32_t blen = 0, *BufLen;
uint8_t *b;
uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM };
@@ -1371,12 +1380,14 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
dev->packet_len = 0;
dev->request_pos = 0;
#ifdef USE_86BOX_CD
device_identify[7] = dev->id + 0x30;
device_identify_ex[7] = dev->id + 0x30;
device_identify_ex[10] = EMU_VERSION_EX[0];
device_identify_ex[12] = EMU_VERSION_EX[2];
device_identify_ex[13] = EMU_VERSION_EX[3];
#endif
memcpy(dev->current_cdb, cdb, 12);
@@ -2301,16 +2312,25 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (dev->drv->bus_type == CDROM_BUS_SCSI)
ide_padstr8(dev->buffer + idx, 8, "TOSHIBA"); /* Vendor */
else
#ifdef USE_86BOX_CD
ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */
#else
ide_padstr8(dev->buffer + idx, 8, "HITACHI"); /* Vendor */
#endif
idx += 8;
if (dev->drv->bus_type == CDROM_BUS_SCSI)
ide_padstr8(dev->buffer + idx, 40, "XM6201TASUN32XCD1103"); /* Product */
else
#ifdef USE_86BOX_CD
ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */
#else
ide_padstr8(dev->buffer + idx, 40, "CDR-8130"); /* Product */
#endif
idx += 40;
ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */
idx += 20;
break;
default:
scsi_cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]);
scsi_cdrom_invalid_field(dev);
@@ -2344,9 +2364,15 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
ide_padstr8(dev->buffer + 16, 16, "XM6201TASUN32XCD"); /* Product */
ide_padstr8(dev->buffer + 32, 4, "1103"); /* Revision */
} else {
#ifdef USE_86BOX_CD
ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */
ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */
ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */
#else
ide_padstr8(dev->buffer + 8, 8, "HITACHI"); /* Vendor */
ide_padstr8(dev->buffer + 16, 16, "CDR-8130"); /* Product */
ide_padstr8(dev->buffer + 32, 4, "0020"); /* Revision */
#endif
}
idx = 36;
@@ -2615,7 +2641,7 @@ scsi_cdrom_get_timings(int ide_has_dma, int type)
static void
scsi_cdrom_identify(ide_t *ide, int ide_has_dma)
{
#if 0
#ifdef USE_86BOX_CD
scsi_cdrom_t *dev;
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
@@ -2627,12 +2653,17 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma)
ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
#if 0
#ifdef USE_86BOX_CD
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
#else
#ifdef USE_NEC_CD
ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */
ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */
#else
ide_padstr((char *) (ide->buffer + 23), "0020 ", 8); /* Firmware */
ide_padstr((char *) (ide->buffer + 27), "HITACHI CDR-8130 ", 40); /* Model */
#endif
#endif
ide->buffer[49] = 0x200; /* LBA supported */
ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */

View File

@@ -534,7 +534,7 @@ MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o
CPUOBJ := $(DYNARECOBJ) \
$(CGTOBJ) \
cpu.o cpu_table.o fpu.o x86.o \
808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \
8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \
x86seg.o x87.o x87_timings.o
CHIPSETOBJ := 82c100.o acc2168.o \

View File

@@ -2136,12 +2136,9 @@ recalc_next_free_id(HWND hdlg)
enable_add = enable_add || (next_free_id >= 0);
enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || (c_ide < IDE_NUM) || (c_ide < ATAPI_NUM) || (c_scsi < SCSI_NUM));
enable_add = enable_add && !bus_full(&mfm_tracking, 2);
enable_add = enable_add && !bus_full(&esdi_tracking, 2);
enable_add = enable_add && !bus_full(&xta_tracking, 2);
enable_add = enable_add && !bus_full(&ide_tracking, IDE_CHAN_MAX);
for (i = 0; i < 2; i++)
enable_add = enable_add && !bus_full(&(scsi_tracking[i]), 8);
enable_add = enable_add && (!bus_full(&mfm_tracking, 2) || !bus_full(&esdi_tracking, 2) || !bus_full(&xta_tracking, 2) || !bus_full(&ide_tracking, IDE_CHAN_MAX * IDE_BUS_MAX) ||
!bus_full(&(scsi_tracking[0]), 8) || !bus_full(&(scsi_tracking[1]), 8) || !bus_full(&(scsi_tracking[2]), 8) || !bus_full(&(scsi_tracking[3]), 8) ||
!bus_full(&(scsi_tracking[4]), 8) || !bus_full(&(scsi_tracking[5]), 8) || !bus_full(&(scsi_tracking[6]), 8) || !bus_full(&(scsi_tracking[7]), 8));
settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD_NEW, enable_add);
settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD, enable_add);