From cc0cdfaa10f5fa6212c85794261c09847456d460 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 11 Dec 2020 16:54:16 -0800 Subject: [PATCH 01/24] Fix crash on linux aarch64 --- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 26 +++++++++++++++++++---- BasiliskII/src/CrossPlatform/vm_alloc.h | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index 19d109e92..176060c07 100755 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -83,6 +83,10 @@ typedef unsigned long vm_uintptr_t; #define MAP_ANONYMOUS 0 #endif +/* NOTE: on linux MAP_32BIT is only implemented on AMD64 + it is a null op on all other architectures + thus the MAP_BASE setting below is the only thing + ensuring low addresses on aarch64 for example */ #define MAP_EXTRA_FLAGS (MAP_32BIT) #ifdef HAVE_MMAP_VM @@ -91,6 +95,16 @@ typedef unsigned long vm_uintptr_t; don't get addresses above when the program is run on AMD64. NOTE: this is empirically determined on Linux/x86. */ #define MAP_BASE 0x10000000 +#elif DIRECT_ADDRESSING +/* linux does not implement any useful fallback behavior + such as allocating the next available address + and the first 4k-64k of address space is marked unavailable + for security reasons (see https://wiki.debian.org/mmap_min_addr) + so we must start requesting after the first page + or we get a high 64bit address that will crash direct addressing + + leaving NULL unmapped is a good idea anyway for debugging reasons */ +#define MAP_BASE 0x00010000 #else #define MAP_BASE 0x00000000 #endif @@ -270,11 +284,15 @@ void * vm_acquire(size_t size, int options) if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED) return VM_MAP_FAILED; -#if USE_JIT - // Sanity checks for 64-bit platforms - if (sizeof(void *) == 8 && (options & VM_MAP_32BIT) && !((char *)addr <= (char *)0xffffffff)) - return VM_MAP_FAILED; + +#if DIRECT_ADDRESSING + // If MAP_32BIT and MAP_BASE fail to ensure + // a 32-bit address crash now instead of later. + // FIXME: make everything 64-bit clean and tear this all out. + if(sizeof(void *) > 4 && (options & VM_MAP_32BIT)) + assert((size_t)addr<0xffffffffL); #endif + next_address = (char *)addr + size; #elif defined(HAVE_WIN32_VM) int alloc_type = MEM_RESERVE | MEM_COMMIT; diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.h b/BasiliskII/src/CrossPlatform/vm_alloc.h index bc5aba974..41dd949df 100644 --- a/BasiliskII/src/CrossPlatform/vm_alloc.h +++ b/BasiliskII/src/CrossPlatform/vm_alloc.h @@ -36,6 +36,8 @@ extern "C" { } #endif +#include + /* Return value of `vm_acquire' in case of an error. */ #ifdef HAVE_MACH_VM #define VM_MAP_FAILED ((void *)-1) From c3c8e8d34253677e40fdb8ce35f557f608b9ed88 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 11 Dec 2020 17:26:27 -0800 Subject: [PATCH 02/24] Update config.guess and config.sub --- BasiliskII/src/Unix/config.guess | 419 ++++++++++--------- BasiliskII/src/Unix/config.sub | 671 +++++++++++++++++-------------- 2 files changed, 608 insertions(+), 482 deletions(-) diff --git a/BasiliskII/src/Unix/config.guess b/BasiliskII/src/Unix/config.guess index 79d1317f5..dc0a6b299 100755 --- a/BasiliskII/src/Unix/config.guess +++ b/BasiliskII/src/Unix/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2019 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2019-03-04' +timestamp='2021-05-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,12 +27,12 @@ timestamp='2019-03-04' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2019 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -99,9 +99,11 @@ tmp= trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039 - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } @@ -129,16 +131,14 @@ if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown +UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown +UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown +UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown -case "$UNAME_SYSTEM" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" @@ -147,24 +147,36 @@ Linux|GNU|GNU/*) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -176,27 +188,27 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - "/sbin/$sysctl" 2>/dev/null || \ - "/usr/sbin/$sysctl" 2>/dev/null || \ - echo unknown)` - case "$UNAME_MACHINE_ARCH" in + UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)) + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') + endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; @@ -217,10 +229,10 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ;; esac # Determine ABI tags. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release @@ -228,12 +240,12 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "$UNAME_VERSION" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: @@ -242,15 +254,19 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/SecBSD.//') + echo "$UNAME_MACHINE_ARCH"-unknown-secbsd"$UNAME_RELEASE" + exit ;; *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) @@ -262,6 +278,9 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; @@ -271,27 +290,32 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in + ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) + case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") @@ -328,11 +352,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; + echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" + exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; @@ -362,7 +383,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then + if test "$( (/bin/universe) 2>/dev/null)" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd @@ -375,17 +396,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in + case $(/usr/bin/uname -p) in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" @@ -396,7 +417,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -404,30 +425,30 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in SUN_ARCH=x86_64 fi fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case $(/usr/bin/arch -k) in Series*|S4*) - UNAME_RELEASE=`uname -v` + UNAME_RELEASE=$(uname -v) ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in + case $(/bin/arch) in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; @@ -507,8 +528,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && + dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && + SYSTEM_NAME=$("$dummy" "$dummyarg") && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; @@ -535,11 +556,11 @@ EOF exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + UNAME_PROCESSOR=$(/usr/bin/uname -p) + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then echo m88k-dg-dgux"$UNAME_RELEASE" else @@ -563,17 +584,17 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/oslevel ; then + IBM_REV=$(/usr/bin/oslevel) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -593,7 +614,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") then echo "$SYSTEM_NAME" else @@ -606,15 +627,15 @@ EOF fi exit ;; *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + if test -x /usr/bin/lslpp ; then + IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -642,26 +663,26 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` - case "$UNAME_MACHINE" in + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "$sc_cpu_version" in + if test -x /usr/bin/getconf; then + sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) + sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) + case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "$sc_kernel_bits" in + case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "$HP_ARCH" = "" ]; then + if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" @@ -696,11 +717,11 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ "$HP_ARCH" = hppa2.0w ] + if test "$HP_ARCH" = hppa2.0w then set_cc_for_build @@ -724,7 +745,7 @@ EOF echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) @@ -754,7 +775,7 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; @@ -774,7 +795,7 @@ EOF echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then + if test -x /usr/sbin/sysversion ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 @@ -823,14 +844,14 @@ EOF echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -843,25 +864,25 @@ EOF echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; arm:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi else - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf fi exit ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case "$UNAME_PROCESSOR" in + UNAME_PROCESSOR=$(/usr/bin/uname -p) + case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin @@ -879,7 +900,7 @@ EOF echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case "$UNAME_MACHINE" in + case $UNAME_MACHINE in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; @@ -897,15 +918,15 @@ EOF echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; *:GNU:*:*) # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" exit ;; *:Minix:*:*) echo "$UNAME_MACHINE"-unknown-minix @@ -918,7 +939,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -931,7 +952,7 @@ EOF if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; - arc:Linux:*:* | arceb:Linux:*:*) + arc:Linux:*:* | arceb:Linux:*:* | arc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) @@ -977,6 +998,9 @@ EOF k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; @@ -1027,7 +1051,7 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) @@ -1047,7 +1071,7 @@ EOF exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; @@ -1065,7 +1089,7 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) @@ -1087,7 +1111,17 @@ EOF echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1127,7 +1161,7 @@ EOF echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else @@ -1136,7 +1170,7 @@ EOF exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in + case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; @@ -1145,10 +1179,10 @@ EOF exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 @@ -1198,7 +1232,7 @@ EOF 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1209,7 +1243,7 @@ EOF NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1242,7 +1276,7 @@ EOF exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=$( (uname -p) 2>/dev/null) echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv @@ -1276,7 +1310,7 @@ EOF echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then + if test -d /usr/nec; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" @@ -1324,44 +1358,48 @@ EOF *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=$(uname -p) + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc @@ -1399,10 +1437,9 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - # shellcheck disable=SC2154 - if test "$cputype" = 386; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else + elif test "x${cputype-}" != x; then UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 @@ -1429,11 +1466,11 @@ EOF echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "$UNAME_MACHINE" in + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + case $UNAME_MACHINE in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1442,13 +1479,13 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; - i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros + *:AROS:*:*) + echo "$UNAME_MACHINE"-unknown-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx @@ -1468,6 +1505,14 @@ cat > "$dummy.c" < #include #endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif main () { #if defined (sony) @@ -1492,7 +1537,7 @@ main () #define __ARCHITECTURE__ "m68k" #endif int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else @@ -1554,19 +1599,24 @@ main () #else printf ("vax-dec-bsd\n"); exit (0); #endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif +#endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#include -#if defined(_SIZE_T_) /* >= ULTRIX4 */ - printf ("mips-dec-ultrix4\n"); exit (0); +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else -#if defined(ULTRIX3) || defined(ultrix3) || defined(SIGLOST) - printf ("mips-dec-ultrix3\n"); exit (0); -#endif + printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif @@ -1579,7 +1629,7 @@ main () } EOF -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. @@ -1587,7 +1637,7 @@ test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 -case "$UNAME_MACHINE:$UNAME_SYSTEM" in +case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` +uname -m = $( (uname -m) 2>/dev/null || echo unknown) +uname -r = $( (uname -r) 2>/dev/null || echo unknown) +uname -s = $( (uname -s) 2>/dev/null || echo unknown) +uname -v = $( (uname -v) 2>/dev/null || echo unknown) -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) +/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +hostinfo = $( (hostinfo) 2>/dev/null) +/bin/universe = $( (/bin/universe) 2>/dev/null) +/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) +/bin/arch = $( (/bin/arch) 2>/dev/null) +/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) +/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 diff --git a/BasiliskII/src/Unix/config.sub b/BasiliskII/src/Unix/config.sub index 3b4c7624b..7384e9198 100755 --- a/BasiliskII/src/Unix/config.sub +++ b/BasiliskII/src/Unix/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2019 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2019-01-05' +timestamp='2021-04-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ timestamp='2019-01-05' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -50,7 +50,7 @@ timestamp='2019-01-05' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2019 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -124,28 +124,27 @@ case $1 in ;; *-*-*-*) basic_machine=$field1-$field2 - os=$field3-$field4 + basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ - | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ + nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 - os=$maybe_os + basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown - os=linux-android + basic_os=linux-android ;; *) basic_machine=$field1-$field2 - os=$field3 + basic_os=$field3 ;; esac ;; @@ -154,7 +153,7 @@ case $1 in case $field1-$field2 in decstation-3100) basic_machine=mips-dec - os= + basic_os= ;; *-*) # Second component is usually, but not always the OS @@ -162,7 +161,7 @@ case $1 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 - os=$field2 + basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ @@ -175,11 +174,11 @@ case $1 in | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 - os= + basic_os= ;; *) basic_machine=$field1 - os=$field2 + basic_os=$field2 ;; esac ;; @@ -191,450 +190,451 @@ case $1 in case $field1 in 386bsd) basic_machine=i386-pc - os=bsd + basic_os=bsd ;; a29khif) basic_machine=a29k-amd - os=udi + basic_os=udi ;; adobe68k) basic_machine=m68010-adobe - os=scout + basic_os=scout ;; alliant) basic_machine=fx80-alliant - os= + basic_os= ;; altos | altos3068) basic_machine=m68k-altos - os= + basic_os= ;; am29k) basic_machine=a29k-none - os=bsd + basic_os=bsd ;; amdahl) basic_machine=580-amdahl - os=sysv + basic_os=sysv ;; amiga) basic_machine=m68k-unknown - os= + basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown - os=amigaos + basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown - os=sysv4 + basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo - os=sysv + basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo - os=bsd + basic_os=bsd ;; aros) basic_machine=i386-pc - os=aros + basic_os=aros ;; aux) basic_machine=m68k-apple - os=aux + basic_os=aux ;; balance) basic_machine=ns32k-sequent - os=dynix + basic_os=dynix ;; blackfin) basic_machine=bfin-unknown - os=linux + basic_os=linux ;; cegcc) basic_machine=arm-unknown - os=cegcc + basic_os=cegcc ;; convex-c1) basic_machine=c1-convex - os=bsd + basic_os=bsd ;; convex-c2) basic_machine=c2-convex - os=bsd + basic_os=bsd ;; convex-c32) basic_machine=c32-convex - os=bsd + basic_os=bsd ;; convex-c34) basic_machine=c34-convex - os=bsd + basic_os=bsd ;; convex-c38) basic_machine=c38-convex - os=bsd + basic_os=bsd ;; cray) basic_machine=j90-cray - os=unicos + basic_os=unicos ;; crds | unos) basic_machine=m68k-crds - os= + basic_os= ;; da30) basic_machine=m68k-da30 - os= + basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec - os= + basic_os= ;; delta88) basic_machine=m88k-motorola - os=sysv3 + basic_os=sysv3 ;; dicos) basic_machine=i686-pc - os=dicos + basic_os=dicos ;; djgpp) basic_machine=i586-pc - os=msdosdjgpp + basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd - os=ebmon + basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson - os=ose + basic_os=ose ;; gmicro) basic_machine=tron-gmicro - os=sysv + basic_os=sysv ;; go32) basic_machine=i386-pc - os=go32 + basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi - os=hms + basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi - os=xray + basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi - os=hms + basic_os=hms ;; harris) basic_machine=m88k-harris - os=sysv3 + basic_os=sysv3 ;; - hp300) + hp300 | hp300hpux) basic_machine=m68k-hp + basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp - os=bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=hpux + basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp - os=osf + basic_os=osf ;; hppro) basic_machine=hppa1.1-hp - os=proelf + basic_os=proelf ;; i386mach) basic_machine=i386-mach - os=mach - ;; - vsta) - basic_machine=i386-pc - os=vsta + basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi - os=sysv + basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown - os=linux + basic_os=linux ;; magnum | m3230) basic_machine=mips-mips - os=sysv + basic_os=sysv ;; merlin) basic_machine=ns32k-utek - os=sysv + basic_os=sysv ;; mingw64) basic_machine=x86_64-pc - os=mingw64 + basic_os=mingw64 ;; mingw32) basic_machine=i686-pc - os=mingw32 + basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown - os=mingw32ce + basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k - os=coff + basic_os=coff ;; morphos) basic_machine=powerpc-unknown - os=morphos + basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown - os=moxiebox + basic_os=moxiebox ;; msdos) basic_machine=i386-pc - os=msdos + basic_os=msdos ;; msys) basic_machine=i686-pc - os=msys + basic_os=msys ;; mvs) basic_machine=i370-ibm - os=mvs + basic_os=mvs ;; nacl) basic_machine=le32-unknown - os=nacl + basic_os=nacl ;; ncr3000) basic_machine=i486-ncr - os=sysv4 + basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc - os=netbsd + basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel - os=linux + basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony - os=newsos + basic_os=newsos ;; news1000) basic_machine=m68030-sony - os=newsos + basic_os=newsos ;; necv70) basic_machine=v70-nec - os=sysv + basic_os=sysv ;; nh3000) basic_machine=m68k-harris - os=cxux + basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris - os=cxux + basic_os=cxux ;; nindy960) basic_machine=i960-intel - os=nindy + basic_os=nindy ;; mon960) basic_machine=i960-intel - os=mon960 + basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq - os=nonstopux + basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm - os=os400 + basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson - os=ose + basic_os=ose ;; os68k) basic_machine=m68k-none - os=os68k + basic_os=os68k ;; paragon) basic_machine=i860-intel - os=osf + basic_os=osf ;; parisc) basic_machine=hppa-unknown - os=linux + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp ;; pw32) basic_machine=i586-unknown - os=pw32 + basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc - os=rdos + basic_os=rdos ;; rdos32) basic_machine=i386-pc - os=rdos + basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k - os=coff + basic_os=coff ;; sa29200) basic_machine=a29k-amd - os=udi + basic_os=udi ;; sei) basic_machine=mips-sei - os=seiux + basic_os=seiux ;; sequent) basic_machine=i386-sequent - os= + basic_os= ;; sps7) basic_machine=m68k-bull - os=sysv2 + basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem - os= + basic_os= ;; stratus) basic_machine=i860-stratus - os=sysv4 + basic_os=sysv4 ;; sun2) basic_machine=m68000-sun - os= + basic_os= ;; sun2os3) basic_machine=m68000-sun - os=sunos3 + basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun - os=sunos4 + basic_os=sunos4 ;; sun3) basic_machine=m68k-sun - os= + basic_os= ;; sun3os3) basic_machine=m68k-sun - os=sunos3 + basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun - os=sunos4 + basic_os=sunos4 ;; sun4) basic_machine=sparc-sun - os= + basic_os= ;; sun4os3) basic_machine=sparc-sun - os=sunos3 + basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun - os=sunos4 + basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun - os=solaris2 + basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun - os= + basic_os= ;; sv1) basic_machine=sv1-cray - os=unicos + basic_os=unicos ;; symmetry) basic_machine=i386-sequent - os=dynix + basic_os=dynix ;; t3e) basic_machine=alphaev5-cray - os=unicos + basic_os=unicos ;; t90) basic_machine=t90-cray - os=unicos + basic_os=unicos ;; toad1) basic_machine=pdp10-xkl - os=tops20 + basic_os=tops20 ;; tpf) basic_machine=s390x-ibm - os=tpf + basic_os=tpf ;; udi29k) basic_machine=a29k-amd - os=udi + basic_os=udi ;; ultra3) basic_machine=a29k-nyu - os=sym1 + basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec - os=none + basic_os=none ;; vaxv) basic_machine=vax-dec - os=sysv + basic_os=sysv ;; vms) basic_machine=vax-dec - os=vms + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta ;; vxworks960) basic_machine=i960-wrs - os=vxworks + basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs - os=vxworks + basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs - os=vxworks + basic_os=vxworks ;; xbox) basic_machine=i686-pc - os=mingw32 + basic_os=mingw32 ;; ymp) basic_machine=ymp-cray - os=unicos + basic_os=unicos ;; *) basic_machine=$1 - os= + basic_os= ;; esac ;; @@ -686,17 +686,17 @@ case $basic_machine in bluegene*) cpu=powerpc vendor=ibm - os=cnk + basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec - os=tops10 + basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec - os=tops20 + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) @@ -706,7 +706,7 @@ case $basic_machine in dpx2*) cpu=m68k vendor=bull - os=sysv3 + basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k @@ -715,7 +715,7 @@ case $basic_machine in elxsi) cpu=elxsi vendor=elxsi - os=${os:-bsd} + basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 @@ -728,7 +728,7 @@ case $basic_machine in h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi - os=hiuxwe2 + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 @@ -769,38 +769,38 @@ case $basic_machine in vendor=hp ;; i*86v32) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv32 + basic_os=sysv32 ;; i*86v4*) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv4 + basic_os=sysv4 ;; i*86v) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv + basic_os=sysv ;; i*86sol2) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=solaris2 + basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray - os=${os:-unicos} + basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi - case $os in + case $basic_os in irix*) ;; *) - os=irix4 + basic_os=irix4 ;; esac ;; @@ -811,24 +811,26 @@ case $basic_machine in *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari - os=mint + basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony - os=newsos + basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next - case $os in - nextstep* ) + case $basic_os in + openstep*) + ;; + nextstep*) ;; ns2*) - os=nextstep2 + basic_os=nextstep2 ;; *) - os=nextstep3 + basic_os=nextstep3 ;; esac ;; @@ -839,12 +841,12 @@ case $basic_machine in op50n-* | op60c-*) cpu=hppa1.1 vendor=oki - os=proelf + basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi - os=hiuxwe2 + basic_os=hiuxwe2 ;; pbd) cpu=sparc @@ -881,12 +883,12 @@ case $basic_machine in sde) cpu=mipsisa32 vendor=sde - os=${os:-elf} + basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs - os=vxworks + basic_os=vxworks ;; tower | tower-32) cpu=m68k @@ -903,7 +905,7 @@ case $basic_machine in w89k-*) cpu=hppa1.1 vendor=winbond - os=proelf + basic_os=proelf ;; none) cpu=none @@ -915,7 +917,7 @@ case $basic_machine in ;; leon-*|leon[3-9]-*) cpu=sparc - vendor=`echo "$basic_machine" | sed 's/-.*//'` + vendor=$(echo "$basic_machine" | sed 's/-.*//') ;; *-*) @@ -956,11 +958,11 @@ case $cpu-$vendor in # some cases the only manufacturer, in others, it is the most popular. craynv-unknown) vendor=cray - os=${os:-unicosmp} + basic_os=${basic_os:-unicosmp} ;; c90-unknown | c90-cray) vendor=cray - os=${os:-unicos} + basic_os=${Basic_os:-unicos} ;; fx80-unknown) vendor=alliant @@ -1004,7 +1006,7 @@ case $cpu-$vendor in dpx20-unknown | dpx20-bull) cpu=rs6000 vendor=bull - os=${os:-bosx} + basic_os=${basic_os:-bosx} ;; # Here we normalize CPU types irrespective of the vendor @@ -1013,7 +1015,7 @@ case $cpu-$vendor in ;; blackfin-*) cpu=bfin - os=linux + basic_os=linux ;; c54x-*) cpu=tic54x @@ -1026,7 +1028,7 @@ case $cpu-$vendor in ;; e500v[12]-*) cpu=powerpc - os=$os"spe" + basic_os=${basic_os}"spe" ;; mips3*-*) cpu=mips64 @@ -1036,7 +1038,7 @@ case $cpu-$vendor in ;; m68knommu-*) cpu=m68k - os=linux + basic_os=linux ;; m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) cpu=s12z @@ -1046,7 +1048,7 @@ case $cpu-$vendor in ;; parisc-*) cpu=hppa - os=linux + basic_os=linux ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 @@ -1082,7 +1084,7 @@ case $cpu-$vendor in cpu=mipsisa64sb1el ;; sh5e[lb]-*) - cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/') ;; spur-*) cpu=spur @@ -1100,13 +1102,16 @@ case $cpu-$vendor in cpu=x86_64 ;; xscale-* | xscalee[bl]-*) - cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + cpu=$(echo "$cpu" | sed 's/^xscale/arm/') + ;; + arm64-*) + cpu=aarch64 ;; # Recognize the canonical CPU Types that limit and/or modify the # company names they are paired with. cr16-*) - os=${os:-elf} + basic_os=${basic_os:-elf} ;; crisv32-* | etraxfs*-*) cpu=crisv32 @@ -1117,7 +1122,7 @@ case $cpu-$vendor in vendor=axis ;; crx-*) - os=${os:-elf} + basic_os=${basic_os:-elf} ;; neo-tandem) cpu=neo @@ -1139,16 +1144,12 @@ case $cpu-$vendor in cpu=nsx vendor=tandem ;; - s390-*) - cpu=s390 - vendor=ibm - ;; - s390x-*) - cpu=s390x - vendor=ibm + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony ;; tile*-*) - os=${os:-linux-gnu} + basic_os=${basic_os:-linux-gnu} ;; *) @@ -1164,13 +1165,13 @@ case $cpu-$vendor in | alphapca5[67] | alpha64pca5[67] \ | am33_2.0 \ | amdgcn \ - | arc | arceb \ - | arm | arm[lb]e | arme[lb] | armv* \ + | arc | arceb | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ | asmjs \ | ba \ | be32 | be64 \ - | bfin | bs2000 \ + | bfin | bpf | bs2000 \ | c[123]* | c30 | [cjt]90 | c4x \ | c8051 | clipper | craynv | csky | cydra \ | d10v | d30v | dlx | dsp16xx \ @@ -1184,6 +1185,7 @@ case $cpu-$vendor in | k1om \ | le32 | le64 \ | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ @@ -1202,9 +1204,13 @@ case $cpu-$vendor in | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r3 | mipsisa32r3el \ + | mipsisa32r5 | mipsisa32r5el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r3 | mipsisa64r3el \ + | mipsisa64r5 | mipsisa64r5el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ @@ -1228,8 +1234,9 @@ case $cpu-$vendor in | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ | pru \ | pyramid \ - | riscv | riscv32 | riscv64 \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ | score \ | sh | shl \ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ @@ -1239,13 +1246,15 @@ case $cpu-$vendor in | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ | spu \ | tahoe \ + | thumbv7* \ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ | tron \ | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ | visium \ - | w65 | wasm32 \ + | w65 \ + | wasm32 | wasm64 \ | we32k \ | x86 | x86_64 | xc16x | xgate | xps100 \ | xstormy16 | xtensa* \ @@ -1275,8 +1284,47 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x$os != x ] +if test x$basic_os != x then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') + ;; + os2-emx) + kernel=os2 + os=$(echo $basic_os | sed -e 's|os2-emx|emx|') + ;; + nto-qnx*) + kernel=nto + os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1530,6 +1503,7 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. +kernel= case $cpu-$vendor in score-*) os=elf @@ -1541,7 +1515,8 @@ case $cpu-$vendor in os=riscix1.2 ;; arm*-rebel) - os=linux + kernel=linux + os=gnu ;; arm*-semi) os=aout @@ -1707,84 +1682,178 @@ case $cpu-$vendor in os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) - case $os in - riscix*) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - sunos*) + *-sunos*) vendor=sun ;; - cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - beos*) + *-beos*) vendor=be ;; - hpux*) + *-hpux*) vendor=hp ;; - mpeix*) + *-mpeix*) vendor=hp ;; - hiux*) + *-hiux*) vendor=hitachi ;; - unos*) + *-unos*) vendor=crds ;; - dgux*) + *-dgux*) vendor=dg ;; - luna*) + *-luna*) vendor=omron ;; - genix*) + *-genix*) vendor=ns ;; - clix*) + *-clix*) vendor=intergraph ;; - mvs* | opened*) + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - os400*) + s390-* | s390x-*) vendor=ibm ;; - ptx*) + *-ptx*) vendor=sequent ;; - tpf*) + *-tpf*) vendor=ibm ;; - vxsim* | vxworks* | windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - aux*) + *-aux*) vendor=apple ;; - hms*) + *-hms*) vendor=hitachi ;; - mpw* | macos*) + *-mpw* | *-macos*) vendor=apple ;; - *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - vos*) + *-vos*) vendor=stratus ;; esac ;; esac -echo "$cpu-$vendor-$os" +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: From c86fa4cb54c8cd283111a0e913b07d865aade151 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 11 Dec 2020 18:02:12 -0800 Subject: [PATCH 03/24] Don't use linker script on x86_64, there is no need for it and it breaks flatpak builds --- .../BasiliskII.xcodeproj/project.pbxproj | 2 - BasiliskII/src/Unix/ldscripts/linux-x86_64.ld | 171 ------------------ 2 files changed, 173 deletions(-) delete mode 100644 BasiliskII/src/Unix/ldscripts/linux-x86_64.ld diff --git a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj index 9d6d46bc0..6c450db11 100644 --- a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj +++ b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj @@ -228,7 +228,6 @@ 7539E20C1F23B32A006B2DF2 /* freebsd-i386.ld */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "freebsd-i386.ld"; sourceTree = ""; }; 7539E20D1F23B32A006B2DF2 /* linux-i386.ld */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "linux-i386.ld"; sourceTree = ""; }; 7539E20E1F23B32A006B2DF2 /* linux-ppc.ld */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "linux-ppc.ld"; sourceTree = ""; }; - 7539E20F1F23B32A006B2DF2 /* linux-x86_64.ld */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "linux-x86_64.ld"; sourceTree = ""; }; 7539E2181F23B32A006B2DF2 /* egrep.m4 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = egrep.m4; sourceTree = ""; }; 7539E2191F23B32A006B2DF2 /* esd.m4 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = esd.m4; sourceTree = ""; }; 7539E21A1F23B32A006B2DF2 /* gettext.m4 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gettext.m4; sourceTree = ""; }; @@ -620,7 +619,6 @@ 7539E20C1F23B32A006B2DF2 /* freebsd-i386.ld */, 7539E20D1F23B32A006B2DF2 /* linux-i386.ld */, 7539E20E1F23B32A006B2DF2 /* linux-ppc.ld */, - 7539E20F1F23B32A006B2DF2 /* linux-x86_64.ld */, ); path = ldscripts; sourceTree = ""; diff --git a/BasiliskII/src/Unix/ldscripts/linux-x86_64.ld b/BasiliskII/src/Unix/ldscripts/linux-x86_64.ld deleted file mode 100644 index b824271ab..000000000 --- a/BasiliskII/src/Unix/ldscripts/linux-x86_64.ld +++ /dev/null @@ -1,171 +0,0 @@ -/* Default linker script, for normal executables */ -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(_start) -SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64"); -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x78048000 + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.init : { *(.rel.init) } - .rela.init : { *(.rela.init) } - .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } - .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } - .rel.fini : { *(.rel.fini) } - .rela.fini : { *(.rela.fini) } - .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } - .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } - .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } - .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } - .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } - .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } - .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } - .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } - .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0x90909090 - .plt : { *(.plt) } - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } =0x90909090 - .fini : - { - KEEP (*(.fini)) - } =0x90909090 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000); - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but - the linker would then create the section even if it turns out to - be empty, which isn't pretty. */ - . = ALIGN(64 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) } - .dynamic : { *(.dynamic) } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - .got : { *(.got.plt) *(.got) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(64 / 8); - } - . = ALIGN(64 / 8); - _end = .; - PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} From 046189db97ecf5de30794f74e027636cdb1f80f9 Mon Sep 17 00:00:00 2001 From: Seg Date: Wed, 30 Dec 2020 07:59:53 -0800 Subject: [PATCH 04/24] Merge Travis CI config from emaculation/macemu --- .travis.yml | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..2529b7120 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,61 @@ +language: cpp + +# Do not build branches of the form "pr/*". By prefixing pull requests coming +# from branches inside the repository with pr/, this avoids building both the +# branch push _and_ the pull request. +# Based on https://github.com/boostorg/hana/blob/master/.travis.yml +branches: + except: /pr\/.*/ + +jobs: + include: + - os: linux + arch: amd64 + dist: bionic + sudo: required + compiler: gcc + env: BADGE=amd64-linux-basiliskii + addons: + apt: + packages: + - libgtk2.0-dev + - libsdl2-dev + script: + - cd BasiliskII/src/Unix + - NO_CONFIGURE=1 ./autogen.sh + - ./configure --with-mon + - make + - os: linux + arch: arm64 + dist: bionic + sudo: required + compiler: gcc + env: BADGE=arm64-linux-basiliskii + addons: + apt: + packages: + - libgtk2.0-dev + - libsdl2-dev + script: + - cd BasiliskII/src/Unix + - NO_CONFIGURE=1 ./autogen.sh + - ./configure --with-mon + - make + - os: linux + arch: amd64 + dist: bionic + sudo: required + compiler: gcc + env: BADGE=amd64-linux-sheepshaver + addons: + apt: + packages: + - libgtk2.0-dev + - libsdl2-dev + script: + - cd SheepShaver + - make links + - cd src/Unix + - NO_CONFIGURE=1 ./autogen.sh + - ./configure --with-mon + - make From 19b636bd0dcf1f06e43e9fc97d03bb1926e56a19 Mon Sep 17 00:00:00 2001 From: Seg Date: Thu, 17 Jun 2021 17:10:10 -0700 Subject: [PATCH 05/24] Remove obsolete AC_HEADER_STDC check --- BasiliskII/src/Unix/configure.ac | 1 - BasiliskII/src/Unix/sysdeps.h | 4 - BasiliskII/src/Windows/config.h | 260 ------------------------------ BasiliskII/src/Windows/sysdeps.h | 4 - SheepShaver/src/Unix/configure.ac | 1 - SheepShaver/src/Unix/sysdeps.h | 4 - SheepShaver/src/Windows/sysdeps.h | 4 - 7 files changed, 278 deletions(-) delete mode 100644 BasiliskII/src/Windows/config.h diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 6ece0de22..1e8b2c2f8 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -519,7 +519,6 @@ dnl We use 64-bit file size support if possible. AC_SYS_LARGEFILE dnl Checks for header files. -AC_HEADER_STDC AC_CHECK_HEADERS(stdlib.h stdint.h) AC_CHECK_HEADERS(unistd.h fcntl.h sys/types.h sys/time.h sys/mman.h mach/mach.h) AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h) diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index bb6ab00d5..6f91115ea 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -28,10 +28,6 @@ #include #include "user_strings_unix.h" -#ifndef STDC_HEADERS -#error "You don't have ANSI C header files." -#endif - #ifdef HAVE_UNISTD_H # include # include diff --git a/BasiliskII/src/Windows/config.h b/BasiliskII/src/Windows/config.h deleted file mode 100644 index 88bd09040..000000000 --- a/BasiliskII/src/Windows/config.h +++ /dev/null @@ -1,260 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* Define if using video enabled on SEGV signals. */ -#ifndef _DEBUG -#define ENABLE_VOSF 1 -#endif - -/* Define to 1 if you have the `acoshl' function. */ -#define HAVE_ACOSHL 1 - -/* Define to 1 if you have the `acosl' function. */ -#define HAVE_ACOSL 1 - -/* Define to 1 if you have the `asinhl' function. */ -#define HAVE_ASINHL 1 - -/* Define to 1 if you have the `asinl' function. */ -#define HAVE_ASINL 1 - -/* Define to 1 if you have the `atanh' function. */ -#define HAVE_ATANH 1 - -/* Define to 1 if you have the `atanhl' function. */ -#define HAVE_ATANHL 1 - -/* Define to 1 if you have the `atanl' function. */ -#define HAVE_ATANL 1 - -/* Define to 1 if the system has the type `caddr_t'. */ -/* #undef HAVE_CADDR_T */ - -/* Define to 1 if you have the `ceill' function. */ -#define HAVE_CEILL 1 - -/* Define to 1 if you have the `coshl' function. */ -#define HAVE_COSHL 1 - -/* Define to 1 if you have the `cosl' function. */ -#define HAVE_COSL 1 - -/* Define to 1 if you have the `expl' function. */ -/* #undef HAVE_EXPL */ - -/* Define to 1 if you have the `fabsl' function. */ -/* #undef HAVE_FABSL */ - -/* Define to 1 if you have the `finite' function. */ -#define HAVE_FINITE 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_FLOATINGPOINT_H */ - -/* Define to 1 if you have the `floorl' function. */ -#define HAVE_FLOORL 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IEEE754_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IEEEFP_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `isinf' function. */ -/* #undef HAVE_ISINF */ - -/* Define to 1 if you have the `isinfl' function. */ -/* #undef HAVE_ISINFL */ - -/* Define to 1 if you have the `isnan' function. */ -#define HAVE_ISNAN 1 - -/* Define to 1 if you have the `isnanl' function. */ -/* #undef HAVE_ISNANL */ - -/* Define to 1 if you have the `isnormal' function. */ -/* #undef HAVE_ISNORMAL */ - -/* Define to 1 if the system has the type `loff_t'. */ -/* #undef HAVE_LOFF_T */ - -/* Define to 1 if you have the `log10l' function. */ -/* #undef HAVE_LOG10L */ - -/* Define to 1 if you have the `logl' function. */ -/* #undef HAVE_LOGL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NAN_H */ - -/* Define to 1 if you have the `powl' function. */ -#define HAVE_POWL 1 - -/* Define to 1 if you have the `signbit' function. */ -/* #undef HAVE_SIGNBIT */ - -/* Define if we can ignore the fault (instruction skipping in SIGSEGV - handler). */ -#define HAVE_SIGSEGV_SKIP_INSTRUCTION 1 - -/* Define to 1 if you have the `sinhl' function. */ -#define HAVE_SINHL 1 - -/* Define to 1 if you have the `sinl' function. */ -#define HAVE_SINL 1 - -/* Define to 1 if you have the `sqrtl' function. */ -#define HAVE_SQRTL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the `tanhl' function. */ -#define HAVE_TANHL 1 - -/* Define to 1 if you have the `tanl' function. */ -#define HAVE_TANL 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define if your system supports Windows exceptions. */ -#define HAVE_WIN32_EXCEPTIONS 1 - -/* Define if your system has a working Win32-based memory allocator. */ -#define HAVE_WIN32_VM 1 - -/* Define to the floating point format of the host machine. */ -#define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT - -/* Define to 1 if the host machine stores floating point numbers in memory - with the word containing the sign bit at the lowest address, or to 0 if it - does it the other way around. This macro should not be defined if the - ordering is the same as for multi-word integers. */ -/* #undef HOST_FLOAT_WORDS_BIG_ENDIAN */ - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Define this program name. */ -#define PACKAGE "Basilisk II" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "Christian.Bauer@uni-mainz.de" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "Basilisk II" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Basilisk II 1.0" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "BasiliskII" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0" - -/* The size of `double', as computed by sizeof. */ -#define SIZEOF_DOUBLE 8 - -/* The size of `float', as computed by sizeof. */ -#define SIZEOF_FLOAT 4 - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* The size of `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 8 - -/* The size of `long long', as computed by sizeof. */ -#define SIZEOF_LONG_LONG 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `void *', as computed by sizeof. */ -#define SIZEOF_VOID_P 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to enble SDL support */ -#define USE_SDL 1 - -/* Define to enable SDL audio support */ -#define USE_SDL_AUDIO 1 - -/* Define to enable SDL video graphics support */ -#define USE_SDL_VIDEO 1 - -/* Define this program version. */ -#define VERSION "1.0" - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `long int' if does not define. */ -/* #undef off_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ diff --git a/BasiliskII/src/Windows/sysdeps.h b/BasiliskII/src/Windows/sysdeps.h index ac040a43e..b729451c0 100755 --- a/BasiliskII/src/Windows/sysdeps.h +++ b/BasiliskII/src/Windows/sysdeps.h @@ -28,10 +28,6 @@ #include "config.h" #include "user_strings_windows.h" -#ifndef STDC_HEADERS -#error "You don't have ANSI C header files." -#endif - #ifndef WIN32 #define WIN32 #endif diff --git a/SheepShaver/src/Unix/configure.ac b/SheepShaver/src/Unix/configure.ac index 3b3480ca4..a8d1a007a 100755 --- a/SheepShaver/src/Unix/configure.ac +++ b/SheepShaver/src/Unix/configure.ac @@ -401,7 +401,6 @@ dnl We use 64-bit file size support if possible. AC_SYS_LARGEFILE dnl Checks for header files. -AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(malloc.h stdint.h) AC_CHECK_HEADERS(mach/vm_map.h mach/mach_init.h sys/mman.h) diff --git a/SheepShaver/src/Unix/sysdeps.h b/SheepShaver/src/Unix/sysdeps.h index 3cf79b30a..8722b40b8 100644 --- a/SheepShaver/src/Unix/sysdeps.h +++ b/SheepShaver/src/Unix/sysdeps.h @@ -28,10 +28,6 @@ #include "config.h" #include "user_strings_unix.h" -#ifndef STDC_HEADERS -#error "You don't have ANSI C header files." -#endif - #ifdef HAVE_UNISTD_H # include # include diff --git a/SheepShaver/src/Windows/sysdeps.h b/SheepShaver/src/Windows/sysdeps.h index 0d73d2bd3..3db649c8b 100755 --- a/SheepShaver/src/Windows/sysdeps.h +++ b/SheepShaver/src/Windows/sysdeps.h @@ -28,10 +28,6 @@ #include "config.h" #include "user_strings_windows.h" -#ifndef STDC_HEADERS -#error "You don't have ANSI C header files." -#endif - #include #include #include From 58e367a73d73171a2c8b19a6f02ba10d93ac84f0 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 18 Jun 2021 15:30:28 -0700 Subject: [PATCH 06/24] Add AppVeyor config --- .appveyor.yml | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..2b1498051 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,100 @@ +image: + - Visual Studio 2019 + - macOS + +environment: + matrix: + - MACEMU_PROJECT: BasiliskII + - MACEMU_PROJECT: SheepShaver + +for: +- + matrix: + only: + - image: Visual Studio 2019 + + environment: + MSYS2_DIR: C:\msys64 + MSYS2_BIN: $(MSYS2_DIR)\usr\bin + MSYS2_PLATFORM: MINGW32 + + install: + - '%MSYS2_BIN%\env %MSYS2_BIN%\bash -lc ''/usr/bin/pacman -Sy --noconfirm'' ' + # After installing a package with pacman -S, check that it is actually installed with pacman -Qi + # because pacman -S reports success even if the package install failed when some necessary package downloads timed out + - '%MSYS2_BIN%\env %MSYS2_BIN%\bash -lc ''/usr/bin/pacman -S --noconfirm mingw-w64-i686-gtk2'' ' + - '%MSYS2_BIN%\env %MSYS2_BIN%\bash -lc ''/usr/bin/pacman -Qi mingw-w64-i686-gtk2'' ' + - '%MSYS2_BIN%\env %MSYS2_BIN%\bash -lc ''/usr/bin/pacman -S --noconfirm mingw-w64-i686-SDL2'' ' + - '%MSYS2_BIN%\env %MSYS2_BIN%\bash -lc ''/usr/bin/pacman -Qi mingw-w64-i686-SDL2'' ' + + cache: + - $(MSYS2_DIR)\var\cache\pacman\pkg # downloaded MSYS2 pacman packages + + build_script: + - if %MACEMU_PROJECT%==SheepShaver %MSYS2_BIN%\env MSYSTEM=%MSYS2_PLATFORM% %MSYS2_BIN%\bash -lc 'cd /c/projects/%APPVEYOR_PROJECT_NAME%/%MACEMU_PROJECT%; make links' + - '%MSYS2_BIN%\env MSYSTEM=%MSYS2_PLATFORM% %MSYS2_BIN%\bash -lc ''cd /c/projects/%APPVEYOR_PROJECT_NAME%/%MACEMU_PROJECT%/src/Windows; ../Unix/autogen.sh'' ' + - '%MSYS2_BIN%\env MSYSTEM=%MSYS2_PLATFORM% %MSYS2_BIN%\bash -lc ''cd /c/projects/%APPVEYOR_PROJECT_NAME%/%MACEMU_PROJECT%/src/Windows; make'' ' + + after_build: + - cd %MACEMU_PROJECT%\src\Windows + - 7z a ..\..\..\%MACEMU_PROJECT%.zip %MACEMU_PROJECT%*.exe + + artifacts: + - path: $(MACEMU_PROJECT)\src\Windows\config.log + - path: $(MACEMU_PROJECT).zip + name: $(MACEMU_PROJECT) + +- + matrix: + only: + - image: macOS + MACEMU_PROJECT: BasiliskII + + environment: + SDL_VERSION: 2.0.14 + + install: + - test -e "SDL2-$SDL_VERSION.dmg" || curl -O http://www.libsdl.org/release/SDL2-$SDL_VERSION.dmg + - sudo hdiutil attach SDL2-$SDL_VERSION.dmg + - sudo cp -r /Volumes/SDL2/SDL2.framework /Library/Frameworks/ +# - brew update +# - HOMEBREW_NO_AUTO_UPDATE=1 brew install mpfr + + cache: + - SDL2-$SDL_VERSION.dmg + + build_script: + - cd $MACEMU_PROJECT/src/MacOSX + - xcodebuild -project $MACEMU_PROJECT.xcodeproj -scheme $MACEMU_PROJECT -configuration Release build SYMROOT=. CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= ARCHS=x86_64 ONLY_ACTIVE_ARCH=NO + - rm -rf Release/gencpu_output* Release/*.a + - hdiutil create ../../../$MACEMU_PROJECT.dmg -ov -volname $MACEMU_PROJECT -fs HFS+ -srcfolder Release/ + + artifacts: + - path: $MACEMU_PROJECT.dmg + name: $MACEMU_PROJECT + +- + matrix: + only: + - image: macOS + MACEMU_PROJECT: SheepShaver + + install: +# - brew update + - HOMEBREW_NO_AUTO_UPDATE=1 brew install sdl2 gtk+ + - HOMEBREW_NO_AUTO_UPDATE=1 brew link sdl2 gtk+ + + cache: + - /usr/local/Cellar + + build_script: + - cd $MACEMU_PROJECT + - make links + - cd src/Unix + - ./autogen.sh + - make + - tar -cJvf ../../../$MACEMU_PROJECT.tar.xz $MACEMU_PROJECT + + artifacts: + - path: $MACEMU_PROJECT.tar.xz + name: $MACEMU_PROJECT From 06747d4a7b85dbae2342cbc138054243fab03705 Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 12 Dec 2020 10:51:56 -0800 Subject: [PATCH 07/24] Remove BeOS and AmigaOS --- BasiliskII/BasiliskII.spec | 3 +- BasiliskII/Makefile | 56 - BasiliskII/src/AmigaOS/BasiliskII.info | Bin 1519 -> 0 bytes BasiliskII/src/AmigaOS/Makefile | 64 - BasiliskII/src/AmigaOS/asm_support.asm | 1393 ------------ BasiliskII/src/AmigaOS/audio_amiga.cpp | 515 ----- BasiliskII/src/AmigaOS/clip_amiga.cpp | 166 -- BasiliskII/src/AmigaOS/ether_amiga.cpp | 705 ------ BasiliskII/src/AmigaOS/extfs_amiga.cpp | 387 ---- BasiliskII/src/AmigaOS/main_amiga.cpp | 743 ------ BasiliskII/src/AmigaOS/prefs_amiga.cpp | 89 - BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp | 1735 -------------- BasiliskII/src/AmigaOS/scsi_amiga.cpp | 289 --- BasiliskII/src/AmigaOS/serial_amiga.cpp | 861 ------- BasiliskII/src/AmigaOS/sys_amiga.cpp | 1122 --------- BasiliskII/src/AmigaOS/sysdeps.h | 76 - BasiliskII/src/AmigaOS/timer_amiga.cpp | 157 -- BasiliskII/src/AmigaOS/user_strings_amiga.cpp | 85 - BasiliskII/src/AmigaOS/user_strings_amiga.h | 51 - BasiliskII/src/AmigaOS/video_amiga.cpp | 1165 ---------- BasiliskII/src/AmigaOS/xpram_amiga.cpp | 80 - BasiliskII/src/BeOS/Makefile | 151 -- BasiliskII/src/BeOS/SheepDriver/Makefile | 117 - .../src/BeOS/SheepDriver/sheep_driver.c | 476 ---- .../src/BeOS/SheepDriver/sheep_driver.h | 33 - BasiliskII/src/BeOS/SheepNet/Makefile | 115 - BasiliskII/src/BeOS/SheepNet/sheep_net.cpp | 294 --- BasiliskII/src/BeOS/SheepNet/sheep_net.h | 65 - BasiliskII/src/BeOS/about_window.cpp | 59 - BasiliskII/src/BeOS/about_window.h | 27 - BasiliskII/src/BeOS/audio_beos.cpp | 342 --- BasiliskII/src/BeOS/clip_beos.cpp | 128 -- BasiliskII/src/BeOS/ether_beos.cpp | 532 ----- BasiliskII/src/BeOS/extfs_beos.cpp | 489 ---- BasiliskII/src/BeOS/main_beos.cpp | 826 ------- BasiliskII/src/BeOS/prefs_beos.cpp | 106 - BasiliskII/src/BeOS/prefs_editor_beos.cpp | 1022 --------- BasiliskII/src/BeOS/scsi_beos.cpp | 237 -- BasiliskII/src/BeOS/serial_beos.cpp | 873 ------- BasiliskII/src/BeOS/sys_beos.cpp | 841 ------- BasiliskII/src/BeOS/sysdeps.h | 144 -- BasiliskII/src/BeOS/timer_beos.cpp | 166 -- BasiliskII/src/BeOS/user_strings_beos.cpp | 69 - BasiliskII/src/BeOS/user_strings_beos.h | 35 - BasiliskII/src/BeOS/video_beos.cpp | 1086 --------- BasiliskII/src/BeOS/xpram_beos.cpp | 84 - BasiliskII/src/MacOSX/video_macosx.mm | 10 +- BasiliskII/src/Unix/BasiliskII.1 | 2 +- BasiliskII/src/Unix/Irix/audio_irix.cpp | 16 +- BasiliskII/src/ether.cpp | 9 - BasiliskII/src/extfs.cpp | 8 +- BasiliskII/src/include/debug.h | 12 - BasiliskII/src/powerrom_cpu/cpu_emulation.h | 66 - BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp | 1367 ----------- BasiliskII/src/rom_patches.cpp | 15 +- BasiliskII/src/sony.cpp | 4 - BasiliskII/src/user_strings.cpp | 4 - SheepShaver/Makefile | 3 - SheepShaver/doc/BeOS/acknowledgements.html | 24 - SheepShaver/doc/BeOS/contact.html | 47 - SheepShaver/doc/BeOS/graphics.gif | Bin 8854 -> 0 bytes SheepShaver/doc/BeOS/history.html | 59 - SheepShaver/doc/BeOS/icon.gif | Bin 2011 -> 0 bytes SheepShaver/doc/BeOS/iconsmall.gif | Bin 1297 -> 0 bytes SheepShaver/doc/BeOS/index.html | 28 - SheepShaver/doc/BeOS/installation.html | 25 - SheepShaver/doc/BeOS/introduction.html | 45 - SheepShaver/doc/BeOS/memory.gif | Bin 5510 -> 0 bytes SheepShaver/doc/BeOS/quickstart.html | 38 - SheepShaver/doc/BeOS/serial.gif | Bin 4844 -> 0 bytes SheepShaver/doc/BeOS/settings.html | 127 -- SheepShaver/doc/BeOS/troubleshooting.html | 79 - SheepShaver/doc/BeOS/using.html | 76 - SheepShaver/doc/BeOS/volumes.gif | Bin 7456 -> 0 bytes .../src/BeOS/CreatePCIDrivers/Ethernet.cpp | 256 --- .../src/BeOS/CreatePCIDrivers/Makefile | 25 - .../src/BeOS/CreatePCIDrivers/Video.cpp | 78 - .../src/BeOS/CreatePCIDrivers/hexconv.cpp | 34 - SheepShaver/src/BeOS/Makefile | 117 - SheepShaver/src/BeOS/NetPeek/Makefile | 110 - SheepShaver/src/BeOS/NetPeek/NetPeek.cpp | 49 - SheepShaver/src/BeOS/SaveROM/Makefile | 110 - SheepShaver/src/BeOS/SaveROM/README | 8 - SheepShaver/src/BeOS/SaveROM/SaveROM.cpp | 128 -- SheepShaver/src/BeOS/SaveROM/SaveROM.rsrc | Bin 4323 -> 0 bytes SheepShaver/src/BeOS/SheepDriver | 1 - SheepShaver/src/BeOS/SheepNet | 1 - SheepShaver/src/BeOS/SheepShaver.rsrc | Bin 4247 -> 0 bytes SheepShaver/src/BeOS/about_window_beos.cpp | 289 --- SheepShaver/src/BeOS/audio_beos.cpp | 1 - SheepShaver/src/BeOS/clip_beos.cpp | 374 --- SheepShaver/src/BeOS/ether_beos.cpp | 400 ---- SheepShaver/src/BeOS/extfs_beos.cpp | 1 - SheepShaver/src/BeOS/main_beos.cpp | 2015 ----------------- SheepShaver/src/BeOS/prefs_beos.cpp | 112 - SheepShaver/src/BeOS/prefs_editor_beos.cpp | 877 ------- SheepShaver/src/BeOS/scsi_beos.cpp | 1 - SheepShaver/src/BeOS/serial_beos.cpp | 1 - SheepShaver/src/BeOS/sys_beos.cpp | 1 - SheepShaver/src/BeOS/sysdeps.h | 74 - SheepShaver/src/BeOS/timer_beos.cpp | 1 - SheepShaver/src/BeOS/user_strings_beos.cpp | 73 - SheepShaver/src/BeOS/user_strings_beos.h | 37 - SheepShaver/src/BeOS/video_beos.cpp | 787 ------- SheepShaver/src/BeOS/video_screen.h | 262 --- SheepShaver/src/BeOS/video_window.h | 523 ----- SheepShaver/src/BeOS/xpram_beos.cpp | 1 - SheepShaver/src/Unix/main_unix.cpp | 32 +- SheepShaver/src/include/main.h | 4 - SheepShaver/src/include/prefs_editor.h | 4 - SheepShaver/src/rsrc_patches.cpp | 285 +-- SheepShaver/src/thunks.cpp | 6 - SheepShaver/src/user_strings.cpp | 4 - SheepShaver/src/video.cpp | 32 +- 114 files changed, 53 insertions(+), 27184 deletions(-) delete mode 100644 BasiliskII/src/AmigaOS/BasiliskII.info delete mode 100644 BasiliskII/src/AmigaOS/Makefile delete mode 100644 BasiliskII/src/AmigaOS/asm_support.asm delete mode 100644 BasiliskII/src/AmigaOS/audio_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/clip_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/ether_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/extfs_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/main_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/prefs_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/scsi_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/serial_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/sys_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/sysdeps.h delete mode 100644 BasiliskII/src/AmigaOS/timer_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/user_strings_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/user_strings_amiga.h delete mode 100644 BasiliskII/src/AmigaOS/video_amiga.cpp delete mode 100644 BasiliskII/src/AmigaOS/xpram_amiga.cpp delete mode 100644 BasiliskII/src/BeOS/Makefile delete mode 100644 BasiliskII/src/BeOS/SheepDriver/Makefile delete mode 100644 BasiliskII/src/BeOS/SheepDriver/sheep_driver.c delete mode 100644 BasiliskII/src/BeOS/SheepDriver/sheep_driver.h delete mode 100644 BasiliskII/src/BeOS/SheepNet/Makefile delete mode 100644 BasiliskII/src/BeOS/SheepNet/sheep_net.cpp delete mode 100644 BasiliskII/src/BeOS/SheepNet/sheep_net.h delete mode 100644 BasiliskII/src/BeOS/about_window.cpp delete mode 100644 BasiliskII/src/BeOS/about_window.h delete mode 100644 BasiliskII/src/BeOS/audio_beos.cpp delete mode 100644 BasiliskII/src/BeOS/clip_beos.cpp delete mode 100644 BasiliskII/src/BeOS/ether_beos.cpp delete mode 100644 BasiliskII/src/BeOS/extfs_beos.cpp delete mode 100644 BasiliskII/src/BeOS/main_beos.cpp delete mode 100644 BasiliskII/src/BeOS/prefs_beos.cpp delete mode 100644 BasiliskII/src/BeOS/prefs_editor_beos.cpp delete mode 100644 BasiliskII/src/BeOS/scsi_beos.cpp delete mode 100644 BasiliskII/src/BeOS/serial_beos.cpp delete mode 100644 BasiliskII/src/BeOS/sys_beos.cpp delete mode 100644 BasiliskII/src/BeOS/sysdeps.h delete mode 100644 BasiliskII/src/BeOS/timer_beos.cpp delete mode 100644 BasiliskII/src/BeOS/user_strings_beos.cpp delete mode 100644 BasiliskII/src/BeOS/user_strings_beos.h delete mode 100644 BasiliskII/src/BeOS/video_beos.cpp delete mode 100644 BasiliskII/src/BeOS/xpram_beos.cpp delete mode 100644 BasiliskII/src/powerrom_cpu/cpu_emulation.h delete mode 100644 BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp delete mode 100644 SheepShaver/doc/BeOS/acknowledgements.html delete mode 100644 SheepShaver/doc/BeOS/contact.html delete mode 100644 SheepShaver/doc/BeOS/graphics.gif delete mode 100644 SheepShaver/doc/BeOS/history.html delete mode 100644 SheepShaver/doc/BeOS/icon.gif delete mode 100644 SheepShaver/doc/BeOS/iconsmall.gif delete mode 100644 SheepShaver/doc/BeOS/index.html delete mode 100644 SheepShaver/doc/BeOS/installation.html delete mode 100644 SheepShaver/doc/BeOS/introduction.html delete mode 100644 SheepShaver/doc/BeOS/memory.gif delete mode 100644 SheepShaver/doc/BeOS/quickstart.html delete mode 100644 SheepShaver/doc/BeOS/serial.gif delete mode 100644 SheepShaver/doc/BeOS/settings.html delete mode 100644 SheepShaver/doc/BeOS/troubleshooting.html delete mode 100644 SheepShaver/doc/BeOS/using.html delete mode 100644 SheepShaver/doc/BeOS/volumes.gif delete mode 100644 SheepShaver/src/BeOS/CreatePCIDrivers/Ethernet.cpp delete mode 100644 SheepShaver/src/BeOS/CreatePCIDrivers/Makefile delete mode 100644 SheepShaver/src/BeOS/CreatePCIDrivers/Video.cpp delete mode 100644 SheepShaver/src/BeOS/CreatePCIDrivers/hexconv.cpp delete mode 100644 SheepShaver/src/BeOS/Makefile delete mode 100644 SheepShaver/src/BeOS/NetPeek/Makefile delete mode 100644 SheepShaver/src/BeOS/NetPeek/NetPeek.cpp delete mode 100644 SheepShaver/src/BeOS/SaveROM/Makefile delete mode 100644 SheepShaver/src/BeOS/SaveROM/README delete mode 100644 SheepShaver/src/BeOS/SaveROM/SaveROM.cpp delete mode 100644 SheepShaver/src/BeOS/SaveROM/SaveROM.rsrc delete mode 120000 SheepShaver/src/BeOS/SheepDriver delete mode 120000 SheepShaver/src/BeOS/SheepNet delete mode 100644 SheepShaver/src/BeOS/SheepShaver.rsrc delete mode 100644 SheepShaver/src/BeOS/about_window_beos.cpp delete mode 120000 SheepShaver/src/BeOS/audio_beos.cpp delete mode 100644 SheepShaver/src/BeOS/clip_beos.cpp delete mode 100644 SheepShaver/src/BeOS/ether_beos.cpp delete mode 120000 SheepShaver/src/BeOS/extfs_beos.cpp delete mode 100644 SheepShaver/src/BeOS/main_beos.cpp delete mode 100644 SheepShaver/src/BeOS/prefs_beos.cpp delete mode 100644 SheepShaver/src/BeOS/prefs_editor_beos.cpp delete mode 120000 SheepShaver/src/BeOS/scsi_beos.cpp delete mode 120000 SheepShaver/src/BeOS/serial_beos.cpp delete mode 120000 SheepShaver/src/BeOS/sys_beos.cpp delete mode 100644 SheepShaver/src/BeOS/sysdeps.h delete mode 120000 SheepShaver/src/BeOS/timer_beos.cpp delete mode 100644 SheepShaver/src/BeOS/user_strings_beos.cpp delete mode 100644 SheepShaver/src/BeOS/user_strings_beos.h delete mode 100644 SheepShaver/src/BeOS/video_beos.cpp delete mode 100644 SheepShaver/src/BeOS/video_screen.h delete mode 100644 SheepShaver/src/BeOS/video_window.h delete mode 120000 SheepShaver/src/BeOS/xpram_beos.cpp diff --git a/BasiliskII/BasiliskII.spec b/BasiliskII/BasiliskII.spec index 291de26ce..85626e899 100644 --- a/BasiliskII/BasiliskII.spec +++ b/BasiliskII/BasiliskII.spec @@ -39,8 +39,7 @@ Some features of Basilisk II: - Serial drivers - SCSI Manager (old-style) emulation - Emulates extended ADB keyboard and 3-button mouse - - Uses UAE 68k emulation or (under AmigaOS and NetBSD/m68k) real 68k - processor + - Uses UAE 68k emulation or real 68k processor %prep %setup -q diff --git a/BasiliskII/Makefile b/BasiliskII/Makefile index d13e26f62..617b23f82 100644 --- a/BasiliskII/Makefile +++ b/BasiliskII/Makefile @@ -6,9 +6,6 @@ RELEASE := $(shell sed lL)!H zOgTlVEbpgEJNHUyMe0OD%t*9^f=_yPqPojE`pI61M@}MvT;kWig9(_VbOmslN~ZyASz=ySkK5WItaO2t)t? diff --git a/BasiliskII/src/AmigaOS/Makefile b/BasiliskII/src/AmigaOS/Makefile deleted file mode 100644 index 2ccaeec03..000000000 --- a/BasiliskII/src/AmigaOS/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# AmigaOS makefile for Basilisk II (GeekGadgets tool chain) - -## System specific configuration -CC = gcc -CXX = c++ -CXXFLAGS = -g -O1 -noixemul -m68020 -msmall-code -Wno-multichar -CPPFLAGS = -I../include -I../native_cpu -I. -DEFS = -LDFLAGS = -noixemul -LIBS = /gg/lib/libnix/swapstack.o -AS = PhxAss -ASFLAGS = OPT ! INCPATH GG:os-include FPU=1 - -## Files -SRCS = ../main.cpp main_amiga.cpp ../prefs.cpp ../prefs_items.cpp \ - prefs_amiga.cpp prefs_editor_amiga.cpp sys_amiga.cpp ../rom_patches.cpp \ - ../slot_rom.cpp ../rsrc_patches.cpp ../emul_op.cpp \ - ../macos_util.cpp ../xpram.cpp xpram_amiga.cpp ../timer.cpp \ - timer_amiga.cpp clip_amiga.cpp ../adb.cpp ../serial.cpp \ - serial_amiga.cpp ../ether.cpp ether_amiga.cpp ../sony.cpp ../disk.cpp \ - ../cdrom.cpp ../scsi.cpp scsi_amiga.cpp ../video.cpp video_amiga.cpp \ - ../audio.cpp audio_amiga.cpp ../extfs.cpp extfs_amiga.cpp \ - ../user_strings.cpp user_strings_amiga.cpp asm_support.asm -APP = BasiliskII - -## Rules -.PHONY: clean distclean -.SUFFIXES: -.SUFFIXES: .c .cpp .asm .o .h - -all: $(APP) - -OBJ_DIR = obj -$(OBJ_DIR):: - @[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1 - -define SRCS_LIST_TO_OBJS - $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(foreach file, $(SRCS), \ - $(basename $(notdir $(file)))))) -endef -OBJS = $(SRCS_LIST_TO_OBJS) - -SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file)))) -VPATH := -VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS)))) - -$(APP): $(OBJ_DIR) $(OBJS) - $(CXX) -o $(APP) $(LDFLAGS) $(LIBS) $(OBJS) - -clean: - rm -f $(APP) $(OBJ_DIR)/* *~ *.bak obj.0000.* - -distclean: clean - rm -rf $(OBJ_DIR) - -$(OBJ_DIR)/%.o : %.cpp - $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o : %.asm - $(AS) $(ASFLAGS) $< TO $(OBJ_DIR)/$*.obj - hunk2aout $(OBJ_DIR)/$*.obj >/dev/null - mv obj.0000.* $@ - -#------------------------------------------------------------------------- -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/BasiliskII/src/AmigaOS/asm_support.asm b/BasiliskII/src/AmigaOS/asm_support.asm deleted file mode 100644 index d2a81b076..000000000 --- a/BasiliskII/src/AmigaOS/asm_support.asm +++ /dev/null @@ -1,1393 +0,0 @@ -* -* asm_support.asm - AmigaOS utility functions in assembly language -* -* Basilisk II (C) 1997-2001 Christian Bauer -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* - -DEBUG_DETAIL SET 1 - - INCLUDE "exec/types.i" - INCLUDE "exec/macros.i" - INCLUDE "exec/memory.i" - INCLUDE "exec/tasks.i" - INCLUDE "dos/dos.i" - INCLUDE "devices/timer.i" - -; INCLUDE "asmsupp.i" - - XDEF _AtomicAnd - XDEF _AtomicOr - XDEF _MoveVBR - XDEF _DisableSuperBypass - XDEF _Execute68k - XDEF _Execute68kTrap - XDEF _TrapHandlerAsm - XDEF _ExceptionHandlerAsm - XDEF _AsmTriggerNMI - - XREF _OldTrapHandler - XREF _OldExceptionHandler - XREF _IllInstrHandler - XREF _PrivViolHandler - XREF _EmulatedSR - XREF _IRQSigMask - XREF _InterruptFlags - XREF _MainTask - XREF _SysBase - XREF _quit_emulator - -INFO_LEVEL equ 0 - - SECTION text,CODE - - MACHINE 68020 - - IFGE INFO_LEVEL -subSysName: dc.b '+',0 - ENDIF - -* -* Atomic bit operations (don't trust the compiler) -* - -_AtomicAnd move.l 4(sp),a0 - move.l 8(sp),d0 - and.l d0,(a0) - rts - -_AtomicOr move.l 4(sp),a0 - move.l 8(sp),d0 - or.l d0,(a0) - rts - -* -* Move VBR away from 0 if neccessary -* - -_MoveVBR movem.l d0-d1/a0-a1/a5-a6,-(sp) - move.l _SysBase,a6 - - lea getvbr,a5 ;VBR at 0? - JSRLIB Supervisor - tst.l d0 - bne.s 1$ - - move.l #$400,d0 ;Yes, allocate memory for new table - move.l #MEMF_PUBLIC,d1 - JSRLIB AllocMem - tst.l d0 - beq.s 1$ - - JSRLIB Disable - - move.l d0,a5 ;Copy old table - move.l d0,a1 - sub.l a0,a0 - move.l #$400,d0 - JSRLIB CopyMem - JSRLIB CacheClearU - - move.l a5,d0 ;Set VBR - lea setvbr,a5 - JSRLIB Supervisor - - JSRLIB Enable - -1$ movem.l (sp)+,d0-d1/a0-a1/a5-a6 - rts - -getvbr movec vbr,d0 - rte - -setvbr movec d0,vbr - rte - -* -* Disable 68060 Super Bypass mode -* - -_DisableSuperBypass - movem.l d0-d1/a0-a1/a5-a6,-(sp) - move.l _SysBase,a6 - - lea dissb,a5 - JSRLIB Supervisor - - movem.l (sp)+,d0-d1/a0-a1/a5-a6 - rts - - MACHINE 68060 - -dissb movec pcr,d0 - bset #5,d0 - movec d0,pcr - rte - - MACHINE 68020 - -* -* Execute 68k subroutine (must be ended with rts) -* r->a[7] and r->sr are unused! -* - -; void Execute68k(uint32 addr, M68kRegisters *r); -_Execute68k - move.l 4(sp),d0 ;Get arguments - move.l 8(sp),a0 - - movem.l d2-d7/a2-a6,-(sp) ;Save registers - - move.l a0,-(sp) ;Push pointer to M68kRegisters on stack - pea 1$ ;Push return address on stack - move.l d0,-(sp) ;Push pointer to 68k routine on stack - movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters - - rts ;Jump into 68k routine - -1$ move.l a6,-(sp) ;Save a6 - move.l 4(sp),a6 ;Get pointer to M68kRegisters - movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters - move.l (sp)+,56(a6) ;Save a6 to M68kRegisters - addq.l #4,sp ;Remove pointer from stack - - movem.l (sp)+,d2-d7/a2-a6 ;Restore registers - rts - -* -* Execute MacOS 68k trap -* r->a[7] and r->sr are unused! -* - -; void Execute68kTrap(uint16 trap, M68kRegisters *r); -_Execute68kTrap - move.l 4(sp),d0 ;Get arguments - move.l 8(sp),a0 - - movem.l d2-d7/a2-a6,-(sp) ;Save registers - - move.l a0,-(sp) ;Push pointer to M68kRegisters on stack - move.w d0,-(sp) ;Push trap word on stack - subq.l #8,sp ;Create fake A-Line exception frame - movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters - - move.l a2,-(sp) ;Save a2 and d2 - move.l d2,-(sp) - lea 1$,a2 ;a2 points to return address - move.w 16(sp),d2 ;Load trap word into d2 - - jmp ([$28.w],10) ;Jump into MacOS A-Line handler - -1$ move.l a6,-(sp) ;Save a6 - move.l 6(sp),a6 ;Get pointer to M68kRegisters - movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters - move.l (sp)+,56(a6) ;Save a6 to M68kRegisters - addq.l #6,sp ;Remove pointer and trap word from stack - - movem.l (sp)+,d2-d7/a2-a6 ;Restore registers - rts - -* -* Exception handler of main task (for interrupts) -* - -_ExceptionHandlerAsm - move.l d0,-(sp) ;Save d0 - - and.l #SIGBREAKF_CTRL_C,d0 ;CTRL-C? - bne.s 2$ - - move.w _EmulatedSR,d0 ;Interrupts enabled in emulated SR? - and.w #$0700,d0 - bne 1$ - move.w #$0064,-(sp) ;Yes, fake interrupt stack frame - pea 1$ - move.w _EmulatedSR,d0 - move.w d0,-(sp) - or.w #$2100,d0 ;Set interrupt level in SR, enter (virtual) supervisor mode - move.w d0,_EmulatedSR - move.l $64.w,-(sp) ;Jump to MacOS interrupt handler - rts - -1$ move.l (sp)+,d0 ;Restore d0 - rts - -2$ JSRLIB Forbid ;Waiting for Dos signal? - sub.l a1,a1 - JSRLIB FindTask - move.l d0,a0 - move.l TC_SIGWAIT(a0),d0 - move.l TC_SIGRECVD(a0),d1 - JSRLIB Permit - btst #SIGB_DOS,d0 - beq 3$ - btst #SIGB_DOS,d1 - bne 4$ - -3$ lea TC_SIZE(a0),a0 ;No, remove pending Dos packets - JSRLIB GetMsg - - move.w _EmulatedSR,d0 - or.w #$0700,d0 ;Disable all interrupts - move.w d0,_EmulatedSR - moveq #0,d0 ;Disable all exception signals - moveq #-1,d1 - JSRLIB SetExcept - jsr _quit_emulator ;CTRL-C, quit emulator -4$ move.l (sp)+,d0 - rts - -* -* Trap handler of main task -* - -_TrapHandlerAsm: - IFEQ INFO_LEVEL-1002 - move.w ([6,a0]),-(sp) - move.w #0,-(sp) - move.l (4+6,a0),-(sp) - PUTMSG 0,'%s/TrapHandlerAsm: addr=%08lx opcode=%04lx' - lea (2*4,sp),sp - ENDC - - cmp.l #4,(sp) ;Illegal instruction? - beq.s doillinstr - cmp.l #10,(sp) ;A-Line exception? - beq.s doaline - cmp.l #8,(sp) ;Privilege violation? - beq.s doprivviol - - cmp.l #9,(sp) ;Trace? - beq dotrace - cmp.l #3,(sp) ;Illegal Address? - beq.s doilladdr - cmp.l #11,(sp) ;F-Line exception - beq.s dofline - - cmp.l #32,(sp) - blt 1$ - cmp.l #47,(sp) - ble doTrapXX ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors - -1$: - cmp.l #48,(sp) - blt 2$ - cmp.l #55,(sp) - ble doTrapFPU -2$: - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/TrapHandlerAsm: stack=%08lx %08lx %08lx %08lx' - ENDC - - move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler - rts - -* -* TRAP #0 - 15 Instruction Vectors -* - -doTrapXX: - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/doTrapXX: stack=%08lx %08lx %08lx %08lx' - ENDC - - movem.l a0/d0,-(sp) ;Save a0,d0 - move.l (2*4,sp),d0 ;vector number 32-47 - - move.l usp,a0 ;Get user stack pointer - move.l (4*4,sp),-(a0) ;Copy 4-word stack frame to user stack - move.l (3*4,sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - - lsl.l #2,d0 ;convert vector number to vector offset - move.l d0,a0 - move.l (a0),d0 ;get mac trap vector - - move.l usp,a0 ;Get user stack pointer - move.l d0,-(a0) ;store vector offset as return address - move.l a0,usp ;Update USP - - movem.l (sp)+,a0/d0 ;Restore a0,d0 - addq.l #4*2,sp ;Remove exception frame from supervisor stack - - andi #$d8ff,sr ;Switch to user mode, enable interrupts - rts - - -* -* FPU Exception Instruction Vectors -* - -doTrapFPU: - move.l d0,(sp) - fmove.l fpcr,d0 - and.w #$00ff,d0 ;disable FPU exceptions - fmove.l d0,fpcr - move.l (sp)+,d0 ;Restore d0 - rte - - -* -* trace Vector -* - -dotrace - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/dotrace: stack=%08lx %08lx %08lx %08lx' - ENDC - - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - - IFEQ INFO_LEVEL-1009 - move.l (12,a0),-(sp) - move.l (8,a0),-(sp) - move.l (4,a0),-(sp) - move.l (0,a0),-(sp) - move.l a0,-(sp) - move.l a7,-(sp) - PUTMSG 0,'%s/dotrace: sp=%08lx usp=%08lx (%08lx %08lx %08lx %08lx)' - lea (6*4,sp),sp - ENDC - - move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack - move.l 2*4(sp),-(a0) - move.l 1*4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - lea 6*2(sp),sp ;Remove exception frame from supervisor stack - andi #$18ff,sr ;Switch to user mode, enable interrupts, disable trace - - move.l $24.w,-(sp) ;Jump to MacOS exception handler - rts - - -* -* A-Line handler: call MacOS A-Line handler -* - -doaline move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l 8(sp),-(a0) ;Copy stack frame to user stack - move.l 4(sp),-(a0) - move.l a0,usp ;Update USP - - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - addq.l #8,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - -; and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR - - move.l $28.w,-(sp) ;Jump to MacOS exception handler - rts - -* -* F-Line handler: call F-Line exception handler -* - -dofline move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l 8(sp),-(a0) ;Copy stack frame to user stack - move.l 4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - addq.l #8,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR - - move.l $2c.w,-(sp) ;Jump to MacOS exception handler - rts - -* -* Illegal address handler -* - -doilladdr: - IFEQ INFO_LEVEL-1009 - PUTMSG 0,'%s/doilladdr: stack=%08lx %08lx %08lx %08lx' - ENDC - - move.l a0,(sp) ;Save a0 - - move.l usp,a0 ;Get user stack pointer - move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack - move.l 2*4(sp),-(a0) - move.l 1*4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - lea 6*2(sp),sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l $0c.w,-(sp) ;Jump to MacOS exception handler - rts - - -* -* Illegal instruction handler: call IllInstrHandler() (which calls EmulOp()) -* to execute extended opcodes (see emul_op.h) -* - -doillinstr movem.l a0/d0,-(sp) - move.w ([6+2*4,sp]),d0 - and.w #$ff00,d0 - cmp.w #$7100,d0 - - IFEQ INFO_LEVEL-1009 - move.l d0,-(sp) - PUTMSG 0,'%s/doillinst: d0=%08lx stack=%08lx %08lx %08lx %08lx' - lea (1*4,sp),sp - ENDC - movem.l (sp)+,a0/d0 - beq 1$ - - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l 8(sp),-(a0) ;Copy stack frame to user stack - move.l 4(sp),-(a0) - move.l a0,usp ;Update USP - or.w #$2000,(a0) ;set Supervisor bit in SR - move.l (sp)+,a0 ;Restore a0 - - add.w #3*4,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l $10.w,-(sp) ;Jump to MacOS exception handler - rts - -1$: - move.l a6,(sp) ;Save a6 - move.l usp,a6 ;Get user stack pointer - - move.l a6,-10(a6) ;Push USP (a7) - move.l 6(sp),-(a6) ;Push PC - move.w 4(sp),-(a6) ;Push SR - subq.l #4,a6 ;Skip saved USP - move.l (sp),-(a6) ;Push old a6 - movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers - move.l a6,usp ;Update USP - - add.w #12,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp - jsr _IllInstrHandler - addq.l #4,sp - - movem.l (sp)+,d0-d7/a0-a6 ;Restore registers - addq.l #4,sp ;Skip saved USP (!!) - rtr ;Return from exception - -* -* Privilege violation handler: MacOS runs in supervisor mode, -* so we have to emulate certain privileged instructions -* - -doprivviol move.l d0,(sp) ;Save d0 - move.w ([6,sp]),d0 ;Get instruction word - - IFEQ INFO_LEVEL-1001 - move.w ([6,a0]),-(sp) - move.w #0,-(sp) - PUTMSG 0,'%s/doprivviol: opcode=%04lx' - lea (1*4,sp),sp - ENDC - - cmp.w #$40e7,d0 ;move sr,-(sp)? - beq pushsr - cmp.w #$46df,d0 ;move (sp)+,sr? - beq popsr - - cmp.w #$007c,d0 ;ori #xxxx,sr? - beq orisr - cmp.w #$027c,d0 ;andi #xxxx,sr? - beq andisr - - cmp.w #$46fc,d0 ;move #xxxx,sr? - beq movetosrimm - - cmp.w #$46ef,d0 ;move (xxxx,sp),sr? - beq movetosrsprel - cmp.w #$46d8,d0 ;move (a0)+,sr? - beq movetosra0p - cmp.w #$46d9,d0 ;move (a1)+,sr? - beq movetosra1p - - cmp.w #$40f8,d0 ;move sr,xxxx.w? - beq movefromsrabs - cmp.w #$40d0,d0 ;move sr,(a0)? - beq movefromsra0 - cmp.w #$40d7,d0 ;move sr,(sp)? - beq movefromsrsp - - cmp.w #$f327,d0 ;fsave -(sp)? - beq fsavepush - cmp.w #$f35f,d0 ;frestore (sp)+? - beq frestorepop - cmp.w #$f32d,d0 ;fsave xxx(a5) ? - beq fsavea5 - cmp.w #$f36d,d0 ;frestore xxx(a5) ? - beq frestorea5 - - cmp.w #$4e73,d0 ;rte? - beq pvrte - - cmp.w #$40c0,d0 ;move sr,d0? - beq movefromsrd0 - cmp.w #$40c1,d0 ;move sr,d1? - beq movefromsrd1 - cmp.w #$40c2,d0 ;move sr,d2? - beq movefromsrd2 - cmp.w #$40c3,d0 ;move sr,d3? - beq movefromsrd3 - cmp.w #$40c4,d0 ;move sr,d4? - beq movefromsrd4 - cmp.w #$40c5,d0 ;move sr,d5? - beq movefromsrd5 - cmp.w #$40c6,d0 ;move sr,d6? - beq movefromsrd6 - cmp.w #$40c7,d0 ;move sr,d7? - beq movefromsrd7 - - cmp.w #$46c0,d0 ;move d0,sr? - beq movetosrd0 - cmp.w #$46c1,d0 ;move d1,sr? - beq movetosrd1 - cmp.w #$46c2,d0 ;move d2,sr? - beq movetosrd2 - cmp.w #$46c3,d0 ;move d3,sr? - beq movetosrd3 - cmp.w #$46c4,d0 ;move d4,sr? - beq movetosrd4 - cmp.w #$46c5,d0 ;move d5,sr? - beq movetosrd5 - cmp.w #$46c6,d0 ;move d6,sr? - beq movetosrd6 - cmp.w #$46c7,d0 ;move d7,sr? - beq movetosrd7 - - cmp.w #$4e7a,d0 ;movec cr,x? - beq movecfromcr - cmp.w #$4e7b,d0 ;movec x,cr? - beq movectocr - - cmp.w #$f478,d0 ;cpusha dc? - beq cpushadc - cmp.w #$f4f8,d0 ;cpusha dc/ic? - beq cpushadcic - - cmp.w #$4e69,d0 ;move usp,a1 - beq moveuspa1 - cmp.w #$4e68,d0 ;move usp,a0 - beq moveuspa0 - - cmp.w #$4e61,d0 ;move a1,usp - beq moved1usp - -pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp - move.l a6,(sp) ;Save a6 - move.l usp,a6 ;Get user stack pointer - - move.l a6,-10(a6) ;Push USP (a7) - move.l 6(sp),-(a6) ;Push PC - move.w 4(sp),-(a6) ;Push SR - subq.l #4,a6 ;Skip saved USP - move.l (sp),-(a6) ;Push old a6 - movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers - move.l a6,usp ;Update USP - - add.w #12,sp ;Remove exception frame from supervisor stack - andi #$d8ff,sr ;Switch to user mode, enable interrupts - - move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp - jsr _PrivViolHandler - addq.l #4,sp - - movem.l (sp)+,d0-d7/a0-a6 ;Restore registers - addq.l #4,sp ;Skip saved USP - rtr ;Return from exception - -; move sr,-(sp) -pushsr move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w 8(sp),d0 ;Get CCR from exception stack frame - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,-(a0) ;Store SR on user stack - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move (sp)+,sr -popsr move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w (a0)+,d0 ;Get SR from user stack - move.w d0,8(sp) ;Store into CCR on exception stack frame - and.w #$00ff,8(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - - and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled - bne 1$ - tst.l _InterruptFlags - beq 1$ - movem.l d0-d1/a0-a1/a6,-(sp) - move.l _SysBase,a6 - move.l _MainTask,a1 - move.l _IRQSigMask,d0 - JSRLIB Signal - movem.l (sp)+,d0-d1/a0-a1/a6 -1$ - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; ori #xxxx,sr -orisr move.w 4(sp),d0 ;Get CCR from stack - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - or.w ([6,sp],2),d0 ;Or with immediate value - move.w d0,4(sp) ;Store into CCR on stack - and.w #$00ff,4(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - move.l (sp)+,d0 ;Restore d0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; andi #xxxx,sr -andisr move.w 4(sp),d0 ;Get CCR from stack - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - and.w ([6,sp],2),d0 ;And with immediate value -storesr4 move.w d0,4(sp) ;Store into CCR on stack - and.w #$00ff,4(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - - and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled - bne.s 1$ - tst.l _InterruptFlags - beq.s 1$ - movem.l d0-d1/a0-a1/a6,-(sp) - move.l _SysBase,a6 - move.l _MainTask,a1 - move.l _IRQSigMask,d0 - JSRLIB Signal - movem.l (sp)+,d0-d1/a0-a1/a6 -1$ move.l (sp)+,d0 ;Restore d0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move #xxxx,sr -movetosrimm move.w ([6,sp],2),d0 ;Get immediate value - bra.s storesr4 - -; move (xxxx,sp),sr -movetosrsprel move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w ([10,sp],2),d0 ;Get offset - move.w (a0,d0.w),d0 ;Read word - move.l (sp)+,a0 ;Restore a0 - bra.s storesr4 - -; move (a0)+,sr -movetosra0p move.w (a0)+,d0 ;Read word - bra storesr2 - -; move (a1)+,sr -movetosra1p move.w (a1)+,d0 ;Read word - bra storesr2 - -; move sr,xxxx.w -movefromsrabs move.l a0,-(sp) ;Save a0 - move.w ([10,sp],2),a0 ;Get address - move.w 8(sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,(a0) ;Store SR - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move sr,(a0) -movefromsra0 move.w 4(sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,(a0) ;Store SR - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move sr,(sp) -movefromsrsp move.l a0,-(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.w 8(sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - move.w d0,(a0) ;Store SR - move.l (sp)+,a0 ;Restore a0 - move.l (sp)+,d0 ;Restore d0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; fsave -(sp) -fsavepush move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - move.l #$41000000,-(a0) ;Push idle frame - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; fsave xxx(a5) -fsavea5 move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l a5,a0 ;Get base register - add.w ([6,sp],2),a0 ;Add offset to base register - move.l #$41000000,(a0) ;Push idle frame - move.l (sp)+,a0 ;Restore a0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; frestore (sp)+ -frestorepop move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l usp,a0 ;Get user stack pointer - addq.l #4,a0 ;Nothing to do... - move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; frestore xxx(a5) -frestorea5 move.l (sp),d0 ;Restore d0 - move.l a0,(sp) ;Save a0 - move.l (sp)+,a0 ;Restore a0 - addq.l #4,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; rte -pvrte movem.l a0/a1,-(sp) ;Save a0 and a1 - move.l usp,a0 ;Get user stack pointer - - move.w (a0)+,d0 ;Get SR from user stack - move.w d0,8+4(sp) ;Store into CCR on exception stack frame - and.w #$c0ff,8+4(sp) - and.w #$e700,d0 ;Extract supervisor bits - move.w d0,_EmulatedSR ;And save them - move.l (a0)+,10+4(sp) ;Store return address in exception stack frame - - move.w (a0)+,d0 ;get format word - lsr.w #7,d0 ;get stack frame Id - lsr.w #4,d0 - and.w #$001e,d0 - move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length - subq.w #4,d0 ; count only extra words - lea 16+4(sp),a1 ; destination address (in supervisor stack) - bra 1$ - -2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack -1$ dbf d0,2$ - - move.l a0,usp ;Update USP - movem.l (sp)+,a0/a1 ;Restore a0 and a1 - move.l (sp)+,d0 ;Restore d0 - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; sizes of exceptions stack frames -StackFormatTable: - dc.w 4 ; Four-word stack frame, format $0 - dc.w 4 ; Throwaway four-word stack frame, format $1 - dc.w 6 ; Six-word stack frame, format $2 - dc.w 6 ; MC68040 floating-point post-instruction stack frame, format $3 - dc.w 8 ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4 - dc.w 4 ; Format $5 - dc.w 4 ; Format $6 - dc.w 30 ; MC68040 access error stack frame, Format $7 - dc.w 29 ; MC68010 bus and address error stack frame, format $8 - dc.w 10 ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9 - dc.w 16 ; MC68020 and MC68030 short bus cycle stack frame, format $a - dc.w 46 ; MC68020 and MC68030 long bus cycle stack frame, format $b - dc.w 12 ; CPU32 bus error for prefetches and operands stack frame, format $c - dc.w 4 ; Format $d - dc.w 4 ; Format $e - dc.w 4 ; Format $f - -; move sr,dx -movefromsrd0 addq.l #4,sp ;Skip saved d0 - moveq #0,d0 - move.w (sp),d0 ;Get CCR - or.w _EmulatedSR,d0 ;Add emulated supervisor bits - addq.l #2,2(sp) ;Skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd1 move.l (sp)+,d0 - moveq #0,d1 - move.w (sp),d1 - or.w _EmulatedSR,d1 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd2 move.l (sp)+,d0 - moveq #0,d2 - move.w (sp),d2 - or.w _EmulatedSR,d2 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd3 move.l (sp)+,d0 - moveq #0,d3 - move.w (sp),d3 - or.w _EmulatedSR,d3 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd4 move.l (sp)+,d0 - moveq #0,d4 - move.w (sp),d4 - or.w _EmulatedSR,d4 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd5 move.l (sp)+,d0 - moveq #0,d5 - move.w (sp),d5 - or.w _EmulatedSR,d5 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd6 move.l (sp)+,d0 - moveq #0,d6 - move.w (sp),d6 - or.w _EmulatedSR,d6 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movefromsrd7 move.l (sp)+,d0 - moveq #0,d7 - move.w (sp),d7 - or.w _EmulatedSR,d7 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; move dx,sr -movetosrd0 move.l (sp),d0 -storesr2 move.w d0,4(sp) - and.w #$00ff,4(sp) - and.w #$e700,d0 - move.w d0,_EmulatedSR - - and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled - bne.s 1$ - tst.l _InterruptFlags - beq.s 1$ - movem.l d0-d1/a0-a1/a6,-(sp) - move.l _SysBase,a6 - move.l _MainTask,a1 - move.l _IRQSigMask,d0 - JSRLIB Signal - movem.l (sp)+,d0-d1/a0-a1/a6 -1$ move.l (sp)+,d0 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movetosrd1 move.l d1,d0 - bra.s storesr2 - -movetosrd2 move.l d2,d0 - bra.s storesr2 - -movetosrd3 move.l d3,d0 - bra.s storesr2 - -movetosrd4 move.l d4,d0 - bra.s storesr2 - -movetosrd5 move.l d5,d0 - bra.s storesr2 - -movetosrd6 move.l d6,d0 - bra.s storesr2 - -movetosrd7 move.l d7,d0 - bra.s storesr2 - -; movec cr,x -movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word - - cmp.w #$8801,d0 ;movec vbr,a0? - beq.s movecvbra0 - cmp.w #$9801,d0 ;movec vbr,a1? - beq.s movecvbra1 - cmp.w #$A801,d0 ;movec vbr,a2? - beq.s movecvbra2 - cmp.w #$1801,d0 ;movec vbr,d1? - beq movecvbrd1 - cmp.w #$0002,d0 ;movec cacr,d0? - beq.s moveccacrd0 - cmp.w #$1002,d0 ;movec cacr,d1? - beq.s moveccacrd1 - cmp.w #$0003,d0 ;movec tc,d0? - beq.s movectcd0 - cmp.w #$1003,d0 ;movec tc,d1? - beq.s movectcd1 - cmp.w #$1000,d0 ;movec sfc,d1? - beq movecsfcd1 - cmp.w #$1001,d0 ;movec dfc,d1? - beq movecdfcd1 - cmp.w #$0806,d0 ;movec urp,d0? - beq movecurpd0 - cmp.w #$0807,d0 ;movec srp,d0? - beq.s movecsrpd0 - cmp.w #$0004,d0 ;movec itt0,d0 - beq.s movecitt0d0 - cmp.w #$0005,d0 ;movec itt1,d0 - beq.s movecitt1d0 - cmp.w #$0006,d0 ;movec dtt0,d0 - beq.s movecdtt0d0 - cmp.w #$0007,d0 ;movec dtt1,d0 - beq.s movecdtt1d0 - - bra pv_unhandled - -; movec cacr,d0 -moveccacrd0 move.l (sp)+,d0 - move.l #$3111,d0 ;All caches and bursts on - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec cacr,d1 -moveccacrd1 move.l (sp)+,d0 - move.l #$3111,d1 ;All caches and bursts on - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,a0 -movecvbra0 move.l (sp)+,d0 - sub.l a0,a0 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,a1 -movecvbra1 move.l (sp)+,d0 - sub.l a1,a1 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,a2 -movecvbra2 move.l (sp)+,d0 - sub.l a2,a2 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec vbr,d1 -movecvbrd1 move.l (sp)+,d0 - moveq.l #0,d1 ;VBR always appears to be at 0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec tc,d0 -movectcd0 addq.l #4,sp - moveq #0,d0 ;MMU is always off - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec tc,d1 +jl+ -movectcd1 move.l (sp)+,d0 ;Restore d0 - moveq #0,d1 ;MMU is always off - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec sfc,d1 +jl+ -movecsfcd1 move.l (sp)+,d0 ;Restore d0 - moveq #0,d1 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec dfc,d1 +jl+ -movecdfcd1 move.l (sp)+,d0 ;Restore d0 - moveq #0,d1 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -movecurpd0 ; movec urp,d0 +jl+ -movecsrpd0 ; movec srp,d0 -movecitt0d0 ; movec itt0,d0 -movecitt1d0 ; movec itt1,d0 -movecdtt0d0 ; movec dtt0,d0 -movecdtt1d0 ; movec dtt1,d0 - addq.l #4,sp - moveq.l #0,d0 ;MMU is always off - addq.l #4,2(sp) ;skip instruction - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec x,cr -movectocr move.w ([6,sp],2),d0 ;Get next instruction word - - cmp.w #$0801,d0 ;movec d0,vbr? - beq.s movectovbr - cmp.w #$1801,d0 ;movec d1,vbr? - beq.s movectovbr - cmp.w #$A801,d0 ;movec a2,vbr? - beq.s movectovbr - cmp.w #$0002,d0 ;movec d0,cacr? - beq.s movectocacr - cmp.w #$1002,d0 ;movec d1,cacr? - beq.s movectocacr - cmp.w #$1000,d0 ;movec d1,sfc? - beq.s movectoxfc - cmp.w #$1001,d0 ;movec d1,dfc? - beq.s movectoxfc - - bra pv_unhandled - -; movec x,vbr -movectovbr move.l (sp)+,d0 ;Ignore moves to VBR - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec dx,cacr -movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches - move.l _SysBase,a6 - JSRLIB CacheClearU - movem.l (sp)+,d1/a0-a1/a6 - move.l (sp)+,d0 - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; movec x,sfc -; movec x,dfc -movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC - addq.l #4,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; cpusha -cpushadc -cpushadcic - IFEQ INFO_LEVEL-1003 - move.l (4),-(sp) - move.l d0,-(sp) - PUTMSG 0,'%s/cpushadc: opcode=%04lx Execbase=%08lx' - lea (2*4,sp),sp - ENDC - movem.l d1/a0-a1/a6,-(sp) ;Clear caches - move.l _SysBase,a6 - JSRLIB CacheClearU - movem.l (sp)+,d1/a0-a1/a6 - move.l (sp)+,d0 - addq.l #2,2(sp) - rte - -; move usp,a1 +jl+ -moveuspa1 move.l (sp)+,d0 - move usp,a1 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1009 - move.l a1,-(sp) - move.l a7,-(sp) - PUTMSG 0,'%s/moveuspa1: a7=%08lx a1=%08lx' - lea (2*4,sp),sp - ENDC - - rte - -; move usp,a0 +jl+ -moveuspa0 move.l (sp)+,d0 - move usp,a0 - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1009 - move.l a0,-(sp) - move.l a7,-(sp) - PUTMSG 0,'%s/moveuspa0: a7=%08lx a0=%08lx' - lea (2*4,sp),sp - ENDC - - rte - -; move a1,usp +jl+ -moved1usp move.l (sp)+,d0 - move a1,usp - addq.l #2,2(sp) - - IFEQ INFO_LEVEL-1001 - move.l (4),-(sp) - PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' - lea (1*4,sp),sp - ENDC - rte - -; -; Trigger NMI (Pop up debugger) -; - -_AsmTriggerNMI move.l d0,-(sp) ;Save d0 - move.w #$007c,-(sp) ;Yes, fake NMI stack frame - pea 1$ - move.w _EmulatedSR,d0 - and.w #$f8ff,d0 ;Set interrupt level in SR - move.w d0,-(sp) - move.w d0,_EmulatedSR - - move.l $7c.w,-(sp) ;Jump to MacOS NMI handler - rts - -1$ move.l (sp)+,d0 ;Restore d0 - rts - - -CopyTrapStack: - movem.l d0/a0/a1,-(sp) - - move.w (5*4+6,sp),d0 ;get format word - lsr.w #7,d0 ;get stack frame Id - lsr.w #4,d0 - and.w #$001e,d0 - move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length - - lea (5*4,sp),a0 ;get start of exception stack frame - move.l usp,a1 ;Get user stack pointer - bra 1$ - -2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack -1$ dbf d0,2$ - - move.l (3*4,sp),-(a0) ;copy return address to new top of stack - move.l a0,sp - rts - - END diff --git a/BasiliskII/src/AmigaOS/audio_amiga.cpp b/BasiliskII/src/AmigaOS/audio_amiga.cpp deleted file mode 100644 index 5c2643146..000000000 --- a/BasiliskII/src/AmigaOS/audio_amiga.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/* - * audio_amiga.cpp - Audio support, AmigaOS implementation using AHI - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define D1(x) ; - - -// Global variables -static ULONG ahi_id = AHI_DEFAULT_ID; // AHI audio ID -static struct AHIAudioCtrl *ahi_ctrl = NULL; -static struct AHISampleInfo sample[2]; // Two sample infos for double-buffering -static struct Hook sf_hook; -static int play_buf = 0; // Number of currently played buffer -static long sound_buffer_size; // Size of one audio buffer in bytes -static int audio_block_fetched = 0; // Number of audio blocks fetched by interrupt routine - -static bool main_mute = false; -static bool speaker_mute = false; -static ULONG supports_volume_changes = false; -static ULONG supports_stereo_panning = false; -static ULONG current_main_volume; -static ULONG current_speaker_volume; - - -// Prototypes -static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/); -void audio_set_sample_rate_byval(uint32 value); -void audio_set_sample_size_byval(uint32 value); -void audio_set_channels_byval(uint32 value); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(int sample_rate_index) -{ - AudioStatus.sample_rate = audio_sample_rates[sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[0]; - AudioStatus.channels = audio_channel_counts[0]; -} - -void AudioInit(void) -{ - sample[0].ahisi_Address = sample[1].ahisi_Address = NULL; - - // Init audio status and feature flags - audio_channel_counts.push_back(2); -// set_audio_status_format(); - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // AHI available? - if (AHIBase == NULL) { - WarningAlert(GetString(STR_NO_AHI_WARN)); - return; - } - - // Initialize callback hook - sf_hook.h_Entry = (HOOKFUNC)audio_callback; - - // Read "sound" preferences - const char *str = PrefsFindString("sound"); - if (str) - sscanf(str, "ahi/%08lx", &ahi_id); - - // Open audio control structure - if ((ahi_ctrl = AHI_AllocAudio( - AHIA_AudioID, ahi_id, - AHIA_MixFreq, AudioStatus.sample_rate >> 16, - AHIA_Channels, 1, - AHIA_Sounds, 2, - AHIA_SoundFunc, (ULONG)&sf_hook, - TAG_END)) == NULL) { - WarningAlert(GetString(STR_NO_AHI_CTRL_WARN)); - return; - } - - ULONG max_channels, sample_rate, frequencies, sample_rate_index; - - AHI_GetAudioAttrs(ahi_id, ahi_ctrl, - AHIDB_MaxChannels, (ULONG) &max_channels, - AHIDB_Frequencies, (ULONG) &frequencies, - TAG_END); - - D(bug("AudioInit: max_channels=%ld frequencies=%ld\n", max_channels, frequencies)); - - for (int n=0; n> 3) * AudioStatus.channels * audio_frames_per_block; - - // Prepare SampleInfos and load sounds (two sounds for double buffering) - sample[0].ahisi_Type = AudioStatus.sample_size == 16 ? AHIST_S16S : AHIST_S8S; - sample[0].ahisi_Length = audio_frames_per_block; - sample[0].ahisi_Address = AllocVec(sound_buffer_size, MEMF_PUBLIC | MEMF_CLEAR); - sample[1].ahisi_Type = AudioStatus.sample_size == 16 ? AHIST_S16S : AHIST_S8S; - sample[1].ahisi_Length = audio_frames_per_block; - sample[1].ahisi_Address = AllocVec(sound_buffer_size, MEMF_PUBLIC | MEMF_CLEAR); - if (sample[0].ahisi_Address == NULL || sample[1].ahisi_Address == NULL) - return; - - AHI_LoadSound(0, AHIST_DYNAMICSAMPLE, &sample[0], ahi_ctrl); - AHI_LoadSound(1, AHIST_DYNAMICSAMPLE, &sample[1], ahi_ctrl); - - // Set parameters - play_buf = 0; - current_main_volume = current_speaker_volume = 0x10000; - AHI_SetVol(0, current_speaker_volume, 0x8000, ahi_ctrl, AHISF_IMM); - - AHI_SetFreq(0, AudioStatus.sample_rate >> 16, ahi_ctrl, AHISF_IMM); - AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, AHISF_IMM); - - // Everything OK - audio_open = true; -} - - -/* - * Deinitialization - */ - -void AudioExit(void) -{ - // Free everything - if (ahi_ctrl != NULL) { - AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END); - AHI_FreeAudio(ahi_ctrl); - } - - FreeVec(sample[0].ahisi_Address); - FreeVec(sample[1].ahisi_Address); -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - AHI_ControlAudio(ahi_ctrl, AHIC_Play, TRUE, TAG_END); -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - AHI_ControlAudio(ahi_ctrl, AHIC_Play, FALSE, TAG_END); -} - - -/* - * AHI sound callback, request next buffer - */ - -static __saveds __attribute__((regparm(3))) ULONG audio_callback(struct Hook *hook /*a0*/, struct AHISoundMessage *msg /*a1*/, struct AHIAudioCtrl *ahi_ctrl /*a2*/) -{ - play_buf ^= 1; - - // New buffer available? - if (audio_block_fetched) - { - audio_block_fetched--; - - if (main_mute || speaker_mute) - { - memset(sample[play_buf].ahisi_Address, 0, sound_buffer_size); - } - else - { - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - int32 sample_count = ReadMacInt32(apple_stream_info + scd_sampleCount); - - uint32 num_channels = ReadMacInt16(apple_stream_info + scd_numChannels); - uint32 sample_size = ReadMacInt16(apple_stream_info + scd_sampleSize); - uint32 sample_rate = ReadMacInt32(apple_stream_info + scd_sampleRate); - - D(bug("stream: sample_count=%ld num_channels=%ld sample_size=%ld sample_rate=%ld\n", sample_count, num_channels, sample_size, sample_rate >> 16)); - - // Yes, this can happen. - if(sample_count != 0) { - if(sample_rate != AudioStatus.sample_rate) { - audio_set_sample_rate_byval(sample_rate); - } - if(num_channels != AudioStatus.channels) { - audio_set_channels_byval(num_channels); - } - if(sample_size != AudioStatus.sample_size) { - audio_set_sample_size_byval(sample_size); - } - } - - if (sample_count < 0) - sample_count = 0; - - int work_size = sample_count * num_channels * (sample_size>>3); - D(bug("stream: work_size=%ld sound_buffer_size=%ld\n", work_size, sound_buffer_size)); - - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - - // Put data into AHI buffer (convert 8-bit data unsigned->signed) - if (AudioStatus.sample_size == 16) - Mac2Host_memcpy(sample[play_buf].ahisi_Address, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - else { - uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - uint32 *q = (uint32 *)sample[play_buf].ahisi_Address; - int r = work_size >> 2; - while (r--) - *q++ = *p++ ^ 0x80808080; - } - if (work_size != sound_buffer_size) - memset((uint8 *)sample[play_buf].ahisi_Address + work_size, 0, sound_buffer_size - work_size); - } - } - - } - else - memset(sample[play_buf].ahisi_Address, 0, sound_buffer_size); - - // Play next buffer - AHI_SetSound(0, play_buf, 0, 0, ahi_ctrl, 0); - - // Trigger audio interrupt to get new buffer - if (AudioStatus.num_sources) { - D1(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - } - return 0; -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D1(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D1(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - audio_block_fetched++; - D1(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. arrays - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -void audio_set_sample_rate_byval(uint32 value) -{ - bool changed = (AudioStatus.sample_rate != value); - if(changed) - { - ULONG sample_rate_index; - - // get index of sample rate closest to Hz - AHI_GetAudioAttrs(ahi_id, ahi_ctrl, - AHIDB_IndexArg, value >> 16, - AHIDB_Index, (ULONG) &sample_rate_index, - TAG_END); - - D(bug(" audio_set_sample_rate_byval requested rate=%ld Hz\n", value >> 16)); - - AudioStatus.sample_rate = audio_sample_rates[sample_rate_index]; - - AHI_SetFreq(0, AudioStatus.sample_rate >> 16, ahi_ctrl, 0); - } - - D(bug(" audio_set_sample_rate_byval rate=%ld Hz\n", AudioStatus.sample_rate >> 16)); -} - -void audio_set_sample_size_byval(uint32 value) -{ - bool changed = (AudioStatus.sample_size != value); - if(changed) { -// AudioStatus.sample_size = value; -// update_sound_parameters(); -// WritePrivateProfileInt( "Audio", "SampleSize", AudioStatus.sample_size, ini_file_name ); - } - D(bug(" audio_set_sample_size_byval %d\n", AudioStatus.sample_size)); -} - -void audio_set_channels_byval(uint32 value) -{ - bool changed = (AudioStatus.channels != value); - if(changed) { -// AudioStatus.channels = value; -// update_sound_parameters(); -// WritePrivateProfileInt( "Audio", "Channels", AudioStatus.channels, ini_file_name ); - } - D(bug(" audio_set_channels_byval %d\n", AudioStatus.channels)); -} - -bool audio_set_sample_rate(int index) -{ - if(index >= 0 && index < audio_sample_rates.size() ) { - audio_set_sample_rate_byval( audio_sample_rates[index] ); - D(bug(" audio_set_sample_rate index=%ld rate=%ld\n", index, AudioStatus.sample_rate >> 16)); - } - - return true; -} - -bool audio_set_sample_size(int index) -{ - if(index >= 0 && index < audio_sample_sizes.size() ) { - audio_set_sample_size_byval( audio_sample_sizes[index] ); - D(bug(" audio_set_sample_size %d,%d\n", index,AudioStatus.sample_size)); - } - - return true; -} - -bool audio_set_channels(int index) -{ - if(index >= 0 && index < audio_channel_counts.size() ) { - audio_set_channels_byval( audio_channel_counts[index] ); - D(bug(" audio_set_channels %d,%d\n", index,AudioStatus.channels)); - } - - return true; -} - - -/* - * Get/set volume controls (volume values received/returned have the left channel - * volume in the upper 16 bits and the right channel volume in the lower 16 bits; - * both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume")) - */ - -bool audio_get_main_mute(void) -{ - D(bug("audio_get_main_mute: mute=%ld\n", main_mute)); - - return main_mute; -} - -uint32 audio_get_main_volume(void) -{ - D(bug("audio_get_main_volume\n")); - - ULONG volume = current_main_volume >> 8; // 0x10000 => 0x100 - - D(bug("audio_get_main_volume: volume=%08lx\n", volume)); - - return (volume << 16) + volume; - - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - D(bug("audio_get_speaker_mute: mute=%ld\n", speaker_mute)); - - return speaker_mute; -} - -uint32 audio_get_speaker_volume(void) -{ - D(bug("audio_get_speaker_volume: \n")); - - if (audio_open) - { - ULONG volume = current_speaker_volume >> 8; // 0x10000 => 0x100 - - D(bug("audio_get_speaker_volume: volume=%08lx\n", volume)); - - return (volume << 16) + volume; - } - - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ - D(bug("audio_set_main_mute: mute=%ld\n", mute)); - - if (mute != main_mute) - { - main_mute = mute; - } -} - -void audio_set_main_volume(uint32 vol) -{ - D(bug("audio_set_main_volume: vol=%08lx\n", vol)); - - if (audio_open && supports_volume_changes) - { - ULONG volume = 0x80 * ((vol >> 16) + (vol & 0xffff)); - - D(bug("audio_set_main_volume: volume=%08lx\n", volume)); - - current_main_volume = volume; - - AHI_SetVol(0, volume, 0x8000, ahi_ctrl, AHISF_IMM); - } -} - -void audio_set_speaker_mute(bool mute) -{ - D(bug("audio_set_speaker_mute: mute=%ld\n", mute)); - - if (mute != speaker_mute) - { - speaker_mute = mute; - } -} - -void audio_set_speaker_volume(uint32 vol) -{ - D(bug("audio_set_speaker_volume: vol=%08lx\n", vol)); - - if (audio_open && supports_volume_changes) - { - ULONG volume = 0x80 * ((vol >> 16) + (vol & 0xffff)); - - D(bug("audio_set_speaker_volume: volume=%08lx\n", volume)); - - current_speaker_volume = volume; - - AHI_SetVol(0, volume, 0x8000, ahi_ctrl, AHISF_IMM); - } -} diff --git a/BasiliskII/src/AmigaOS/clip_amiga.cpp b/BasiliskII/src/AmigaOS/clip_amiga.cpp deleted file mode 100644 index 10336bbd2..000000000 --- a/BasiliskII/src/AmigaOS/clip_amiga.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * clip_amiga.cpp - Clipboard handling, AmigaOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "clip.h" -#include "prefs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static struct IFFHandle *iffw = NULL; -static struct ClipboardHandle *ch = NULL; -static bool clipboard_open = false; -static bool no_clip_conversion; - - -// Conversion tables -static const uint8 mac2iso[0x80] = { - 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, - 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, - 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, - 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, - 0x2b, 0xb0, 0xa2, 0xa3, 0xa7, 0xb7, 0xb6, 0xdf, - 0xae, 0xa9, 0x20, 0xb4, 0xa8, 0x23, 0xc6, 0xd8, - 0x20, 0xb1, 0x3c, 0x3e, 0xa5, 0xb5, 0xf0, 0x53, - 0x50, 0x70, 0x2f, 0xaa, 0xba, 0x4f, 0xe6, 0xf8, - 0xbf, 0xa1, 0xac, 0x2f, 0x66, 0x7e, 0x44, 0xab, - 0xbb, 0x2e, 0x20, 0xc0, 0xc3, 0xd5, 0x4f, 0x6f, - 0x2d, 0x2d, 0x22, 0x22, 0x60, 0x27, 0xf7, 0x20, - 0xff, 0x59, 0x2f, 0xa4, 0x3c, 0x3e, 0x66, 0x66, - 0x23, 0xb7, 0x2c, 0x22, 0x25, 0xc2, 0xca, 0xc1, - 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, - 0x20, 0xd2, 0xda, 0xdb, 0xd9, 0x69, 0x5e, 0x7e, - 0xaf, 0x20, 0xb7, 0xb0, 0xb8, 0x22, 0xb8, 0x20 -}; - - -/* - * Initialization - */ - -void ClipInit(void) -{ - no_clip_conversion = PrefsFindBool("noclipconversion"); - - // Create clipboard IFF handle - iffw = AllocIFF(); - if (iffw) { - ch = OpenClipboard(PRIMARY_CLIP); - if (ch) { - iffw->iff_Stream = (ULONG)ch; - InitIFFasClip(iffw); - clipboard_open = true; - } - } -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ - if (ch) - CloseClipboard(ch); - if (iffw) - FreeIFF(iffw); -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %08lx, length %ld\n", type, scrap, length)); - if (length <= 0 || !clipboard_open) - return; - - switch (type) { - case 'TEXT': { - D(bug(" clipping TEXT\n")); - - // Open IFF stream - if (OpenIFF(iffw, IFFF_WRITE)) - break; - - // Convert text from Mac charset to ISO-Latin1 - uint8 *buf = new uint8[length]; - uint8 *p = (uint8 *)scrap; - uint8 *q = buf; - for (int i=0; i LF - c = 10; - } else if (!no_clip_conversion) - c = mac2iso[c & 0x7f]; - *q++ = c; - } - - // Write text - if (!PushChunk(iffw, 'FTXT', 'FORM', IFFSIZE_UNKNOWN)) { - if (!PushChunk(iffw, 0, 'CHRS', IFFSIZE_UNKNOWN)) { - WriteChunkBytes(iffw, scrap, length); - PopChunk(iffw); - } - PopChunk(iffw); - } - - // Close IFF stream - CloseIFF(iffw); - delete[] buf; - break; - } - } -} diff --git a/BasiliskII/src/AmigaOS/ether_amiga.cpp b/BasiliskII/src/AmigaOS/ether_amiga.cpp deleted file mode 100644 index 99121a24f..000000000 --- a/BasiliskII/src/AmigaOS/ether_amiga.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/* - * ether_amiga.cpp - Ethernet device driver, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "macos_util.h" -#include "ether.h" -#include "ether_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// These messages are sent to the network process -const uint32 MSG_CLEANUP = 'clea'; // Remove all protocols -const uint32 MSG_ADD_MULTI = 'addm'; // Add multicast address -const uint32 MSG_DEL_MULTI = 'delm'; // Add multicast address -const uint32 MSG_ATTACH_PH = 'atph'; // Attach protocol handler -const uint32 MSG_DETACH_PH = 'deph'; // Attach protocol handler -const uint32 MSG_WRITE = 'writ'; // Write packet - -struct NetMessage : public Message { - NetMessage(uint32 what_, const struct MsgPort *reply_port) - { - what = what_; - mn_ReplyPort = (struct MsgPort *)reply_port; - mn_Length = sizeof(*this); - } - uint32 what; - uint32 pointer; - uint16 type; - int16 result; -}; - - -// List of attached protocols -static const int NUM_READ_REQUESTS = 32; // Number of read requests that are sent to device in advance - -struct NetProtocol : public Node { - struct IOSana2Req read_io[NUM_READ_REQUESTS]; - uint8 read_buf[NUM_READ_REQUESTS][1518]; // 14 bytes header, 1500 bytes data, 4 bytes CRC - uint16 type; - uint32 handler; -}; - -static struct List prot_list; - - -// Global variables -static struct Process *net_proc = NULL; // Network device handler process -static bool proc_error; // Flag: process didn't initialize -static struct MsgPort *proc_port = NULL; // Message port of process, for communication with main task -static struct MsgPort *reply_port = NULL; // Reply port for communication with process -static struct MsgPort *read_port = NULL; // Reply port for read IORequests (set up and owned by network process) - -static bool write_done = false; // Flag: write request done - -extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp) - - -// Prototypes -static void net_func(void); - - -/* - * Send message to network process - */ - -static int16 send_to_proc(uint32 what, uint32 pointer = 0, uint16 type = 0) -{ - D(bug("sending %08lx to net_proc\n", what)); - NetMessage msg(what, reply_port); - msg.pointer = pointer; - msg.type = type; - PutMsg(proc_port, &msg); - WaitPort(reply_port); - GetMsg(reply_port); - D(bug(" sent\n")); - return msg.result; -} - - -/* - * Initialization - */ - -bool ether_init(void) -{ - // Do nothing if no Ethernet device specified - if (PrefsFindString("ether") == NULL) - return false; - - // Initialize protocol list - NewList(&prot_list); - - // Create message port - reply_port = CreateMsgPort(); - if (reply_port == NULL) - goto open_error; - D(bug("signal mask %08lx\n", 1 << reply_port->mp_SigBit)); - - // Start process - proc_error = false; - SetSignal(0, SIGF_SINGLE); - net_proc = CreateNewProcTags( - NP_Entry, (ULONG)net_func, - NP_Name, (ULONG)"Basilisk II Ethernet Task", - NP_Priority, 1, - TAG_END - ); - if (net_proc == NULL) - goto open_error; - - // Wait for signal from process - Wait(SIGF_SINGLE); - - // Initialization error? Then bail out - if (proc_error) - goto open_error; - - // Everything OK - return true; - -open_error: - net_proc = NULL; - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } - return false; -} - - -/* - * Deinitialization - */ - -void ether_exit(void) -{ - // Stop process - if (net_proc) { - SetSignal(0, SIGF_SINGLE); - Signal(&net_proc->pr_Task, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - } - - // Delete reply port - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } -} - - -/* - * Reset - */ - -void ether_reset(void) -{ - // Remove all protocols - if (net_proc) - send_to_proc(MSG_CLEANUP); -} - - -/* - * Add multicast address - */ - -int16 ether_add_multicast(uint32 pb) -{ - return send_to_proc(MSG_ADD_MULTI, pb); -} - - -/* - * Delete multicast address - */ - -int16 ether_del_multicast(uint32 pb) -{ - return send_to_proc(MSG_DEL_MULTI, pb); -} - - -/* - * Attach protocol handler - */ - -int16 ether_attach_ph(uint16 type, uint32 handler) -{ - return send_to_proc(MSG_ATTACH_PH, handler, type); -} - - -/* - * Detach protocol handler - */ - -int16 ether_detach_ph(uint16 type) -{ - return send_to_proc(MSG_DETACH_PH, type); -} - - -/* - * Transmit raw ethernet packet - */ - -int16 ether_write(uint32 wds) -{ - send_to_proc(MSG_WRITE, wds); - return 1; // Command in progress -} - - -/* - * Remove protocol from protocol list - */ - -static void remove_protocol(NetProtocol *p) -{ - // Remove from list - Forbid(); - Remove(p); - Permit(); - - // Cancel read requests - for (int i=0; iread_io + i)); - WaitIO((struct IORequest *)(p->read_io + i)); - } - - // Free protocol struct - FreeMem(p, sizeof(NetProtocol)); -} - - -/* - * Remove all protocols - */ - -static void remove_all_protocols(void) -{ - NetProtocol *n = (NetProtocol *)prot_list.lh_Head, *next; - while ((next = (NetProtocol *)n->ln_Succ) != NULL) { - remove_protocol(n); - n = next; - } -} - - -/* - * Copy received network packet to Mac side - */ - -static __saveds __regargs LONG copy_to_buff(uint8 *to /*a0*/, uint8 *from /*a1*/, uint32 packet_len /*d0*/) -{ - D(bug("CopyToBuff to %08lx, from %08lx, size %08lx\n", to, from, packet_len)); - - // It would be more efficient (and take up less memory) if we - // could invoke the packet handler from here. But we don't know - // in what context we run, so calling Execute68k() would not be - // a good idea, and even worse, we might run inside a hardware - // interrupt, so we can't even trigger a Basilisk interrupt from - // here and wait for its completion. - CopyMem(from, to, packet_len); -#if MONITOR - bug("Receiving Ethernet packet:\n"); - for (int i=0; imp_SigBit; - - // Create message ports for device I/O - read_port = CreateMsgPort(); - if (read_port == NULL) - goto quit; - read_mask = 1 << read_port->mp_SigBit; - write_port = CreateMsgPort(); - if (write_port == NULL) - goto quit; - write_mask = 1 << write_port->mp_SigBit; - control_port = CreateMsgPort(); - if (control_port == NULL) - goto quit; - - // Create control IORequest - control_io = (struct IOSana2Req *)CreateIORequest(control_port, sizeof(struct IOSana2Req)); - if (control_io == NULL) - goto quit; - control_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - - // Parse device name - char dev_name[256]; - ULONG dev_unit; - - str = PrefsFindString("ether"); - if (str) { - const char *FirstSlash = strchr(str, '/'); - const char *LastSlash = strrchr(str, '/'); - - if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { - - // Device name contains path, i.e. "Networks/xyzzy.device" - const char *lp = str; - char *dp = dev_name; - - while (lp != LastSlash) - *dp++ = *lp++; - *dp = '\0'; - - if (strlen(dev_name) < 1) - goto quit; - - if (sscanf(LastSlash, "/%ld", &dev_unit) != 1) - goto quit; - } else { - if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) != 2) - goto quit; - } - } else - goto quit; - - // Open device - control_io->ios2_BufferManagement = buffer_tags; - od_error = OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)control_io, 0); - if (od_error != 0 || control_io->ios2_Req.io_Device == 0) { - printf("WARNING: OpenDevice(<%s>, unit=%d) returned error %d)\n", (UBYTE *)dev_name, dev_unit, od_error); - goto quit; - } - opened = true; - - // Is it Ethernet? - control_io->ios2_Req.io_Command = S2_DEVICEQUERY; - control_io->ios2_StatData = (void *)&query_data; - DoIO((struct IORequest *)control_io); - if (control_io->ios2_Req.io_Error) - goto quit; - if (query_data.HardwareType != S2WireType_Ethernet) { - WarningAlert(GetString(STR_NOT_ETHERNET_WARN)); - goto quit; - } - - // Yes, create IORequest for writing - write_io = (struct IOSana2Req *)CreateIORequest(write_port, sizeof(struct IOSana2Req)); - if (write_io == NULL) - goto quit; - memcpy(write_io, control_io, sizeof(struct IOSana2Req)); - write_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - write_io->ios2_Req.io_Message.mn_ReplyPort = write_port; - - // Configure Ethernet - control_io->ios2_Req.io_Command = S2_GETSTATIONADDRESS; - DoIO((struct IORequest *)control_io); - memcpy(ether_addr, control_io->ios2_DstAddr, 6); - memcpy(control_io->ios2_SrcAddr, control_io->ios2_DstAddr, 6); - control_io->ios2_Req.io_Command = S2_CONFIGINTERFACE; - DoIO((struct IORequest *)control_io); - D(bug("Ethernet address %08lx %08lx\n", *(uint32 *)ether_addr, *(uint16 *)(ether_addr + 4))); - - // Initialization went well, inform main task - proc_error = false; - Signal(MainTask, SIGF_SINGLE); - - // Main loop - for (;;) { - - // Wait for I/O and messages (CTRL_C is used for quitting the task) - ULONG sig = Wait(proc_port_mask | read_mask | write_mask | SIGBREAKF_CTRL_C); - - // Main task wants to quit us - if (sig & SIGBREAKF_CTRL_C) - break; - - // Main task sent a command to us - if (sig & proc_port_mask) { - struct NetMessage *msg; - while (msg = (NetMessage *)GetMsg(proc_port)) { - D(bug("net_proc received %08lx\n", msg->what)); - switch (msg->what) { - case MSG_CLEANUP: - remove_all_protocols(); - break; - - case MSG_ADD_MULTI: - control_io->ios2_Req.io_Command = S2_ADDMULTICASTADDRESS; - Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); - DoIO((struct IORequest *)control_io); - if (control_io->ios2_Req.io_Error == S2ERR_NOT_SUPPORTED) { - WarningAlert(GetString(STR_NO_MULTICAST_WARN)); - msg->result = noErr; - } else if (control_io->ios2_Req.io_Error) - msg->result = eMultiErr; - else - msg->result = noErr; - break; - - case MSG_DEL_MULTI: - control_io->ios2_Req.io_Command = S2_DELMULTICASTADDRESS; - Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); - DoIO((struct IORequest *)control_io); - if (control_io->ios2_Req.io_Error) - msg->result = eMultiErr; - else - msg->result = noErr; - break; - - case MSG_ATTACH_PH: { - uint16 type = msg->type; - uint32 handler = msg->pointer; - - // Protocol of that type already installed? - NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next; - while ((next = (NetProtocol *)p->ln_Succ) != NULL) { - if (p->type == type) { - msg->result = lapProtErr; - goto reply; - } - p = next; - } - - // Allocate NetProtocol, set type and handler - p = (NetProtocol *)AllocMem(sizeof(NetProtocol), MEMF_PUBLIC); - if (p == NULL) { - msg->result = lapProtErr; - goto reply; - } - p->type = type; - p->handler = handler; - - // Set up and submit read requests - for (int i=0; iread_io + i, control_io, sizeof(struct IOSana2Req)); - p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Name = (char *)p; // Hide pointer to NetProtocol in node name - p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - p->read_io[i].ios2_Req.io_Message.mn_ReplyPort = read_port; - p->read_io[i].ios2_Req.io_Command = CMD_READ; - p->read_io[i].ios2_PacketType = type; - p->read_io[i].ios2_Data = p->read_buf[i]; - p->read_io[i].ios2_Req.io_Flags = SANA2IOF_RAW; - BeginIO((struct IORequest *)(p->read_io + i)); - } - - // Add protocol to list - AddTail(&prot_list, p); - - // Everything OK - msg->result = noErr; - break; - } - - case MSG_DETACH_PH: { - uint16 type = msg->type; - msg->result = lapProtErr; - NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next; - while ((next = (NetProtocol *)p->ln_Succ) != NULL) { - if (p->type == type) { - remove_protocol(p); - msg->result = noErr; - break; - } - p = next; - } - break; - } - - case MSG_WRITE: { - // Get pointer to Write Data Structure - uint32 wds = msg->pointer; - write_io->ios2_Data = (void *)wds; - - // Calculate total packet length - long len = 0; - uint32 tmp = wds; - for (;;) { - int16 w = ReadMacInt16(tmp); - if (w == 0) - break; - len += w; - tmp += 6; - } - write_io->ios2_DataLength = len; - - // Get destination address - uint32 hdr = ReadMacInt32(wds + 2); - Mac2Host_memcpy(write_io->ios2_DstAddr, hdr, 6); - - // Get packet type - uint32 type = ReadMacInt16(hdr + 12); - if (type <= 1500) - type = 0; // 802.3 packet - write_io->ios2_PacketType = type; - - // Multicast/broadcard packet? - if (write_io->ios2_DstAddr[0] & 1) { - if (*(uint32 *)(write_io->ios2_DstAddr) == 0xffffffff && *(uint16 *)(write_io->ios2_DstAddr + 4) == 0xffff) - write_io->ios2_Req.io_Command = S2_BROADCAST; - else - write_io->ios2_Req.io_Command = S2_MULTICAST; - } else - write_io->ios2_Req.io_Command = CMD_WRITE; - - // Send packet - write_done = false; - write_io->ios2_Req.io_Flags = SANA2IOF_RAW; - BeginIO((IORequest *)write_io); - break; - } - } -reply: D(bug(" net_proc replying\n")); - ReplyMsg(msg); - } - } - - // Packet received - if (sig & read_mask) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - - // Packet write completed - if (sig & write_mask) { - GetMsg(write_port); - WriteMacInt32(ether_data + ed_Result, write_io->ios2_Req.io_Error ? excessCollsns : 0); - write_done = true; - D(bug(" packet write done, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - } -quit: - - // Close everything - remove_all_protocols(); - if (opened) { - if (CheckIO((struct IORequest *)write_io) == 0) { - AbortIO((struct IORequest *)write_io); - WaitIO((struct IORequest *)write_io); - } - CloseDevice((struct IORequest *)control_io); - } - if (write_io) - DeleteIORequest(write_io); - if (control_io) - DeleteIORequest(control_io); - if (control_port) - DeleteMsgPort(control_port); - if (write_port) - DeleteMsgPort(write_port); - if (read_port) - DeleteMsgPort(read_port); - - // Send signal to main task to confirm termination - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -/* - * Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers - */ - -void EtherInterrupt(void) -{ - D(bug("EtherIRQ\n")); - - // Packet write done, enqueue DT to call IODone - if (write_done) { - EnqueueMac(ether_data + ed_DeferredTask, 0xd92); - write_done = false; - } - - // Call protocol handler for received packets - IOSana2Req *io; - while (io = (struct IOSana2Req *)GetMsg(read_port)) { - - // Get pointer to NetProtocol (hidden in node name) - NetProtocol *p = (NetProtocol *)io->ios2_Req.io_Message.mn_Node.ln_Name; - - // No default handler - if (p->handler == 0) - continue; - - // Copy header to RHA - Host2Mac_memcpy(ether_data + ed_RHA, io->ios2_Data, 14); - D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); - - // Call protocol handler - M68kRegisters r; - r.d[0] = *(uint16 *)((uint32)io->ios2_Data + 12); // Packet type - r.d[1] = io->ios2_DataLength - 18; // Remaining packet length (without header, for ReadPacket) (-18 because the CRC is also included) - r.a[0] = (uint32)io->ios2_Data + 14; // Pointer to packet (host address, for ReadPacket) - r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA - r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines - D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", p->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); - Execute68k(p->handler, &r); - - // Resend IORequest - io->ios2_Req.io_Flags = SANA2IOF_RAW; - BeginIO((struct IORequest *)io); - } - D(bug(" EtherIRQ done\n")); -} diff --git a/BasiliskII/src/AmigaOS/extfs_amiga.cpp b/BasiliskII/src/AmigaOS/extfs_amiga.cpp deleted file mode 100644 index 9f157e294..000000000 --- a/BasiliskII/src/AmigaOS/extfs_amiga.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - * extfs_amiga.cpp - MacOS file system for access native file system access, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#define __USE_SYSBASE -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "extfs.h" -#include "extfs_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Default Finder flags -const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited; - - -/* - * Initialization - */ - -void extfs_init(void) -{ -} - - -/* - * Deinitialization - */ - -void extfs_exit(void) -{ -} - - -/* - * Add component to path name - */ - -void add_path_component(char *path, const char *component) -{ - AddPart(path, (char *)component, MAX_PATH_LENGTH); -} - - -/* - * Finder info and resource forks are kept in helper files - * - * Finder info: - * /path/.finf/file - * Resource fork: - * /path/.rsrc/file - * - * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo - * (16+16 bytes) - */ - -static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false) -{ - dest[0] = 0; - - // Get pointer to last component of path - const char *last_part = FilePart((char *)src); - - // Copy everything before - strncpy(dest, src, last_part-src); - dest[last_part-src] = 0; - - // Add additional component - AddPart(dest, (char *)add, MAX_PATH_LENGTH); - - // Add last component - if (!only_dir) - AddPart(dest, (char *)last_part, MAX_PATH_LENGTH); -} - -static int create_helper_dir(const char *path, const char *add) -{ - char helper_dir[MAX_PATH_LENGTH]; - make_helper_path(path, helper_dir, add, true); - if (helper_dir[strlen(helper_dir) - 1] == '/') // Remove trailing "/" - helper_dir[strlen(helper_dir) - 1] = 0; - return mkdir(helper_dir, 0777); -} - -static int open_helper(const char *path, const char *add, int flag) -{ - char helper_path[MAX_PATH_LENGTH]; - make_helper_path(path, helper_path, add); - - if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY) - flag |= O_CREAT; - int fd = open(helper_path, flag, 0666); - if (fd < 0) { - if (errno == ENOENT && (flag & O_CREAT)) { - // One path component was missing, probably the helper - // directory. Try to create it and re-open the file. - int ret = create_helper_dir(path, add); - if (ret < 0) - return ret; - fd = open(helper_path, flag, 0666); - } - } - return fd; -} - -static int open_finf(const char *path, int flag) -{ - return open_helper(path, ".finf/", flag); -} - -static int open_rsrc(const char *path, int flag) -{ - return open_helper(path, ".rsrc/", flag); -} - - -/* - * Get/set finder type/creator for file specified by full path - */ - -struct ext2type { - const char *ext; - uint32 type; - uint32 creator; -}; - -static const ext2type e2t_translation[] = { - {".z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')}, - {".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')}, - {".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')}, - {".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')}, - {".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')}, - {".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')}, - {".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')}, - {".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')}, - {".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')}, - {".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')}, - {".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')}, - {".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')}, - {".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')}, - {".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')}, - {".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')}, - {".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')}, - {".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')}, - {".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')}, - {".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')}, - {".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')}, - {".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')}, - {".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')}, - {".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')}, - {".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')}, - {".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')}, - {".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')}, - {".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')}, - {".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')}, - {".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')}, - {".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')}, - {".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')}, - {".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')}, - {".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')}, - {".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')}, - {NULL, 0, 0} // End marker -}; - -void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Set default finder info - Mac_memset(finfo, 0, SIZEOF_FInfo); - if (fxinfo) - Mac_memset(fxinfo, 0, SIZEOF_FXInfo); - WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); - WriteMacInt32(finfo + fdLocation, (uint32)-1); - - // Read Finder info file - int fd = open_finf(path, O_RDONLY); - if (fd >= 0) { - ssize_t actual = read(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); - if (fxinfo) - actual += read(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); - close(fd); - if (actual >= SIZEOF_FInfo) - return; - } - - // No Finder info file, translate file name extension to MacOS type/creator - if (!is_dir) { - int path_len = strlen(path); - for (int i=0; e2t_translation[i].ext; i++) { - int ext_len = strlen(e2t_translation[i].ext); - if (path_len < ext_len) - continue; - if (!strcasecmp(path + path_len - ext_len, e2t_translation[i].ext)) { - WriteMacInt32(finfo + fdType, e2t_translation[i].type); - WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator); - break; - } - } - } -} - -void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Open Finder info file - int fd = open_finf(path, O_RDWR); - if (fd < 0) - return; - - // Write file - write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo); - if (fxinfo) - write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo); - close(fd); -} - - -/* - * Resource fork emulation functions - */ - -uint32 get_rfork_size(const char *path) -{ - // Open resource file - int fd = open_rsrc(path, O_RDONLY); - if (fd < 0) - return 0; - - // Get size - off_t size = lseek(fd, 0, SEEK_END); - - // Close file and return size - close(fd); - return size < 0 ? 0 : size; -} - -int open_rfork(const char *path, int flag) -{ - return open_rsrc(path, flag); -} - -void close_rfork(const char *path, int fd) -{ - close(fd); -} - - -/* - * Read "length" bytes from file to "buffer", - * returns number of bytes read (or -1 on error) - */ - -ssize_t extfs_read(int fd, void *buffer, size_t length) -{ - return read(fd, buffer, length); -} - - -/* - * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or -1 on error) - */ - -ssize_t extfs_write(int fd, void *buffer, size_t length) -{ - return write(fd, buffer, length); -} - - -/* - * Remove file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_remove(const char *path) -{ - // Remove helpers first, don't complain if this fails - char helper_path[MAX_PATH_LENGTH]; - make_helper_path(path, helper_path, ".finf/", false); - remove(helper_path); - make_helper_path(path, helper_path, ".rsrc/", false); - remove(helper_path); - - // Now remove file or directory (and helper directories in the directory) - if (remove(path) < 0) { - if (errno == EISDIR || errno == ENOTEMPTY) { - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".finf"); - rmdir(helper_path); - helper_path[0] = 0; - strncpy(helper_path, path, MAX_PATH_LENGTH-1); - add_path_component(helper_path, ".rsrc"); - rmdir(helper_path); - return rmdir(path) == 0; - } else - return false; - } - return true; -} - - -/* - * Rename/move file/directory (and associated helper files), - * returns false on error (and sets errno) - */ - -bool extfs_rename(const char *old_path, const char *new_path) -{ - // Rename helpers first, don't complain if this fails - char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH]; - make_helper_path(old_path, old_helper_path, ".finf/", false); - make_helper_path(new_path, new_helper_path, ".finf/", false); - create_helper_dir(new_path, ".finf/"); - rename(old_helper_path, new_helper_path); - make_helper_path(old_path, old_helper_path, ".rsrc/", false); - make_helper_path(new_path, new_helper_path, ".rsrc/", false); - create_helper_dir(new_path, ".rsrc/"); - rename(old_helper_path, new_helper_path); - - // Now rename file - return rename(old_path, new_path) == 0; -} - - -/* - * ftruncate() is missing from libnix - */ - -extern unsigned long *__stdfiledes; - -int ftruncate(int fd, off_t size) -{ - if (SetFileSize(__stdfiledes[fd], size, OFFSET_BEGINNING) < 0) - return -1; - else - return 0; -} diff --git a/BasiliskII/src/AmigaOS/main_amiga.cpp b/BasiliskII/src/AmigaOS/main_amiga.cpp deleted file mode 100644 index 90ac6db23..000000000 --- a/BasiliskII/src/AmigaOS/main_amiga.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/* - * main_amiga.cpp - Startup code for AmigaOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "xpram.h" -#include "timer.h" -#include "sony.h" -#include "disk.h" -#include "cdrom.h" -#include "scsi.h" -#include "audio.h" -#include "video.h" -#include "serial.h" -#include "ether.h" -#include "clip.h" -#include "emul_op.h" -#include "rom_patches.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "sys.h" -#include "user_strings.h" -#include "version.h" - -#define DEBUG 0 -#include "debug.h" - - -// Options for libnix -unsigned long __stack = 0x4000; // Stack requirement -int __nocommandline = 1; // Disable command line parsing - - -// Constants -static const char ROM_FILE_NAME[] = "ROM"; -static const char __ver[] = "$VER: " VERSION_STRING " " __DATE__; -static const int SCRATCH_MEM_SIZE = 65536; - - -// RAM and ROM pointers -uint32 RAMBaseMac; // RAM base (Mac address space) -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - -// Global variables -extern ExecBase *SysBase; -struct Library *GfxBase = NULL; -struct IntuitionBase *IntuitionBase = NULL; -struct Library *GadToolsBase = NULL; -struct Library *IFFParseBase = NULL; -struct Library *AslBase = NULL; -struct Library *P96Base = NULL; -struct Library *CyberGfxBase = NULL; -struct Library *TimerBase = NULL; -struct Library *AHIBase = NULL; -struct Library *DiskBase = NULL; - -struct Task *MainTask; // Our task -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -APTR OldTrapHandler = NULL; // Old trap handler -APTR OldExceptionHandler = NULL; // Old exception handler -BYTE IRQSig = -1; // "Interrupt" signal number -ULONG IRQSigMask = 0; // "Interrupt" signal mask - -static struct timerequest *timereq = NULL; // IORequest for timer - -static struct MsgPort *ahi_port = NULL; // Port for AHI -static struct AHIRequest *ahi_io = NULL; // IORequest for AHI - -static struct Process *xpram_proc = NULL; // XPRAM watchdog -static volatile bool xpram_proc_active = true; // Flag for quitting the XPRAM watchdog - -static struct Process *tick_proc = NULL; // 60Hz process -static volatile bool tick_proc_active = true; // Flag for quitting the 60Hz process - -static bool stack_swapped = false; // Stack swapping -static StackSwapStruct stack_swap; - - -// Assembly functions -struct trap_regs; -extern "C" void AtomicAnd(uint32 *p, uint32 val); -extern "C" void AtomicOr(uint32 *p, uint32 val); -extern "C" void MoveVBR(void); -extern "C" void DisableSuperBypass(void); -extern "C" void TrapHandlerAsm(void); -extern "C" void ExceptionHandlerAsm(void); -extern "C" void IllInstrHandler(trap_regs *regs); -extern "C" void PrivViolHandler(trap_regs *regs); -extern "C" void quit_emulator(void); -extern "C" void AsmTriggerNMI(void); -uint16 EmulatedSR; // Emulated SR (supervisor bit and interrupt mask) - - -// Prototypes -static void jump_to_rom(void); -static void xpram_func(void); -static void tick_func(void); - - -/* - * Main program - */ - -int main(int argc, char **argv) -{ - // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; - MainTask = FindTask(NULL); - struct DateStamp ds; - DateStamp(&ds); - srand(ds.ds_Tick); - - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - - // Open libraries - GfxBase = OpenLibrary((UBYTE *) "graphics.library", 39); - if (GfxBase == NULL) { - printf("Cannot open graphics.library V39.\n"); - exit(1); - } - IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *) "intuition.library", 39); - if (IntuitionBase == NULL) { - printf("Cannot open intuition.library V39.\n"); - CloseLibrary(GfxBase); - exit(1); - } - DiskBase = (struct Library *)OpenResource((UBYTE *) "disk.resource"); - if (DiskBase == NULL) - QuitEmulator(); - GadToolsBase = OpenLibrary((UBYTE *) "gadtools.library", 39); - if (GadToolsBase == NULL) { - ErrorAlert(STR_NO_GADTOOLS_LIB_ERR); - QuitEmulator(); - } - IFFParseBase = OpenLibrary((UBYTE *) "iffparse.library", 39); - if (IFFParseBase == NULL) { - ErrorAlert(STR_NO_IFFPARSE_LIB_ERR); - QuitEmulator(); - } - AslBase = OpenLibrary((UBYTE *) "asl.library", 36); - if (AslBase == NULL) { - ErrorAlert(STR_NO_ASL_LIB_ERR); - QuitEmulator(); - } - - if (FindTask((UBYTE *) "« Enforcer »")) { - ErrorAlert(STR_ENFORCER_RUNNING_ERR); - QuitEmulator(); - } - - // These two can fail (the respective gfx support won't be available, then) - P96Base = OpenLibrary((UBYTE *) "Picasso96API.library", 2); - CyberGfxBase = OpenLibrary((UBYTE *) "cybergraphics.library", 2); - - // Read preferences - PrefsInit(NULL, argc, argv); - - // Open AHI - ahi_port = CreateMsgPort(); - if (ahi_port) { - ahi_io = (struct AHIRequest *)CreateIORequest(ahi_port, sizeof(struct AHIRequest)); - if (ahi_io) { - ahi_io->ahir_Version = 2; - if (OpenDevice((UBYTE *) AHINAME, AHI_NO_UNIT, (struct IORequest *)ahi_io, 0) == 0) { - AHIBase = (struct Library *)ahi_io->ahir_Std.io_Device; - } - } - } - - // Init system routines - SysInit(); - - // Show preferences editor - if (!PrefsFindBool("nogui")) - if (!PrefsEditor()) - QuitEmulator(); - - // Check start of Chip memory (because we need access to 0x0000..0x2000) - if ((uint32)FindName(&SysBase->MemList, (UBYTE *) "chip memory") < 0x2000) { - ErrorAlert(STR_NO_PREPARE_EMUL_ERR); - QuitEmulator(); - } - - // Open timer.device - timereq = (struct timerequest *)AllocVec(sizeof(timerequest), MEMF_PUBLIC | MEMF_CLEAR); - if (timereq == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - if (OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timereq, 0)) { - ErrorAlert(STR_NO_TIMER_DEV_ERR); - QuitEmulator(); - } - TimerBase = (struct Library *)timereq->tr_node.io_Device; - - // Allocate scratch memory - ScratchMem = (uint8 *)AllocMem(SCRATCH_MEM_SIZE, MEMF_PUBLIC); - if (ScratchMem == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block - - // Create area for Mac RAM and ROM (ROM must be higher in memory, - // so we allocate one big chunk and put the ROM at the top of it) - RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - RAMBaseHost = (uint8 *)AllocVec(RAMSize + 0x100000, MEMF_PUBLIC); - if (RAMBaseHost == NULL) { - uint32 newRAMSize = AvailMem(MEMF_LARGEST) - 0x100000; - char xText[120]; - - sprintf(xText, GetString(STR_NOT_ENOUGH_MEM_WARN), RAMSize, newRAMSize); - - if (ChoiceAlert(xText, "Use", "Quit") != 1) - QuitEmulator(); - - RAMSize = newRAMSize; - RAMBaseHost = (uint8 *)AllocVec(RAMSize - 0x100000, MEMF_PUBLIC); - if (RAMBaseHost == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - } - RAMBaseMac = (uint32)RAMBaseHost; - D(bug("Mac RAM starts at %08lx\n", RAMBaseHost)); - ROMBaseHost = RAMBaseHost + RAMSize; - ROMBaseMac = (uint32)ROMBaseHost; - D(bug("Mac ROM starts at %08lx\n", ROMBaseHost)); - - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - - // Load Mac ROM - BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE); - if (rom_fh == 0) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - QuitEmulator(); - } - printf(GetString(STR_READING_ROM_FILE)); - Seek(rom_fh, 0, OFFSET_END); - ROMSize = Seek(rom_fh, 0, OFFSET_CURRENT); - if (ROMSize != 512*1024 && ROMSize != 1024*1024) { - ErrorAlert(STR_ROM_SIZE_ERR); - Close(rom_fh); - QuitEmulator(); - } - Seek(rom_fh, 0, OFFSET_BEGINNING); - if (Read(rom_fh, ROMBaseHost, ROMSize) != ROMSize) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - Close(rom_fh); - QuitEmulator(); - } - - // Set CPU and FPU type - UWORD attn = SysBase->AttnFlags; - CPUType = attn & AFF_68040 ? 4 : (attn & AFF_68030 ? 3 : 2); - CPUIs68060 = attn & AFF_68060; - FPUType = attn & AFF_68881 ? 1 : 0; - - // Initialize everything - if (!InitAll(NULL)) - QuitEmulator(); - - // Move VBR away from 0 if neccessary - MoveVBR(); - - // On 68060, disable Super Bypass mode because of a CPU bug that is triggered by MacOS 8 - if (CPUIs68060) - DisableSuperBypass(); - - memset((UBYTE *) 8, 0, 0x2000-8); - - // Install trap handler - EmulatedSR = 0x2700; - OldTrapHandler = MainTask->tc_TrapCode; - MainTask->tc_TrapCode = (APTR)TrapHandlerAsm; - - // Allocate signal for interrupt emulation and install exception handler - IRQSig = AllocSignal(-1); - IRQSigMask = 1 << IRQSig; - OldExceptionHandler = MainTask->tc_ExceptCode; - MainTask->tc_ExceptCode = (APTR)ExceptionHandlerAsm; - SetExcept(SIGBREAKF_CTRL_C | IRQSigMask, SIGBREAKF_CTRL_C | IRQSigMask); - - // Start XPRAM watchdog process - xpram_proc = CreateNewProcTags( - NP_Entry, (ULONG)xpram_func, - NP_Name, (ULONG)"Basilisk II XPRAM Watchdog", - NP_Priority, 0, - TAG_END - ); - - // Start 60Hz process - tick_proc = CreateNewProcTags( - NP_Entry, (ULONG)tick_func, - NP_Name, (ULONG)"Basilisk II 60Hz", - NP_Priority, 5, - TAG_END - ); - - // Set task priority to -1 so we don't use all processing time - SetTaskPri(MainTask, -1); - - WriteMacInt32(0xbff, 0); // MacsBugFlags - - // Swap stack to Mac RAM area - stack_swap.stk_Lower = RAMBaseHost; - stack_swap.stk_Upper = (ULONG)RAMBaseHost + RAMSize; - stack_swap.stk_Pointer = RAMBaseHost + 0x8000; - StackSwap(&stack_swap); - stack_swapped = true; - - // Jump to ROM boot routine - Start680x0(); - - QuitEmulator(); - return 0; -} - -void Start680x0(void) -{ - typedef void (*rom_func)(void); - rom_func fp = (rom_func)(ROMBaseHost + 0x2a); - fp(); -} - - -/* - * Quit emulator (__saveds because it might be called from an exception) - */ - -// Assembly entry point -void __saveds quit_emulator(void) -{ - QuitEmulator(); -} - -void QuitEmulator(void) -{ - // Stop 60Hz process - if (tick_proc) { - SetSignal(0, SIGF_SINGLE); - tick_proc_active = false; - Wait(SIGF_SINGLE); - } - - // Stop XPRAM watchdog process - if (xpram_proc) { - SetSignal(0, SIGF_SINGLE); - xpram_proc_active = false; - Wait(SIGF_SINGLE); - } - - // Restore stack - if (stack_swapped) { - stack_swapped = false; - StackSwap(&stack_swap); - } - - // Remove exception handler - if (IRQSig >= 0) { - SetExcept(0, SIGBREAKF_CTRL_C | IRQSigMask); - MainTask->tc_ExceptCode = OldExceptionHandler; - FreeSignal(IRQSig); - } - - // Remove trap handler - MainTask->tc_TrapCode = OldTrapHandler; - - // Deinitialize everything - ExitAll(); - - // Delete RAM/ROM area - if (RAMBaseHost) - FreeVec(RAMBaseHost); - - // Delete scratch memory area - if (ScratchMem) - FreeMem((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); - - // Close timer.device - if (TimerBase) - CloseDevice((struct IORequest *)timereq); - if (timereq) - FreeVec(timereq); - - // Exit system routines - SysExit(); - - // Close AHI - if (AHIBase) - CloseDevice((struct IORequest *)ahi_io); - if (ahi_io) - DeleteIORequest((struct IORequest *)ahi_io); - if (ahi_port) - DeleteMsgPort(ahi_port); - - // Exit preferences - PrefsExit(); - - // Close libraries - if (CyberGfxBase) - CloseLibrary(CyberGfxBase); - if (P96Base) - CloseLibrary(P96Base); - if (AslBase) - CloseLibrary(AslBase); - if (IFFParseBase) - CloseLibrary(IFFParseBase); - if (GadToolsBase) - CloseLibrary(GadToolsBase); - if (IntuitionBase) - CloseLibrary((struct Library *)IntuitionBase); - if (GfxBase) - CloseLibrary(GfxBase); - - exit(0); -} - - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size) -{ - CacheClearE(start, size, CACRF_ClearI | CACRF_ClearD); -} - - -/* - * Mutexes - */ - -struct B2_mutex { - int dummy; //!! -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - - -/* - * Interrupt flags (must be handled atomically!) - */ - -uint32 InterruptFlags; - -void SetInterruptFlag(uint32 flag) -{ - AtomicOr(&InterruptFlags, flag); -} - -void ClearInterruptFlag(uint32 flag) -{ - AtomicAnd(&InterruptFlags, ~flag); -} - -void TriggerInterrupt(void) -{ - Signal(MainTask, IRQSigMask); -} - -void TriggerNMI(void) -{ - AsmTriggerNMI(); -} - - -/* - * 60Hz thread (really 60.15Hz) - */ - -static __saveds void tick_func(void) -{ - int tick_counter = 0; - struct MsgPort *timer_port = NULL; - struct timerequest *timer_io = NULL; - ULONG timer_mask = 0; - - // Start 60Hz timer - timer_port = CreateMsgPort(); - if (timer_port) { - timer_io = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest)); - if (timer_io) { - if (!OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) { - timer_mask = 1 << timer_port->mp_SigBit; - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16625; - SendIO((struct IORequest *)timer_io); - } - } - } - - while (tick_proc_active) { - - // Wait for timer tick - Wait(timer_mask); - - // Restart timer - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16625; - SendIO((struct IORequest *)timer_io); - - // Pseudo Mac 1Hz interrupt, update local time - if (++tick_counter > 60) { - tick_counter = 0; - WriteMacInt32(0x20c, TimerDateTime()); - SetInterruptFlag(INTFLAG_1HZ); - TriggerInterrupt(); - } - - // Trigger 60Hz interrupt - SetInterruptFlag(INTFLAG_60HZ); - TriggerInterrupt(); - } - - // Stop timer - if (timer_io) { - if (!CheckIO((struct IORequest *)timer_io)) - AbortIO((struct IORequest *)timer_io); - WaitIO((struct IORequest *)timer_io); - CloseDevice((struct IORequest *)timer_io); - DeleteIORequest(timer_io); - } - if (timer_port) - DeleteMsgPort(timer_port); - - // Main task asked for termination, send signal - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -/* - * XPRAM watchdog thread (saves XPRAM every minute) - */ - -static __saveds void xpram_func(void) -{ - uint8 last_xpram[XPRAM_SIZE]; - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - - while (xpram_proc_active) { - for (int i=0; i<60 && xpram_proc_active; i++) - Delay(50); // Only wait 1 second so we quit promptly when xpram_proc_active becomes false - if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) { - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - SaveXPRAM(); - } - } - - // Main task asked for termination, send signal - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_ERROR_PREFIX), text); - return; - } - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_ERROR_ALERT_TITLE); - req.es_TextFormat = (UBYTE *)GetString(STR_GUI_ERROR_PREFIX); - req.es_GadgetFormat = (UBYTE *)GetString(STR_QUIT_BUTTON); - EasyRequest(NULL, &req, NULL, (ULONG)text); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return; - } - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE); - req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX); - req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON); - EasyRequest(NULL, &req, NULL, (ULONG)text); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - char str[256]; - sprintf(str, "%s|%s", pos, neg); - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_WARNING_ALERT_TITLE); - req.es_TextFormat = (UBYTE *)GetString(STR_GUI_WARNING_PREFIX); - req.es_GadgetFormat = (UBYTE *)str; - return EasyRequest(NULL, &req, NULL, (ULONG)text); -} - - -/* - * Illegal Instruction and Privilege Violation trap handlers - */ - -struct trap_regs { // This must match the layout of M68kRegisters - uint32 d[8]; - uint32 a[8]; - uint16 sr; - uint32 pc; -}; - -void __saveds IllInstrHandler(trap_regs *r) -{ -// D(bug("IllInstrHandler/%ld\n", __LINE__)); - - uint16 opcode = *(uint16 *)(r->pc); - if ((opcode & 0xff00) != 0x7100) { - printf("Illegal Instruction %04x at %08lx\n", *(uint16 *)(r->pc), r->pc); - printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n" - "d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n" - "a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n" - "a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n" - "sr %04x\n", - r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], - r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], - r->sr); - QuitEmulator(); - } else { - // Disable interrupts - uint16 sr = EmulatedSR; - EmulatedSR |= 0x0700; - - // Call opcode routine - EmulOp(opcode, (M68kRegisters *)r); - r->pc += 2; - - // Restore interrupts - EmulatedSR = sr; - if ((EmulatedSR & 0x0700) == 0 && InterruptFlags) - Signal(MainTask, IRQSigMask); - } -} - -void __saveds PrivViolHandler(trap_regs *r) -{ - printf("Privileged instruction %04x %04x at %08lx\n", *(uint16 *)(r->pc), *(uint16 *)(r->pc + 2), r->pc); - printf("d0 %08lx d1 %08lx d2 %08lx d3 %08lx\n" - "d4 %08lx d5 %08lx d6 %08lx d7 %08lx\n" - "a0 %08lx a1 %08lx a2 %08lx a3 %08lx\n" - "a4 %08lx a5 %08lx a6 %08lx a7 %08lx\n" - "sr %04x\n", - r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7], - r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7], - r->sr); - QuitEmulator(); -} diff --git a/BasiliskII/src/AmigaOS/prefs_amiga.cpp b/BasiliskII/src/AmigaOS/prefs_amiga.cpp deleted file mode 100644 index 3d71c1de7..000000000 --- a/BasiliskII/src/AmigaOS/prefs_amiga.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * prefs_amiga.cpp - Preferences handling, AmigaOS specifix stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "sysdeps.h" -#include "prefs.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { - {"sound", TYPE_STRING, false, "sound output mode description"}, - {"scsimemtype", TYPE_INT32, false, "SCSI buffer memory type"}, - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Prefs file name -const char PREFS_FILE_NAME[] = "ENV:BasiliskII_prefs"; -const char PREFS_FILE_NAME_ARC[] = "ENVARC:BasiliskII_prefs"; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(void) -{ - // Read preferences from settings file - FILE *f = fopen(PREFS_FILE_NAME, "r"); - if (f != NULL) { - - // Prefs file found, load settings - LoadPrefsFromStream(f); - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - } -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = fopen(PREFS_FILE_NAME, "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } - if ((f = fopen(PREFS_FILE_NAME_ARC, "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsReplaceString("extfs", "WORK:"); - PrefsAddInt32("scsimemtype", 0); -} diff --git a/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp b/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp deleted file mode 100644 index f19569061..000000000 --- a/BasiliskII/src/AmigaOS/prefs_editor_amiga.cpp +++ /dev/null @@ -1,1735 +0,0 @@ -/* - * prefs_editor_amiga.cpp - Preferences editor, AmigaOS implementation (using gtlayout.library) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "xpram.h" -#include "cdrom.h" -#include "user_strings.h" -#include "version.h" -#include "prefs.h" -#include "prefs_editor.h" - - -// Gadget/menu IDs -const int MSG_OK = 0x0100; // "Start" button -const int MSG_CANCEL = 0x0101; // "Quit" button -const int MSG_ABOUT = 0x0102; // "About..." menu item -const int MSG_ZAP_PRAM = 0x0103; // "Zap PRAM" menu item - -const int GAD_PAGEGROUP = 0x0200; - -const int GAD_DISK_LIST = 0x0300; // "Volumes" pane -const int GAD_ADD_VOLUME = 0x0301; -const int GAD_EDIT_VOLUME = 0x0302; -const int GAD_REMOVE_VOLUME = 0x0303; -const int GAD_CDROM_DEVICE = 0x0304; -const int GAD_CDROM_UNIT = 0x0305; -const int GAD_BOOTDRIVER = 0x0306; -const int GAD_NOCDROM = 0x0307; -const int GAD_EXTFS = 0x0308; - -const int GAD_VOLUME_READONLY = 0x0310; // "Add/Edit Volume" window -const int GAD_VOLUME_TYPE = 0x0311; -const int GAD_VOLUME_FILE = 0x0312; -const int GAD_VOLUME_DEVICE = 0x0313; -const int GAD_VOLUME_UNIT = 0x0314; -const int GAD_VOLUME_OPENFLAGS = 0x0315; -const int GAD_VOLUME_STARTBLOCK = 0x0316; -const int GAD_VOLUME_SIZE = 0x0317; -const int GAD_VOLUME_BLOCKSIZE = 0x0318; -const int GAD_VOLUME_PAGEGROUP = 0x0319; - -const int GAD_SCSI0_DEVICE = 0x0400; // "SCSI" pane -const int GAD_SCSI1_DEVICE = 0x0401; -const int GAD_SCSI2_DEVICE = 0x0402; -const int GAD_SCSI3_DEVICE = 0x0403; -const int GAD_SCSI4_DEVICE = 0x0404; -const int GAD_SCSI5_DEVICE = 0x0405; -const int GAD_SCSI6_DEVICE = 0x0406; -const int GAD_SCSI0_UNIT = 0x0410; -const int GAD_SCSI1_UNIT = 0x0411; -const int GAD_SCSI2_UNIT = 0x0412; -const int GAD_SCSI3_UNIT = 0x0413; -const int GAD_SCSI4_UNIT = 0x0414; -const int GAD_SCSI5_UNIT = 0x0415; -const int GAD_SCSI6_UNIT = 0x0416; -const int GAD_SCSI_MEMTYPE = 0x0420; - -const int GAD_VIDEO_TYPE = 0x0500; // "Graphics/Sound" pane -const int GAD_DISPLAY_X = 0x0501; -const int GAD_DISPLAY_Y = 0x0502; -const int GAD_FRAMESKIP = 0x0503; -const int GAD_SCREEN_MODE = 0x0504; -const int GAD_AHI_MODE = 0x0505; -const int GAD_NOSOUND = 0x0506; - -const int GAD_SERIALA_DEVICE = 0x0600; // "Serial/Network" pane -const int GAD_SERIALA_UNIT = 0x0601; -const int GAD_SERIALA_ISPAR = 0x0602; -const int GAD_SERIALB_DEVICE = 0x0603; -const int GAD_SERIALB_UNIT = 0x0604; -const int GAD_SERIALB_ISPAR = 0x0605; -const int GAD_ETHER_DEVICE = 0x0606; -const int GAD_ETHER_UNIT = 0x00607; - -const int GAD_RAMSIZE = 0x0700; // "Memory/Misc" pane -const int GAD_MODELID = 0x0701; -const int GAD_ROM_FILE = 0x0702; - - -// Global variables -struct Library *GTLayoutBase = NULL; -static struct FileRequester *dev_request = NULL, *file_request = NULL; - -// gtlayout.library macros -#define VGROUP LT_New(h, LA_Type, VERTICAL_KIND, TAG_END) -#define HGROUP LT_New(h, LA_Type, HORIZONTAL_KIND, TAG_END) -#define ENDGROUP LT_EndGroup(h) - -// Prototypes -static void create_volumes_pane(struct LayoutHandle *h); -static void create_scsi_pane(struct LayoutHandle *h); -static void create_graphics_pane(struct LayoutHandle *h); -static void create_serial_pane(struct LayoutHandle *h); -static void create_memory_pane(struct LayoutHandle *h); -static void add_edit_volume(struct LayoutHandle *h, bool adding); -static void remove_volume(struct LayoutHandle *h); -static void ghost_volumes_gadgets(struct LayoutHandle *h); -static void ghost_graphics_gadgets(struct LayoutHandle *h); -static void screen_mode_req(struct Window *win, struct LayoutHandle *h); -static void ahi_mode_req(struct Window *win, struct LayoutHandle *h); -static void read_settings(struct LayoutHandle *h); - - -/* - * Locale hook - returns string for given ID - */ - -static __saveds __attribute__((regparm(3))) const char *locale_hook_func(struct Hook *hook /*a0*/, void *id /*a1*/, struct LayoutHandle *h /*a2*/) -{ - return GetString((uint32)id); -} - -struct Hook locale_hook = {{NULL, NULL}, (HOOKFUNC)locale_hook_func, NULL, NULL}; - - -/* - * Show preferences editor - * Returns true when user clicked on "Start", false otherwise - */ - -bool PrefsEditor(void) -{ - bool retval = true, done = false; - struct LayoutHandle *h = NULL; - struct Window *win = NULL; - struct Menu *menu = NULL; - - // Pane tabs - static const LONG labels[] = { - STR_VOLUMES_PANE_TITLE, - STR_SCSI_PANE_TITLE, - STR_GRAPHICS_SOUND_PANE_TITLE, - STR_SERIAL_NETWORK_PANE_TITLE, - STR_MEMORY_MISC_PANE_TITLE, - -1 - }; - - // Open gtlayout.library - GTLayoutBase = (struct Library *)OpenLibrary("gtlayout.library", 39); - if (GTLayoutBase == NULL) { - WarningAlert(GetString(STR_NO_GTLAYOUT_LIB_WARN)); - return true; - } - - // Create layout handle - h = LT_CreateHandleTags(NULL, - LAHN_AutoActivate, FALSE, - LAHN_LocaleHook, (ULONG)&locale_hook, - TAG_END - ); - if (h == NULL) - goto quit; - - // Create menus - menu = LT_NewMenuTags( - LAMN_LayoutHandle, (ULONG)h, - LAMN_TitleID, STR_PREFS_MENU, - LAMN_ItemID, STR_PREFS_ITEM_ABOUT, - LAMN_UserData, MSG_ABOUT, - LAMN_ItemText, (ULONG)NM_BARLABEL, - LAMN_ItemID, STR_PREFS_ITEM_START, - LAMN_UserData, MSG_OK, - LAMN_ItemID, STR_PREFS_ITEM_ZAP_PRAM, - LAMN_UserData, MSG_ZAP_PRAM, - LAMN_ItemText, (ULONG)NM_BARLABEL, - LAMN_ItemID, STR_PREFS_ITEM_QUIT, - LAMN_UserData, MSG_CANCEL, - LAMN_KeyText, (ULONG)"Q", - TAG_END - ); - - // Create window contents - VGROUP; - VGROUP; - LT_New(h, LA_Type, TAB_KIND, - LATB_LabelTable, (ULONG)labels, - LATB_AutoPageID, GAD_PAGEGROUP, - LATB_FullWidth, TRUE, - TAG_END - ); - ENDGROUP; - - // Panes - LT_New(h, LA_Type, VERTICAL_KIND, - LA_ID, GAD_PAGEGROUP, - LAGR_ActivePage, 0, - TAG_END - ); - create_volumes_pane(h); - create_scsi_pane(h); - create_graphics_pane(h); - create_serial_pane(h); - create_memory_pane(h); - ENDGROUP; - - // Separator between tabs and buttons - VGROUP; - LT_New(h, LA_Type, XBAR_KIND, - LAXB_FullSize, TRUE, - TAG_END - ); - ENDGROUP; - - // "Start" and "Quit" buttons - LT_New(h, LA_Type, HORIZONTAL_KIND, - LAGR_SameSize, TRUE, - LAGR_Spread, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_START_BUTTON, - LA_ID, MSG_OK, - LABT_ReturnKey, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_QUIT_BUTTON, - LA_ID, MSG_CANCEL, - LABT_EscKey, TRUE, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - // Open window - win = LT_Build(h, - LAWN_TitleID, STR_PREFS_TITLE, - LAWN_Menu, (ULONG)menu, - LAWN_IDCMP, IDCMP_CLOSEWINDOW, - LAWN_BelowMouse, TRUE, - LAWN_SmartZoom, TRUE, - WA_SimpleRefresh, TRUE, - WA_Activate, TRUE, - WA_CloseGadget, TRUE, - WA_DepthGadget, TRUE, - WA_DragBar, TRUE, - TAG_END - ); - if (win == NULL) - goto quit; - - // Create file requesters - dev_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, - ASLFR_DoPatterns, TRUE, - ASLFR_RejectIcons, TRUE, - ASLFR_InitialDrawer, (ULONG)"DEVS:", - ASLFR_InitialPattern, (ULONG)"#?.device", - TAG_END - ); - file_request = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, - ASLFR_DoPatterns, TRUE, - ASLFR_RejectIcons, TRUE, - ASLFR_InitialPattern, (ULONG)"#?", - TAG_END - ); - - // Event loop - do { - struct IntuiMessage *msg; - - // Wait for message - WaitPort(win->UserPort); - - // Get pending messages - while (msg = LT_GetIMsg(h)) { - - // Get data from message and reply - ULONG cl = msg->Class; - UWORD code = msg->Code; - struct Gadget *gad = (struct Gadget *)msg->IAddress; - LT_ReplyIMsg(msg); - - // Handle message according to class - switch (cl) { - case IDCMP_CLOSEWINDOW: - retval = false; - done = true; - break; - - case IDCMP_GADGETUP: - switch (gad->GadgetID) { - case MSG_OK: - read_settings(h); - SavePrefs(); - retval = true; - done = true; - break; - - case MSG_CANCEL: - retval = false; - done = true; - break; - - case GAD_DISK_LIST: - ghost_volumes_gadgets(h); - break; - - case GAD_ADD_VOLUME: - LT_LockWindow(win); - add_edit_volume(h, true); - LT_UnlockWindow(win); - break; - - case GAD_EDIT_VOLUME: - LT_LockWindow(win); - add_edit_volume(h, false); - LT_UnlockWindow(win); - break; - - case GAD_REMOVE_VOLUME: - remove_volume(h); - break; - - case GAD_BOOTDRIVER: - switch (code) { - case 0: - PrefsReplaceInt32("bootdriver", 0); - break; - case 1: - PrefsReplaceInt32("bootdriver", CDROMRefNum); - break; - } - break; - - case GAD_SCSI_MEMTYPE: - PrefsReplaceInt32("scsimemtype", code); - break; - - case GAD_VIDEO_TYPE: - ghost_graphics_gadgets(h); - break; - - case GAD_FRAMESKIP: - switch (code) { - case 0: - PrefsReplaceInt32("frameskip", 12); - break; - case 1: - PrefsReplaceInt32("frameskip", 8); - break; - case 2: - PrefsReplaceInt32("frameskip", 6); - break; - case 3: - PrefsReplaceInt32("frameskip", 4); - break; - case 4: - PrefsReplaceInt32("frameskip", 2); - break; - case 5: - PrefsReplaceInt32("frameskip", 1); - break; - } - break; - - case GAD_MODELID: - switch (code) { - case 0: - PrefsReplaceInt32("modelid", 5); - break; - case 1: - PrefsReplaceInt32("modelid", 14); - break; - } - break; - } - break; - - case IDCMP_IDCMPUPDATE: - switch (gad->GadgetID) { - case GAD_DISK_LIST: // Double-click on volumes list = edit volume - LT_LockWindow(win); - add_edit_volume(h, false); - LT_UnlockWindow(win); - break; - - case GAD_SCREEN_MODE: - screen_mode_req(win, h); - break; - - case GAD_AHI_MODE: - ahi_mode_req(win, h); - break; - - case GAD_CDROM_DEVICE: - case GAD_SCSI0_DEVICE: - case GAD_SCSI1_DEVICE: - case GAD_SCSI2_DEVICE: - case GAD_SCSI3_DEVICE: - case GAD_SCSI4_DEVICE: - case GAD_SCSI5_DEVICE: - case GAD_SCSI6_DEVICE: - case GAD_SERIALA_DEVICE: - case GAD_SERIALB_DEVICE: - if (dev_request) { - LT_LockWindow(win); - BOOL result = AslRequestTags(dev_request, - ASLFR_Window, (ULONG)win, - ASLFR_InitialDrawer, (ULONG) "Devs:", - TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. - str[255] = 0; - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - - case GAD_ETHER_DEVICE: - if (dev_request) { - LT_LockWindow(win); - BOOL result = AslRequestTags(dev_request, - ASLFR_Window, (ULONG)win, - ASLFR_InitialDrawer, (ULONG) "Devs:Networks", - TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - strncpy(str, dev_request->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. - str[255] = 0; - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - - case GAD_ROM_FILE: - if (file_request) { - LT_LockWindow(win); - BOOL result = AslRequestTags(file_request, ASLFR_Window, (ULONG)win, TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - strncpy(str, file_request->rf_Dir, 255); - str[255] = 0; - AddPart(str, file_request->rf_File, 255); - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - } - break; - - case IDCMP_MENUPICK: - while (code != MENUNULL) { - struct MenuItem *item = ItemAddress(menu, code); - if (item == NULL) - break; - switch ((ULONG)GTMENUITEM_USERDATA(item)) { - case MSG_OK: - read_settings(h); - SavePrefs(); - retval = true; - done = true; - break; - - case MSG_CANCEL: - retval = false; - done = true; - break; - - case MSG_ABOUT: { - char str[256]; - sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - strncat(str, "\n", 255); - strncat(str, GetString(STR_ABOUT_TEXT2), 255); - - EasyStruct req; - req.es_StructSize = sizeof(EasyStruct); - req.es_Flags = 0; - req.es_Title = (UBYTE *)GetString(STR_ABOUT_TITLE); - req.es_TextFormat = (UBYTE *)str; - req.es_GadgetFormat = (UBYTE *)GetString(STR_OK_BUTTON); - LT_LockWindow(win); - EasyRequest(win, &req, NULL); - LT_UnlockWindow(win); - break; - } - - case MSG_ZAP_PRAM: - ZapPRAM(); - break; - } - code = item->NextSelect; - } - break; - } - } - } while (!done); - -quit: - // Free requesters - FreeAslRequest(dev_request); - FreeAslRequest(file_request); - - // Delete Menus - LT_DisposeMenu(menu); - - // Delete handle - LT_DeleteHandle(h); - - // Close gtlayout.library - CloseLibrary(GTLayoutBase); - return retval; -} - - -/* - * "Volumes" pane - */ - -static struct List disk_list; -static char cdrom_name[256], extfs_name[256]; -static ULONG cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize; -static BYTE bootdriver_num, nocdrom; - -// Read volumes preferences -static void parse_volumes_prefs(void) -{ - NewList(&disk_list); - const char *str; - for (int i=0; (str = PrefsFindString("disk", i)) != NULL; i++) { - struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR); - item->ln_Name = (char *)str; - AddTail(&disk_list, item); - } - - cdrom_name[0] = 0; - cdrom_unit = 0; cdrom_flags = 0; cdrom_start = 0; cdrom_size = 0; cdrom_bsize = 2048; - - str = PrefsFindString("cdrom"); - if (str) - sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", cdrom_name, &cdrom_unit, &cdrom_flags, &cdrom_start, &cdrom_size, &cdrom_bsize); - - bootdriver_num = 0; - - int bootdriver = PrefsFindInt32("bootdriver"); - switch (bootdriver) { - case 0: - bootdriver_num = 0; - break; - case CDROMRefNum: - bootdriver_num = 1; - break; - } - - nocdrom = PrefsFindBool("nocdrom"); - - extfs_name[0] = 0; - str = PrefsFindString("extfs"); - if (str) - strncpy(extfs_name, str, sizeof(extfs_name) - 1); -} - -// Ghost/unghost "Edit" and "Remove" buttons -static void ghost_volumes_gadgets(struct LayoutHandle *h) -{ - UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END); - if (sel == 0xffff) { - LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, TRUE, TAG_END); - LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, TRUE, TAG_END); - } else { - LT_SetAttributes(h, GAD_EDIT_VOLUME, GA_Disabled, FALSE, TAG_END); - LT_SetAttributes(h, GAD_REMOVE_VOLUME, GA_Disabled, FALSE, TAG_END); - } -} - -// Get device data from partition name -static void analyze_partition(const char *part, char *dev_name, ULONG &dev_unit, ULONG &dev_flags, ULONG &dev_start, ULONG &dev_size, ULONG &dev_bsize) -{ - // Remove everything after and including the ':' - char str[256]; - strncpy(str, part, sizeof(str) - 1); - str[sizeof(str) - 1] = 0; - char *colon = strchr(str, ':'); - if (colon) - *colon = 0; - - // Look for partition - struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ); - dl = FindDosEntry(dl, str, LDF_DEVICES); - if (dl) { - // Get File System Startup Message - struct FileSysStartupMsg *fssm = (struct FileSysStartupMsg *)(dl->dol_misc.dol_handler.dol_Startup << 2); - if (fssm) { - // Get DOS environment vector - struct DosEnvec *de = (struct DosEnvec *)(fssm->fssm_Environ << 2); - if (de && de->de_TableSize >= DE_UPPERCYL) { - // Read settings from FSSM and Envec - strncpy(dev_name, (char *)(fssm->fssm_Device << 2) + 1, 255); - dev_name[255] = 0; - dev_unit = fssm->fssm_Unit; - dev_flags = fssm->fssm_Flags; - dev_start = de->de_BlocksPerTrack * de->de_Surfaces * de->de_LowCyl; - dev_size = de->de_BlocksPerTrack * de->de_Surfaces * (de->de_HighCyl - de->de_LowCyl + 1); - dev_bsize = de->de_SizeBlock << 2; - } - } - } - UnLockDosList(LDF_DEVICES | LDF_READ); -} - -// Display and handle "Add/Edit Volume" window -static void add_edit_volume(struct LayoutHandle *h2, bool adding) -{ - bool ok_clicked = false; - - UWORD sel = LT_GetAttributes(h2, GAD_DISK_LIST, TAG_END); - if ((sel == 0xffff) && !adding) - return; - - char dev_name[256] = ""; - char file_name[256] = ""; - ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 0, dev_bsize = 512; - BYTE read_only = false, is_device = false; - - if (!adding) { - const char *str = PrefsFindString("disk", sel); - if (str == NULL) - return; - if (str[0] == '*') { - read_only = true; - str++; - } - if (strstr(str, "/dev/") == str) { - is_device = true; - sscanf(str, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize); - } else { - strncpy(file_name, str, sizeof(file_name) - 1); - file_name[sizeof(file_name) - 1] = 0; - } - } - - // Create layout handle - struct LayoutHandle *h = NULL; - struct Window *win = NULL; - h = LT_CreateHandleTags(NULL, - LAHN_AutoActivate, FALSE, - LAHN_LocaleHook, (ULONG)&locale_hook, - TAG_END - ); - if (h == NULL) - return; - - // Create window contents - VGROUP; - // Volume gadgets - VGROUP; - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_VOL_READONLY_CTRL, - LA_ID, GAD_VOLUME_READONLY, - LA_BYTE, (ULONG)&read_only, - TAG_END - ); - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_VOL_TYPE_CTRL, - LA_ID, GAD_VOLUME_TYPE, - LACY_AutoPageID, GAD_VOLUME_PAGEGROUP, - LACY_FirstLabel, STR_VOL_FILE_LAB, - LACY_LastLabel, STR_VOL_DEVICE_LAB, - LA_BYTE, (ULONG)&is_device, - TAG_END - ); - ENDGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_ID, GAD_VOLUME_PAGEGROUP, - LAGR_ActivePage, is_device, - TAG_END - ); - VGROUP; - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_VOL_FILE_CTRL, - LA_ID, GAD_VOLUME_FILE, - LA_Chars, 20, - LA_STRPTR, (ULONG)file_name, - GTST_MaxChars, sizeof(file_name) - 1, - LAST_Picker, TRUE, - TAG_END - ); - ENDGROUP; - VGROUP; - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_VOLUME_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)dev_name, - GTST_MaxChars, sizeof(dev_name) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_VOLUME_UNIT, - LA_LONG, (ULONG)&dev_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_OPENFLAGS_CTRL, - LA_ID, GAD_VOLUME_OPENFLAGS, - LA_LONG, (ULONG)&dev_flags, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_STARTBLOCK_CTRL, - LA_ID, GAD_VOLUME_STARTBLOCK, - LA_LONG, (ULONG)&dev_start, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_SIZE_CTRL, - LA_ID, GAD_VOLUME_SIZE, - LA_LONG, (ULONG)&dev_size, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_VOL_BLOCKSIZE_CTRL, - LA_ID, GAD_VOLUME_BLOCKSIZE, - LA_LONG, (ULONG)&dev_bsize, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - // Separator between gadgets and buttons - VGROUP; - LT_New(h, LA_Type, XBAR_KIND, - LAXB_FullSize, TRUE, - TAG_END - ); - ENDGROUP; - - // "OK" and "Cancel" buttons - LT_New(h, LA_Type, HORIZONTAL_KIND, - LAGR_SameSize, TRUE, - LAGR_Spread, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_OK_BUTTON, - LA_ID, MSG_OK, - LABT_ReturnKey, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_CANCEL_BUTTON, - LA_ID, MSG_CANCEL, - LABT_EscKey, TRUE, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - // Open window - win = LT_Build(h, - LAWN_TitleID, adding ? STR_ADD_VOLUME_TITLE : STR_EDIT_VOLUME_TITLE, - LAWN_IDCMP, IDCMP_CLOSEWINDOW, - LAWN_BelowMouse, TRUE, - LAWN_SmartZoom, TRUE, - WA_SimpleRefresh, TRUE, - WA_Activate, TRUE, - WA_CloseGadget, TRUE, - WA_DepthGadget, TRUE, - WA_DragBar, TRUE, - TAG_END - ); - if (win == NULL) { - LT_DeleteHandle(h); - return; - } - - // Event loop - bool done = false; - do { - struct IntuiMessage *msg; - - // Wait for message - WaitPort(win->UserPort); - - // Get pending messages - while (msg = LT_GetIMsg(h)) { - - // Get data from message and reply - ULONG cl = msg->Class; - UWORD code = msg->Code; - struct Gadget *gad = (struct Gadget *)msg->IAddress; - LT_ReplyIMsg(msg); - - // Handle message according to class - switch (cl) { - case IDCMP_CLOSEWINDOW: - done = true; - break; - - case IDCMP_GADGETUP: - switch (gad->GadgetID) { - case MSG_OK: - ok_clicked = true; - done = true; - break; - case MSG_CANCEL: - done = true; - break; - } - break; - - case IDCMP_IDCMPUPDATE: { - struct FileRequester *req = NULL; - switch (gad->GadgetID) { - case GAD_VOLUME_FILE: - req = file_request; - goto do_req; - case GAD_VOLUME_DEVICE: - req = dev_request; -do_req: if (req) { - LT_LockWindow(win); - BOOL result = AslRequestTags(req, ASLFR_Window, (ULONG)win, TAG_END); - LT_UnlockWindow(win); - if (result) { - char *str; - GT_GetGadgetAttrs(gad, win, NULL, GTST_String, (ULONG)&str, TAG_END); - if (gad->GadgetID == GAD_VOLUME_FILE) { - strncpy(str, req->rf_Dir, 255); - str[255] = 0; - AddPart(str, req->rf_File, 255); - } else { - if (strlen(req->rf_File)) { - strncpy(str, req->rf_File, 255); // Don't copy the directory part. This is usually "DEVS:" and we don't need that. - str[255] = 0; - } else if (strlen(req->rf_Dir) && req->rf_Dir[strlen(req->rf_Dir) - 1] == ':') { - analyze_partition(req->rf_Dir, str, dev_unit, dev_flags, dev_start, dev_size, dev_bsize); - LT_SetAttributes(h, GAD_VOLUME_UNIT, GTIN_Number, dev_unit, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_OPENFLAGS, GTIN_Number, dev_flags, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_STARTBLOCK, GTIN_Number, dev_start, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_SIZE, GTIN_Number, dev_size, TAG_END); - LT_SetAttributes(h, GAD_VOLUME_BLOCKSIZE, GTIN_Number, dev_bsize, TAG_END); - } - } - LT_SetAttributes(h, gad->GadgetID, GTST_String, (ULONG)str, TAG_END); - } - } - break; - } - break; - } - } - } - } while (!done); - - // Update preferences and list view - if (ok_clicked) { - char str[256]; - LT_UpdateStrings(h); - - if (is_device) - sprintf(str, "%s/dev/%s/%ld/%ld/%ld/%ld/%ld", read_only ? "*" : "", dev_name, dev_unit, dev_flags, dev_start, dev_size, dev_bsize); - else - sprintf(str, "%s%s", read_only ? "*" : "", file_name); - LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END); - - if (adding) { - - // Add new item - int i; - PrefsAddString("disk", str); - struct Node *item = (struct Node *)AllocMem(sizeof(struct Node), MEMF_CLEAR); - for (i=0; PrefsFindString("disk", i); i++) ; - item->ln_Name = (char *)PrefsFindString("disk", i - 1); - AddTail(&disk_list, item); - - } else { - - // Replace existing item - PrefsReplaceString("disk", str, sel); - struct Node *item = disk_list.lh_Head; - for (int i=0; item->ln_Succ; i++) { - if (i == sel) { - item->ln_Name = (char *)PrefsFindString("disk", sel); - break; - } - item = item->ln_Succ; - } - } - LT_SetAttributes(h2, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, TAG_END); - ghost_volumes_gadgets(h2); - } - - // Delete handle - LT_DeleteHandle(h); -} - -// Remove volume from list -static void remove_volume(struct LayoutHandle *h) -{ - UWORD sel = LT_GetAttributes(h, GAD_DISK_LIST, TAG_END); - if (sel != 0xffff) { - - // Remove item from preferences and list view - LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, ~0, TAG_END); - PrefsRemoveItem("disk", sel); - struct Node *item = disk_list.lh_Head; - for (int i=0; item->ln_Succ; i++) { - struct Node *next = item->ln_Succ; - if (i == sel) { - Remove(item); - FreeMem(item, sizeof(struct Node)); - break; - } - item = next; - } - LT_SetAttributes(h, GAD_DISK_LIST, GTLV_Labels, (ULONG)&disk_list, GTLV_Selected, 0xffff, TAG_END); - ghost_volumes_gadgets(h); - } -} - -// Read settings from gadgets and set preferences -static void read_volumes_settings(void) -{ - struct Node *item = disk_list.lh_Head; - while (item->ln_Succ) { - struct Node *next = item->ln_Succ; - Remove(item); - FreeMem(item, sizeof(struct Node)); - item = next; - } - - if (strlen(cdrom_name)) { - char str[256]; - sprintf(str, "/dev/%s/%ld/%ld/%ld/%ld/%ld", cdrom_name, cdrom_unit, cdrom_flags, cdrom_start, cdrom_size, cdrom_bsize); - PrefsReplaceString("cdrom", str); - } else - PrefsRemoveItem("cdrom"); - - PrefsReplaceBool("nocdrom", nocdrom); - - if (strlen(extfs_name)) - PrefsReplaceString("extfs", extfs_name); -} - -// Create "Volumes" pane -static void create_volumes_pane(struct LayoutHandle *h) -{ - parse_volumes_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_VOLUMES_CTRL, - TAG_END - ); - VGROUP; - LT_New(h, LA_Type, LISTVIEW_KIND, - LA_ID, GAD_DISK_LIST, - LA_Chars, 20, - GTLV_Labels, (ULONG)&disk_list, - LALV_Lines, 6, - LALV_Link, (ULONG)NIL_LINK, - LALV_ResizeX, TRUE, - LALV_ResizeY, TRUE, - LALV_Selected, 0, - TAG_END - ); - ENDGROUP; - LT_New(h, LA_Type, HORIZONTAL_KIND, - LAGR_SameSize, TRUE, - LAGR_Spread, TRUE, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_ADD_VOLUME_BUTTON, - LA_ID, GAD_ADD_VOLUME, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_EDIT_VOLUME_BUTTON, - LA_ID, GAD_EDIT_VOLUME, - TAG_END - ); - LT_New(h, LA_Type, BUTTON_KIND, - LA_LabelID, STR_REMOVE_VOLUME_BUTTON, - LA_ID, GAD_REMOVE_VOLUME, - TAG_END - ); - ENDGROUP; - ENDGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_CDROM_DRIVE_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_CDROM_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)cdrom_name, - GTST_MaxChars, sizeof(cdrom_name) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_CDROM_UNIT, - LA_LONG, (ULONG)&cdrom_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_BOOTDRIVER_CTRL, - LA_ID, GAD_BOOTDRIVER, - LACY_FirstLabel, STR_BOOT_ANY_LAB, - LACY_LastLabel, STR_BOOT_CDROM_LAB, - LA_BYTE, (ULONG)&bootdriver_num, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_NOCDROM_CTRL, - LA_ID, GAD_NOCDROM, - LA_BYTE, (ULONG)&nocdrom, - TAG_END - ); - ENDGROUP; - VGROUP; - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_EXTFS_CTRL, - LA_ID, GAD_EXTFS, - LA_Chars, 20, - LA_STRPTR, (ULONG)extfs_name, - GTST_MaxChars, sizeof(extfs_name) - 1, - TAG_END - ); - ENDGROUP; - ENDGROUP; -} - - -/* - * "SCSI" pane - */ - -static char scsi_dev[6][256]; -static LONG scsi_unit[6]; -static LONG scsi_memtype; - -// Read SCSI preferences -static void parse_scsi_prefs(void) -{ - for (int i=0; i<7; i++) { - scsi_dev[i][0] = 0; - scsi_unit[i] = 0; - - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", i); - const char *str = PrefsFindString(prefs_name); - if (str) - sscanf(str, "%[^/]/%ld", scsi_dev[i], &scsi_unit[i]); - } - - scsi_memtype = PrefsFindInt32("scsimemtype"); -} - -// Read settings from gadgets and set preferences -static void read_scsi_settings(void) -{ - for (int i=0; i<7; i++) { - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", i); - - if (strlen(scsi_dev[i])) { - char str[256]; - sprintf(str, "%s/%ld", scsi_dev[i], scsi_unit[i]); - PrefsReplaceString(prefs_name, str); - } else - PrefsRemoveItem(prefs_name); - } -} - -// Create "SCSI" pane -static void create_scsi_pane(struct LayoutHandle *h) -{ - parse_scsi_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SCSI_DEVICES_CTRL, - TAG_END - ); - for (int i=0; i<7; i++) { - HGROUP; - LT_New(h, LA_Type, TEXT_KIND, - LA_LabelID, STR_SCSI_ID_0 + i, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_SCSI0_DEVICE + i, - LA_Chars, 20, - LA_STRPTR, (ULONG)scsi_dev[i], - GTST_MaxChars, sizeof(scsi_dev[i]) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_SCSI0_UNIT + i, - LA_Chars, 4, - LA_LONG, (ULONG)&scsi_unit[i], - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - ENDGROUP; - } - ENDGROUP; - VGROUP; - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_SCSI_MEMTYPE_CTRL, - LA_ID, GAD_SCSI_MEMTYPE, - LACY_FirstLabel, STR_MEMTYPE_CHIP_LAB, - LACY_LastLabel, STR_MEMTYPE_ANY_LAB, - LA_LONG, (ULONG)&scsi_memtype, - TAG_END - ); - ENDGROUP; - ENDGROUP; -} - - -/* - * "Graphics/Sound" pane - */ - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_PIP, - DISPLAY_SCREEN -}; - -static LONG display_type; -static LONG dis_width, dis_height; -static ULONG mode_id; -static BYTE frameskip_num; -static struct NameInfo mode_name; -static ULONG ahi_id; -static char ahi_mode_name[256]; -static BYTE nosound; - -// Read graphics preferences -static void parse_graphics_prefs(void) -{ - display_type = DISPLAY_WINDOW; - dis_width = 512; - dis_height = 384; - mode_id = 0; - ahi_id = AHI_DEFAULT_ID; - ahi_mode_name[0] = 0; - - frameskip_num = 0; - int frameskip = PrefsFindInt32("frameskip"); - switch (frameskip) { - case 12: - frameskip_num = 0; - break; - case 8: - frameskip_num = 1; - break; - case 6: - frameskip_num = 2; - break; - case 4: - frameskip_num = 3; - break; - case 2: - frameskip_num = 4; - break; - case 1: - frameskip_num = 5; - break; - } - - const char *str = PrefsFindString("screen"); - if (str) { - if (sscanf(str, "win/%ld/%ld", &dis_width, &dis_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(str, "pip/%ld/%ld", &dis_width, &dis_height) == 2) - display_type = DISPLAY_PIP; - else if (sscanf(str, "scr/%08lx", &mode_id) == 1) - display_type = DISPLAY_SCREEN; - } - - GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id); - - str = PrefsFindString("sound"); - if (str) { - if (sscanf(str, "ahi/%08lx", &ahi_id) == 1 && AHIBase) { - AHI_GetAudioAttrs(ahi_id, NULL, - AHIDB_Name, (ULONG)ahi_mode_name, - AHIDB_BufferLen, sizeof(ahi_mode_name) - 1, - TAG_END - ); - } - } - nosound = PrefsFindBool("nosound"); -} - -// Ghost/unghost graphics gadgets, depending on display type -static void ghost_graphics_gadgets(struct LayoutHandle *h) -{ - bool dis_xy, dis_skip, dis_mode; - switch (display_type) { - case DISPLAY_WINDOW: - dis_xy = false; - dis_skip = false; - dis_mode = true; - break; - case DISPLAY_PIP: - dis_xy = false; - dis_skip = true; - dis_mode = true; - break; - case DISPLAY_SCREEN: - dis_xy = true; - dis_skip = true; - dis_mode = false; - break; - } - LT_SetAttributes(h, GAD_DISPLAY_X, GA_Disabled, dis_xy, TAG_END); - LT_SetAttributes(h, GAD_DISPLAY_Y, GA_Disabled, dis_xy, TAG_END); - LT_SetAttributes(h, GAD_FRAMESKIP, GA_Disabled, dis_skip, TAG_END); - LT_SetAttributes(h, GAD_SCREEN_MODE, GA_Disabled, dis_mode, TAG_END); - LT_SetAttributes(h, GAD_AHI_MODE, GA_Disabled, AHIBase == NULL, TAG_END); -} - -// Show screen mode requester -static void screen_mode_req(struct Window *win, struct LayoutHandle *h) -{ - if (P96Base == NULL && CyberGfxBase == NULL) - return; - - LT_LockWindow(win); - - ULONG id; - - // Try P96 first, because it also provides a (fake) cybergraphics.library - if (P96Base) { - id = p96RequestModeIDTags( - P96MA_MinDepth, 8, - P96MA_FormatsAllowed, RGBFF_CLUT | RGBFF_R5G5B5 | RGBFF_A8R8G8B8, - TAG_END - ); - } else { - UWORD ModelArray[] = { PIXFMT_LUT8, PIXFMT_RGB15, PIXFMT_ARGB32, 0, ~0 }; - id = (ULONG) CModeRequestTags(NULL, - CYBRMREQ_MinDepth, 8, - CYBRMREQ_CModelArray, (ULONG) ModelArray, - TAG_END - ); - } - LT_UnlockWindow(win); - - if (id != INVALID_ID) { - mode_id = id; - GetDisplayInfoData(NULL, (UBYTE *)&mode_name, sizeof(mode_name), DTAG_NAME, mode_id); - LT_SetAttributes(h, GAD_SCREEN_MODE, GTTX_Text, (ULONG)mode_name.Name, TAG_END); - } -} - -// Show AHI mode requester -static void ahi_mode_req(struct Window *win, struct LayoutHandle *h) -{ - if (AHIBase == NULL) - return; - - struct AHIAudioModeRequester *req = AHI_AllocAudioRequest( - AHIR_Window, (ULONG)win, - TAG_END - ); - if (req == NULL) - return; - - LT_LockWindow(win); - BOOL ok = AHI_AudioRequest(req, - AHIR_InitialAudioID, ahi_id, - TAG_END - ); - LT_UnlockWindow(win); - - if (ok) { - ahi_id = req->ahiam_AudioID; - AHI_GetAudioAttrs(ahi_id, NULL, - AHIDB_Name, (ULONG)ahi_mode_name, - AHIDB_BufferLen, sizeof(ahi_mode_name) - 1, - TAG_END - ); - LT_SetAttributes(h, GAD_AHI_MODE, GTTX_Text, (ULONG)ahi_mode_name, TAG_END); - } - AHI_FreeAudioRequest(req); -} - -// Read settings from gadgets and set preferences -static void read_graphics_settings(void) -{ - char str[256]; - switch (display_type) { - case DISPLAY_WINDOW: - sprintf(str, "win/%ld/%ld", dis_width, dis_height); - break; - case DISPLAY_PIP: - sprintf(str, "pip/%ld/%ld", dis_width, dis_height); - break; - case DISPLAY_SCREEN: - sprintf(str, "scr/%08lx", mode_id); - break; - default: - PrefsRemoveItem("screen"); - return; - } - PrefsReplaceString("screen", str); - - sprintf(str, "ahi/%08lx", ahi_id); - PrefsReplaceString("sound", str); - - PrefsReplaceBool("nosound", nosound); -} - -// Create "Graphics/Sound" pane -static void create_graphics_pane(struct LayoutHandle *h) -{ - parse_graphics_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_GRAPHICS_CTRL, - TAG_END - ); - static const LONG labels[] = {STR_WINDOW_LAB, STR_PIP_LAB, STR_FULLSCREEN_LAB, -1}; - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_VIDEO_TYPE_CTRL, - LA_ID, GAD_VIDEO_TYPE, - LACY_LabelTable, (ULONG)labels, - LA_LONG, (ULONG)&display_type, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_DISPLAY_X_CTRL, - LA_ID, GAD_DISPLAY_X, - LA_LONG, (ULONG)&dis_width, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_DISPLAY_Y_CTRL, - LA_ID, GAD_DISPLAY_Y, - LA_LONG, (ULONG)&dis_height, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, POPUP_KIND, - LA_LabelID, STR_FRAMESKIP_CTRL, - LA_ID, GAD_FRAMESKIP, - LAPU_FirstLabel, STR_REF_5HZ_LAB, - LAPU_LastLabel, STR_REF_60HZ_LAB, - LA_BYTE, (ULONG)&frameskip_num, - TAG_END - ); - LT_New(h, LA_Type, TEXT_KIND, - LA_LabelID, STR_SCREEN_MODE_CTRL, - LA_ID, GAD_SCREEN_MODE, - LA_Chars, DISPLAYNAMELEN, - LATX_Picker, TRUE, - GTTX_Text, (ULONG)mode_name.Name, - GTTX_Border, TRUE, - TAG_END - ); - ENDGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SOUND_CTRL, - TAG_END - ); - LT_New(h, LA_Type, TEXT_KIND, - LA_LabelID, STR_AHI_MODE_CTRL, - LA_ID, GAD_AHI_MODE, - LA_Chars, DISPLAYNAMELEN, - LATX_Picker, TRUE, - GTTX_Text, (ULONG)ahi_mode_name, - GTTX_Border, TRUE, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_NOSOUND_CTRL, - LA_ID, GAD_NOSOUND, - LA_BYTE, (ULONG)&nosound, - TAG_END - ); - ENDGROUP; - ENDGROUP; - - ghost_graphics_gadgets(h); -} - - -/* - * "Serial/Network" pane - */ - -static char seriala_dev[256], serialb_dev[256]; -static LONG seriala_unit, serialb_unit; -static BYTE seriala_ispar, serialb_ispar; - -static char ether_dev[256]; -static ULONG ether_unit; - -// Read serial/network preferences -static void parse_ser_prefs(const char *prefs, char *dev, LONG &unit, BYTE &ispar) -{ - dev[0] = 0; - unit = 0; - ispar = false; - - const char *str = PrefsFindString(prefs); - if (str) { - if (str[0] == '*') { - ispar = true; - str++; - } - sscanf(str, "%[^/]/%ld", dev, &unit); - } -} - -static void parse_serial_prefs(void) -{ - parse_ser_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar); - parse_ser_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar); - - ether_dev[0] = 0; - ether_unit = 0; - - const char *str = PrefsFindString("ether"); - if (str) { - const char *FirstSlash = strchr(str, '/'); - const char *LastSlash = strrchr(str, '/'); - - if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { - // Device name contains path, i.e. "Networks/xyzzy.device" - const char *lp = str; - char *dp = ether_dev; - - while (lp != LastSlash) - *dp++ = *lp++; - *dp = '\0'; - - sscanf(LastSlash, "/%ld", ðer_unit); - -// printf("dev=<%s> unit=%d\n", ether_dev, ether_unit); - } else { - sscanf(str, "%[^/]/%ld", ether_dev, ðer_unit); - } - } -} - -// Set serial preference item -static void make_serial_prefs(const char *prefs, const char *dev, LONG unit, BYTE ispar) -{ - if (strlen(dev)) { - char str[256]; - sprintf(str, "%s%s/%ld", ispar ? "*" : "", dev, unit); - PrefsReplaceString(prefs, str); - } else - PrefsRemoveItem(prefs); -} - -// Read settings from gadgets and set preferences -static void read_serial_settings(void) -{ - make_serial_prefs("seriala", seriala_dev, seriala_unit, seriala_ispar); - make_serial_prefs("serialb", serialb_dev, serialb_unit, serialb_ispar); - - if (strlen(ether_dev)) { - char str[256]; - - sprintf(str, "%s/%ld", ether_dev, ether_unit); - PrefsReplaceString("ether", str); - } else - PrefsRemoveItem("ether"); -} - -// Create "Serial/Network" pane -static void create_serial_pane(struct LayoutHandle *h) -{ - parse_serial_prefs(); - - VGROUP; - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SERIALA_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_SERIALA_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)seriala_dev, - GTST_MaxChars, sizeof(seriala_dev) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_SERIALA_UNIT, - LA_LONG, (ULONG)&seriala_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_ISPAR_CTRL, - LA_ID, GAD_SERIALA_ISPAR, - LA_BYTE, (ULONG)&seriala_ispar, - TAG_END - ); - ENDGROUP; - - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_SERIALB_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_SERIALB_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)serialb_dev, - GTST_MaxChars, sizeof(serialb_dev) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_SERIALB_UNIT, - LA_LONG, (ULONG)&serialb_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - LT_New(h, LA_Type, CHECKBOX_KIND, - LA_LabelID, STR_ISPAR_CTRL, - LA_ID, GAD_SERIALB_ISPAR, - LA_BYTE, (ULONG)&serialb_ispar, - TAG_END - ); - ENDGROUP; - - LT_New(h, LA_Type, VERTICAL_KIND, - LA_LabelID, STR_ETHERNET_IF_CTRL, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_DEVICE_CTRL, - LA_ID, GAD_ETHER_DEVICE, - LA_Chars, 20, - LA_STRPTR, (ULONG)ether_dev, - GTST_MaxChars, sizeof(ether_dev) - 1, - LAST_Picker, TRUE, - TAG_END - ); - LT_New(h, LA_Type, INTEGER_KIND, - LA_LabelID, STR_UNIT_CTRL, - LA_ID, GAD_ETHER_UNIT, - LA_LONG, (ULONG)ðer_unit, - LAIN_UseIncrementers, TRUE, - GTIN_MaxChars, 8, - TAG_END - ); - ENDGROUP; - ENDGROUP; -} - - -/* - * "Memory/Misc" pane - */ - -static ULONG ramsize_mb; -static BYTE model_num; -static char rom_file[256]; - -// Read memory/misc preferences -static void parse_memory_prefs(void) -{ - ramsize_mb = PrefsFindInt32("ramsize") >> 20; - - model_num = 0; - int id = PrefsFindInt32("modelid"); - switch (id) { - case 5: - model_num = 0; - break; - case 14: - model_num = 1; - break; - } - - rom_file[0] = 0; - const char *str = PrefsFindString("rom"); - if (str) { - strncpy(rom_file, str, sizeof(rom_file) - 1); - rom_file[sizeof(rom_file) - 1] = 0; - } -} - -// Read settings from gadgets and set preferences -static void read_memory_settings(void) -{ - PrefsReplaceInt32("ramsize", ramsize_mb << 20); - - if (strlen(rom_file)) - PrefsReplaceString("rom", rom_file); - else - PrefsRemoveItem("rom"); -} - -// Create "Memory/Misc" pane -static void create_memory_pane(struct LayoutHandle *h) -{ - parse_memory_prefs(); - - VGROUP; - LT_New(h, LA_Type, LEVEL_KIND, - LA_LabelID, STR_RAMSIZE_SLIDER, - LA_ID, GAD_RAMSIZE, - LA_Chars, 20, - LA_LONG, (ULONG)&ramsize_mb, - GTSL_LevelFormat, (ULONG)GetString(STR_RAMSIZE_FMT), - GTSL_Min, 1, - GTSL_Max, AvailMem(MEMF_LARGEST) >> 20, - TAG_END - ); - LT_New(h, LA_Type, CYCLE_KIND, - LA_LabelID, STR_MODELID_CTRL, - LA_ID, GAD_MODELID, - LACY_FirstLabel, STR_MODELID_5_LAB, - LACY_LastLabel, STR_MODELID_14_LAB, - LA_BYTE, (ULONG)&model_num, - TAG_END - ); - LT_New(h, LA_Type, STRING_KIND, - LA_LabelID, STR_ROM_FILE_CTRL, - LA_ID, GAD_ROM_FILE, - LA_Chars, 20, - LA_STRPTR, (ULONG)rom_file, - GTST_MaxChars, sizeof(rom_file) - 1, - LAST_Picker, TRUE, - TAG_END - ); - ENDGROUP; -} - - -/* - * Read settings from gadgets and set preferences - */ - -static void read_settings(struct LayoutHandle *h) -{ - LT_UpdateStrings(h); - read_volumes_settings(); - read_scsi_settings(); - read_graphics_settings(); - read_serial_settings(); - read_memory_settings(); -} diff --git a/BasiliskII/src/AmigaOS/scsi_amiga.cpp b/BasiliskII/src/AmigaOS/scsi_amiga.cpp deleted file mode 100644 index c660eb268..000000000 --- a/BasiliskII/src/AmigaOS/scsi_amiga.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * scsi_amiga.cpp - SCSI Manager, Amiga specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "scsi.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static struct SCSICmd scsi; - -static IOStdReq *ios[8*8]; // IORequests for 8 units and 8 LUNs each -static IOStdReq *io; // Active IORequest (selected target) - -static struct MsgPort *the_port = NULL; // Message port for device communication - -static ULONG buffer_size; // Size of data buffer -static UBYTE *buffer = NULL; // Pointer to data buffer -static ULONG buffer_memf; // Buffer memory flags - -static UBYTE cmd_buffer[12]; // Buffer for SCSI command - -const int SENSE_LENGTH = 256; -static UBYTE *sense_buffer = NULL; // Buffer for autosense data - -static bool direct_transfers_supported = false; // Direct data transfers (bypassing the buffer) are supported - - -/* - * Initialization - */ - -void SCSIInit(void) -{ - int id, lun; - - int memtype = PrefsFindInt32("scsimemtype"); - switch (memtype) { - case 1: - buffer_memf = MEMF_24BITDMA | MEMF_PUBLIC; - break; - case 2: - buffer_memf = MEMF_ANY | MEMF_PUBLIC; - direct_transfers_supported = true; - break; - default: - buffer_memf = MEMF_CHIP | MEMF_PUBLIC; - break; - } - - // Create port and buffers - the_port = CreateMsgPort(); - buffer = (UBYTE *)AllocMem(buffer_size = 0x10000, buffer_memf); - sense_buffer = (UBYTE *)AllocMem(SENSE_LENGTH, MEMF_CHIP | MEMF_PUBLIC); - if (the_port == NULL || buffer == NULL || sense_buffer == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - - // Create and open IORequests for all 8 units (and all 8 LUNs) - for (id=0; id<8; id++) { - for (lun=0; lun<8; lun++) - ios[id*8+lun] = NULL; - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", id); - const char *str = PrefsFindString(prefs_name); - if (str) { - char dev_name[256]; - ULONG dev_unit = 0; - if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) == 2) { - for (lun=0; lun<8; lun++) { - struct IOStdReq *io = (struct IOStdReq *)CreateIORequest(the_port, sizeof(struct IOStdReq)); - if (io == NULL) - continue; - if (OpenDevice((UBYTE *) dev_name, dev_unit + lun * 10, (struct IORequest *)io, 0)) { - DeleteIORequest(io); - continue; - } - io->io_Data = &scsi; - io->io_Length = sizeof(scsi); - io->io_Command = HD_SCSICMD; - ios[id*8+lun] = io; - } - } - } - } - - // Reset SCSI bus - SCSIReset(); - - // Init SCSICmd - memset(&scsi, 0, sizeof(scsi)); - scsi.scsi_Command = cmd_buffer; - scsi.scsi_SenseData = sense_buffer; - scsi.scsi_SenseLength = SENSE_LENGTH; -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - // Close all devices - for (int i=0; i<8; i++) - for (int j=0; j<8; j++) { - struct IOStdReq *io = ios[i*8+j]; - if (io) { - CloseDevice((struct IORequest *)io); - DeleteIORequest(io); - } - } - - // Delete port and buffers - if (the_port) - DeleteMsgPort(the_port); - if (buffer) - FreeMem(buffer, buffer_size); - if (sense_buffer) - FreeMem(sense_buffer, SENSE_LENGTH); -} - - -/* - * Check if requested data size fits into buffer, allocate new buffer if needed - */ - -static bool try_buffer(int size) -{ - if (size <= buffer_size) - return true; - - UBYTE *new_buffer = (UBYTE *)AllocMem(size, buffer_memf); - if (new_buffer == NULL) - return false; - FreeMem(buffer, buffer_size); - buffer = new_buffer; - buffer_size = size; - return true; -} - - -/* - * Set SCSI command to be sent by scsi_send_cmd() - */ - -void scsi_set_cmd(int cmd_length, uint8 *cmd) -{ - scsi.scsi_CmdLength = cmd_length; - memcpy(cmd_buffer, cmd, cmd_length); -} - - -/* - * Check for presence of SCSI target - */ - -bool scsi_is_target_present(int id) -{ - return ios[id * 8] != NULL; -} - - -/* - * Set SCSI target (returns false on error) - */ - -bool scsi_set_target(int id, int lun) -{ - struct IOStdReq *new_io = ios[id * 8 + lun]; - if (new_io == NULL) - return false; - if (new_io != io) - scsi.scsi_SenseActual = 0; // Clear sense data when selecting new target - io = new_io; - return true; -} - - -/* - * Send SCSI command to active target (scsi_set_command() must have been called), - * read/write data according to S/G table (returns false on error); timeout is in 1/60 sec - */ - -bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout) -{ - // Bypass the buffer if there's only one S/G table entry - bool do_direct_transfer = (sg_size == 1 && ((uint32)sg_ptr[0] & 1) == 0 && direct_transfers_supported); - - if (!do_direct_transfer) { - - // Check if buffer is large enough, allocate new buffer if needed - if (!try_buffer(data_length)) { - char str[256]; - sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length); - ErrorAlert(str); - return false; - } - - // Process S/G table when writing - if (!reading) { - D(bug(" writing to buffer\n")); - uint8 *buffer_ptr = buffer; - for (int i=0; i -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "serial.h" -#include "serial_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// These messages are sent to the serial process -const uint32 MSG_QUERY = 'qery'; // Query port status, return status in control_io -const uint32 MSG_SET_PARAMS = 'setp'; // Set serial parameters (parameters in control_io) -const uint32 MSG_SET_PAR_PARAMS = 'pstp'; // Set parallel parameters (parameters in control_io) -const uint32 MSG_KILL_IO = 'kill'; // Kill pending I/O requests -const uint32 MSG_BREAK = 'brek'; // Send break -const uint32 MSG_RESET = 'rset'; // Reset channel -const uint32 MSG_PRIME_IN = 'prin'; // Data input -const uint32 MSG_PRIME_OUT = 'pout'; // Data output - -struct SerMessage : public Message { - SerMessage(uint32 what_, const struct MsgPort *reply_port = NULL) - { - what = what_; - mn_ReplyPort = (struct MsgPort *)reply_port; - mn_Length = sizeof(*this); - } - uint32 what; - uint32 pb; -}; - - -// Driver private variables -class ASERDPort : public SERDPort { -public: - ASERDPort(const char *dev) - { - device_name = dev; - if (dev && dev[0] == '*') { - is_parallel = true; - device_name++; - } else - is_parallel = false; - control_io = NULL; - serial_proc = NULL; - reply_port = NULL; - } - - virtual ~ASERDPort() - { - } - - virtual int16 open(uint16 config); - virtual int16 prime_in(uint32 pb, uint32 dce); - virtual int16 prime_out(uint32 pb, uint32 dce); - virtual int16 control(uint32 pb, uint32 dce, uint16 code); - virtual int16 status(uint32 pb, uint32 dce, uint16 code); - virtual int16 close(void); - -private: - bool configure(uint16 config); - void set_handshake(uint32 s, bool with_dtr); - void send_to_proc(uint32 what, uint32 pb = 0); - bool query(void); - bool set_params(void); - bool set_par_params(void); - void conv_error(struct IOExtSer *io, uint32 dt); - static void serial_func(void); - - const char *device_name; // Device name - bool is_parallel; // Flag: Port is parallel - IOExtSer *control_io; // IORequest for setting serial port characteristics etc. - - struct Process *serial_proc; // Serial device handler process - bool proc_error; // Flag: process didn't initialize - struct MsgPort *proc_port; // Message port of process, for communication with main task - struct MsgPort *reply_port; // Reply port for communication with process - - uint8 err_mask; // shkErrs -}; - - -// Global variables -static void *proc_arg; // Argument to process -extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp) - - -/* - * Initialization - */ - -void SerialInit(void) -{ - // Read serial preferences and create structs for both ports - the_serd_port[0] = new ASERDPort(PrefsFindString("seriala")); - the_serd_port[1] = new ASERDPort(PrefsFindString("serialb")); -} - - -/* - * Deinitialization - */ - -void SerialExit(void) -{ - delete (ASERDPort *)the_serd_port[0]; - delete (ASERDPort *)the_serd_port[1]; -} - - -/* - * Open serial port - */ - -int16 ASERDPort::open(uint16 config) -{ - // Don't open NULL name devices - if (device_name == NULL) - return openErr; - - // Init variables - err_mask = 0; - - // Create message port - reply_port = CreateMsgPort(); - if (reply_port == NULL) - goto open_error; - - // Start process - proc_error = false; - proc_arg = this; - SetSignal(0, SIGF_SINGLE); - serial_proc = CreateNewProcTags( - NP_Entry, (ULONG)serial_func, - NP_Name, (ULONG)"Basilisk II Serial Task", - NP_Priority, 1, - TAG_END - ); - if (serial_proc == NULL) - goto open_error; - - // Wait for signal from process - Wait(SIGF_SINGLE); - - // Initialization error? Then bail out - if (proc_error) - goto open_error; - - // Configure port - configure(config); - return noErr; - -open_error: - serial_proc = NULL; - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } - return openErr; -} - - -/* - * Read data from port - */ - -int16 ASERDPort::prime_in(uint32 pb, uint32 dce) -{ - // Send input command to serial process - D(bug("primein\n")); - read_done = false; - read_pending = true; - WriteMacInt32(input_dt + serdtDCE, dce); - send_to_proc(MSG_PRIME_IN, pb); - return 1; // Command in progress -} - - -/* - * Write data to port - */ - -int16 ASERDPort::prime_out(uint32 pb, uint32 dce) -{ - // Send output command to serial process - D(bug("primeout\n")); - write_done = false; - write_pending = true; - WriteMacInt32(output_dt + serdtDCE, dce); - send_to_proc(MSG_PRIME_OUT, pb); - return 1; // Command in progress -} - - -/* - * Control calls - */ - -int16 ASERDPort::control(uint32 pb, uint32 dce, uint16 code) -{ - D(bug("control(%ld)\n", (uint32)code)); - switch (code) { - case 1: // KillIO - send_to_proc(MSG_KILL_IO); - return noErr; - - case kSERDConfiguration: - if (configure(ReadMacInt16(pb + csParam))) - return noErr; - else - return paramErr; - - case kSERDInputBuffer: { - if (is_parallel) - return noErr; - int buf = ReadMacInt16(pb + csParam + 4) & 0xffffffc0; - if (buf < 1024) // 1k minimum - buf = 1024; - D(bug(" buffer size is now %08lx\n", buf)); - control_io->io_RBufLen = buf; - return set_params() ? noErr : paramErr; - } - - case kSERDSerHShake: - set_handshake(pb + csParam, false); - return noErr; - - case kSERDSetBreak: - if (!is_parallel) - send_to_proc(MSG_BREAK); - return noErr; - - case kSERDClearBreak: - return noErr; - - case kSERDBaudRate: - if (is_parallel) - return noErr; - control_io->io_Baud = ReadMacInt16(pb + csParam); - D(bug(" baud rate %ld\n", control_io->io_Baud)); - return set_params() ? noErr : paramErr; - - case kSERDHandshake: - case kSERDHandshakeRS232: - set_handshake(pb + csParam, true); - return noErr; - - case kSERDClockMIDI: - if (is_parallel) - return noErr; - control_io->io_Baud = 31250; - control_io->io_SerFlags = SERF_XDISABLED | SERF_SHARED; - control_io->io_StopBits = 1; - control_io->io_ReadLen = control_io->io_WriteLen = 8; - return set_params() ? noErr : paramErr; - - case kSERDMiscOptions: - case kSERDAssertDTR: - case kSERDNegateDTR: - case kSERDSetPEChar: - case kSERDSetPEAltChar: - case kSERDAssertRTS: - case kSERDNegateRTS: - return noErr; // Not supported under AmigaOS - - case kSERD115KBaud: - if (is_parallel) - return noErr; - control_io->io_Baud = 115200; - return set_params() ? noErr : paramErr; - - case kSERD230KBaud: - case kSERDSetHighSpeed: - if (is_parallel) - return noErr; - control_io->io_Baud = 230400; - return set_params() ? noErr : paramErr; - - case kSERDResetChannel: - send_to_proc(MSG_RESET); - return noErr; - - default: - printf("WARNING: SerialControl(): unimplemented control code %d\n", code); - return controlErr; - } -} - - -/* - * Status calls - */ - -int16 ASERDPort::status(uint32 pb, uint32 dce, uint16 code) -{ - D(bug("status(%ld)\n", (uint32)code)); - switch (code) { - case kSERDInputCount: - WriteMacInt32(pb + csParam, 0); - if (!is_parallel) { - if (!query()) - return noErr; - D(bug("status(2) successful, returning %08lx\n", control_io->IOSer.io_Actual)); - WriteMacInt32(pb + csParam, control_io->IOSer.io_Actual); - } - return noErr; - - case kSERDStatus: { - uint32 p = pb + csParam; - WriteMacInt8(p + staCumErrs, cum_errors); - cum_errors = 0; - WriteMacInt8(p + staRdPend, read_pending); - WriteMacInt8(p + staWrPend, write_pending); - if (is_parallel) { - WriteMacInt8(p + staXOffSent, 0); - WriteMacInt8(p + staXOffHold, 0); - WriteMacInt8(p + staCtsHold, 0); - WriteMacInt8(p + staDsrHold, 0); - WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent); - } else { - query(); - WriteMacInt8(p + staXOffSent, - (control_io->io_Status & IO_STATF_XOFFREAD ? xOffWasSent : 0) - | (control_io->io_Status & (1 << 6) ? dtrNegated : 0)); // RTS - WriteMacInt8(p + staXOffHold, control_io->io_Status & IO_STATF_XOFFWRITE); - WriteMacInt8(p + staCtsHold, control_io->io_Status & (1 << 4)); // CTS - WriteMacInt8(p + staDsrHold, control_io->io_Status & (1 << 3)); // DSR - WriteMacInt8(p + staModemStatus, - (control_io->io_Status & (1 << 3) ? 0 : dsrEvent) - | (control_io->io_Status & (1 << 2) ? riEvent : 0) - | (control_io->io_Status & (1 << 5) ? 0 : dcdEvent) - | (control_io->io_Status & (1 << 4) ? 0 : ctsEvent) - | (control_io->io_Status & IO_STATF_READBREAK ? breakEvent : 0)); - } - return noErr; - } - - default: - printf("WARNING: SerialStatus(): unimplemented status code %d\n", code); - return statusErr; - } -} - - -/* - * Close serial port - */ - -int16 ASERDPort::close() -{ - // Stop process - if (serial_proc) { - SetSignal(0, SIGF_SINGLE); - Signal(&serial_proc->pr_Task, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - } - - // Delete reply port - if (reply_port) { - DeleteMsgPort(reply_port); - reply_port = NULL; - } - return noErr; -} - - -/* - * Configure serial port with MacOS config word - */ - -bool ASERDPort::configure(uint16 config) -{ - D(bug(" configure %04lx\n", (uint32)config)); - if (is_parallel) - return true; - - // Set number of stop bits - switch (config & 0xc000) { - case stop10: - control_io->io_StopBits = 1; - break; - case stop20: - control_io->io_StopBits = 2; - break; - default: - return false; - } - - // Set parity mode - switch (config & 0x3000) { - case noParity: - control_io->io_SerFlags &= ~SERF_PARTY_ON; - break; - case oddParity: - control_io->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD; - break; - case evenParity: - control_io->io_SerFlags |= SERF_PARTY_ON; - control_io->io_SerFlags &= ~SERF_PARTY_ODD; - break; - default: - return false; - } - - // Set number of data bits - switch (config & 0x0c00) { - case data5: - control_io->io_ReadLen = control_io->io_WriteLen = 5; - break; - case data6: - control_io->io_ReadLen = control_io->io_WriteLen = 6; - break; - case data7: - control_io->io_ReadLen = control_io->io_WriteLen = 7; - break; - case data8: - control_io->io_ReadLen = control_io->io_WriteLen = 8; - break; - } - - // Set baud rate - control_io->io_Baud = 115200 / ((config & 0x03ff) + 2); - return set_params(); -} - - -/* - * Set serial handshaking - */ - -void ASERDPort::set_handshake(uint32 s, bool with_dtr) -{ - D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n", - ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3), - ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7))); - - err_mask = ReadMacInt8(s + shkErrs); - - if (is_parallel) { - - // Parallel handshake - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - ((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE; - else - ((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE; - } else { - if (ReadMacInt8(s + shkFCTS)) - ((IOExtPar *)control_io)->io_ParFlags |= PARF_ACKMODE; - else - ((IOExtPar *)control_io)->io_ParFlags &= ~PARF_ACKMODE; - } - set_par_params(); - - } else { - - // Serial handshake - if (ReadMacInt8(s + shkFXOn) || ReadMacInt8(s + shkFInX)) - control_io->io_SerFlags &= ~SERF_XDISABLED; - else - control_io->io_SerFlags |= SERF_XDISABLED; - - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - control_io->io_SerFlags |= SERF_7WIRE; - else - control_io->io_SerFlags &= ~SERF_7WIRE; - } else { - if (ReadMacInt8(s + shkFCTS)) - control_io->io_SerFlags |= SERF_7WIRE; - else - control_io->io_SerFlags &= ~SERF_7WIRE; - } - control_io->io_CtlChar = ReadMacInt16(s + shkXOn) << 16; - set_params(); - } -} - - -/* - * Send message to serial process - */ - -void ASERDPort::send_to_proc(uint32 what, uint32 pb) -{ - D(bug("sending %08lx to serial_proc\n", what)); - SerMessage msg(what, reply_port); - msg.pb = pb; - PutMsg(proc_port, &msg); - WaitPort(reply_port); - GetMsg(reply_port); - D(bug(" sent\n")); -} - - -/* - * Query serial port status - */ - -bool ASERDPort::query(void) -{ - send_to_proc(MSG_QUERY); - return control_io->IOSer.io_Error == 0; -} - - -/* - * Set serial parameters - */ - -bool ASERDPort::set_params(void) -{ - // Set/clear RadBoogie - UBYTE flags = control_io->io_SerFlags; - if (!(flags & SERF_PARTY_ON) && (flags & SERF_XDISABLED) && control_io->io_ReadLen == 8) - control_io->io_SerFlags |= SERF_RAD_BOOGIE; - else - control_io->io_SerFlags &= ~SERF_RAD_BOOGIE; - - // Send message to serial process - send_to_proc(MSG_SET_PARAMS); - return control_io->IOSer.io_Error == 0; -} - - -/* - * Set parallel parameters - */ - -bool ASERDPort::set_par_params(void) -{ - send_to_proc(MSG_SET_PAR_PARAMS); - return control_io->IOSer.io_Error == 0; -} - - -/* - * Convert AmigaOS error code to MacOS error code, set serdtResult and cum_errors - */ - -void ASERDPort::conv_error(struct IOExtSer *io, uint32 dt) -{ - int16 oserr; - uint8 cum; - - BYTE err = io->IOSer.io_Error; - if (err == 0 || err == IOERR_NOCMD) { - oserr = 0; - cum = 0; - } else { - if (is_parallel) { - oserr = (err_mask & framingErr) ? rcvrErr : 0; - cum = framingErr; - } else { - switch (io->IOSer.io_Error) { - case SerErr_DetectedBreak: - oserr = breakRecd; - cum = breakErr; - break; - case SerErr_ParityErr: - oserr = (err_mask & parityErr) ? rcvrErr : 0; - cum = parityErr; - break; - case SerErr_BufOverflow: - oserr = (err_mask & swOverrunErr) ? rcvrErr : 0; - cum = swOverrunErr; - break; - case SerErr_LineErr: - oserr = (err_mask & hwOverrunErr) ? rcvrErr : 0; - cum = hwOverrunErr; - break; - default: - oserr = (err_mask & framingErr) ? rcvrErr : 0; - cum = framingErr; - break; - } - } - } - - WriteMacInt32(dt + serdtResult, oserr); - cum_errors |= cum; -} - - -/* - * Process for communication with the serial.device - */ - -__saveds void ASERDPort::serial_func(void) -{ - struct ASERDPort *obj = (ASERDPort *)proc_arg; - struct MsgPort *proc_port = NULL, *io_port = NULL, *control_port = NULL; - struct IOExtSer *read_io = NULL, *write_io = NULL, *control_io = NULL; - uint8 orig_params[sizeof(struct IOExtSer)]; - bool opened = false; - ULONG io_mask = 0, proc_port_mask = 0; - - // Default: error occured - obj->proc_error = true; - - // Create message port for communication with main task - proc_port = CreateMsgPort(); - if (proc_port == NULL) - goto quit; - proc_port_mask = 1 << proc_port->mp_SigBit; - - // Create message ports for serial.device I/O - io_port = CreateMsgPort(); - if (io_port == NULL) - goto quit; - io_mask = 1 << io_port->mp_SigBit; - control_port = CreateMsgPort(); - if (control_port == NULL) - goto quit; - - // Create IORequests - read_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer)); - write_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer)); - control_io = (struct IOExtSer *)CreateIORequest(control_port, sizeof(struct IOExtSer)); - if (read_io == NULL || write_io == NULL || control_io == NULL) - goto quit; - read_io->IOSer.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug - write_io->IOSer.io_Message.mn_Node.ln_Type = 0; - control_io->IOSer.io_Message.mn_Node.ln_Type = 0; - - // Parse device name - char dev_name[256]; - ULONG dev_unit; - if (sscanf(obj->device_name, "%[^/]/%ld", dev_name, &dev_unit) < 2) - goto quit; - - // Open device - if (obj->is_parallel) - ((IOExtPar *)read_io)->io_ParFlags = PARF_SHARED; - else - read_io->io_SerFlags = SERF_SHARED | SERF_7WIRE; - if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)read_io, 0) || read_io->IOSer.io_Device == NULL) - goto quit; - opened = true; - - // Copy IORequests - memcpy(write_io, read_io, sizeof(struct IOExtSer)); - memcpy(control_io, read_io, sizeof(struct IOExtSer)); - - // Attach control_io to control_port and set default values - control_io->IOSer.io_Message.mn_ReplyPort = control_port; - if (!obj->is_parallel) { - control_io->io_CtlChar = SER_DEFAULT_CTLCHAR; - control_io->io_RBufLen = 64; - control_io->io_ExtFlags = 0; - control_io->io_Baud = 9600; - control_io->io_BrkTime = 250000; - control_io->io_ReadLen = control_io->io_WriteLen = 8; - control_io->io_StopBits = 1; - control_io->io_SerFlags = SERF_SHARED; - control_io->IOSer.io_Command = SDCMD_SETPARAMS; - DoIO((struct IORequest *)control_io); - memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - } - - // Initialization went well, inform main task - obj->proc_port = proc_port; - obj->control_io = control_io; - obj->proc_error = false; - Signal(MainTask, SIGF_SINGLE); - - // Main loop - for (;;) { - - // Wait for I/O and messages (CTRL_C is used for quitting the task) - ULONG sig = Wait(proc_port_mask | io_mask | SIGBREAKF_CTRL_C); - - // Main task wants to quit us - if (sig & SIGBREAKF_CTRL_C) - break; - - // Main task sent a command to us - if (sig & proc_port_mask) { - struct SerMessage *msg; - while (msg = (SerMessage *)GetMsg(proc_port)) { - D(bug("serial_proc received %08lx\n", msg->what)); - switch (msg->what) { - case MSG_QUERY: - control_io->IOSer.io_Command = SDCMD_QUERY; - DoIO((struct IORequest *)control_io); - D(bug(" query returned %08lx, actual %08lx\n", control_io->IOSer.io_Error, control_io->IOSer.io_Actual)); - break; - - case MSG_SET_PARAMS: - // Only send SDCMD_SETPARAMS when configuration has changed - if (memcmp(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar))) { - memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - memcpy(&(read_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - memcpy(&(write_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar)); - control_io->IOSer.io_Command = SDCMD_SETPARAMS; - D(bug(" params %08lx %08lx %08lx %08lx %08lx %08lx\n", control_io->io_CtlChar, control_io->io_RBufLen, control_io->io_ExtFlags, control_io->io_Baud, control_io->io_BrkTime, *(uint32 *)((uint8 *)control_io + 76))); - DoIO((struct IORequest *)control_io); - D(bug(" set_parms returned %08lx\n", control_io->IOSer.io_Error)); - } - break; - - case MSG_SET_PAR_PARAMS: - control_io->IOSer.io_Command = PDCMD_SETPARAMS; - DoIO((struct IORequest *)control_io); - D(bug(" set_par_parms returned %08lx\n", control_io->IOSer.io_Error)); - break; - - case MSG_BREAK: - control_io->IOSer.io_Command = SDCMD_BREAK; - DoIO((struct IORequest *)control_io); - D(bug(" break returned %08lx\n", control_io->IOSer.io_Error)); - break; - - case MSG_RESET: - control_io->IOSer.io_Command = CMD_RESET; - DoIO((struct IORequest *)control_io); - D(bug(" reset returned %08lx\n", control_io->IOSer.io_Error)); - break; - - case MSG_KILL_IO: - AbortIO((struct IORequest *)read_io); - AbortIO((struct IORequest *)write_io); - WaitIO((struct IORequest *)read_io); - WaitIO((struct IORequest *)write_io); - obj->read_pending = obj->write_pending = false; - obj->read_done = obj->write_done = false; - break; - - case MSG_PRIME_IN: - read_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb; - read_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - read_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount); - read_io->IOSer.io_Actual = 0; - read_io->IOSer.io_Command = CMD_READ; - D(bug("serial_proc receiving %ld bytes from %08lx\n", read_io->IOSer.io_Length, read_io->IOSer.io_Data)); - SendIO((struct IORequest *)read_io); - break; - - case MSG_PRIME_OUT: { - write_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb; - write_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - write_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount); - write_io->IOSer.io_Actual = 0; - write_io->IOSer.io_Command = CMD_WRITE; - D(bug("serial_proc transmitting %ld bytes from %08lx\n", write_io->IOSer.io_Length, write_io->IOSer.io_Data)); -#if MONITOR - bug("Sending serial data:\n"); - uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - for (int i=0; iIOSer.io_Actual, read_io->IOSer.io_Error)); - uint32 pb = (uint32)read_io->IOSer.io_Message.mn_Node.ln_Name; -#if MONITOR - bug("Receiving serial data:\n"); - uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer)); - for (int i=0; iIOSer.io_Actual; i++) { - bug("%02lx ", adr[i]); - } - bug("\n"); -#endif - WriteMacInt32(pb + ioActCount, read_io->IOSer.io_Actual); - obj->conv_error(read_io, obj->input_dt); - obj->read_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } else if (io == write_io) { - D(bug("write_io complete, %ld bytes sent, error %ld\n", write_io->IOSer.io_Actual, write_io->IOSer.io_Error)); - uint32 pb = (uint32)write_io->IOSer.io_Message.mn_Node.ln_Name; - WriteMacInt32(pb + ioActCount, write_io->IOSer.io_Actual); - obj->conv_error(write_io, obj->output_dt); - obj->write_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - } - } -quit: - - // Close everything - if (opened) { - if (CheckIO((struct IORequest *)write_io) == 0) { - AbortIO((struct IORequest *)write_io); - WaitIO((struct IORequest *)write_io); - } - if (CheckIO((struct IORequest *)read_io) == 0) { - AbortIO((struct IORequest *)read_io); - WaitIO((struct IORequest *)read_io); - } - CloseDevice((struct IORequest *)read_io); - } - if (control_io) - DeleteIORequest(control_io); - if (write_io) - DeleteIORequest(write_io); - if (read_io) - DeleteIORequest(read_io); - if (control_port) - DeleteMsgPort(control_port); - if (io_port) - DeleteMsgPort(io_port); - - // Send signal to main task to confirm termination - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} diff --git a/BasiliskII/src/AmigaOS/sys_amiga.cpp b/BasiliskII/src/AmigaOS/sys_amiga.cpp deleted file mode 100644 index 617df7b0a..000000000 --- a/BasiliskII/src/AmigaOS/sys_amiga.cpp +++ /dev/null @@ -1,1122 +0,0 @@ -/* - * sys_amiga.cpp - System dependent routines, Amiga implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "sys.h" - -#define DEBUG 0 -#include "debug.h" - - -// File handles are pointers to these structures -struct file_handle { - bool is_file; // Flag: plain file or /dev/something? - bool read_only; // Copy of Sys_open() flag - loff_t start_byte; // Size of file header (if any) - loff_t size; // Size of file/device (minus header) - - BPTR f; // AmigaDOS file handle (if is_file == true) - - struct IOStdReq *io; // Pointer to IORequest (if is_file == false) - ULONG block_size; // Block size of device (must be a power of two) - bool is_nsd; // New style device? - bool does_64bit; // Supports 64 bit trackdisk commands? - bool is_ejected; // Volume has been (logically) ejected - bool is_2060scsi; // Enable workaround for 2060scsi.device CD-ROM TD_READ bug -}; - - -// FileInfoBlock (must be global because it has to be on a longword boundary) -static struct FileInfoBlock FIB; - -// Message port for device communication -static struct MsgPort *the_port = NULL; - -// Temporary buffer in chip memory -const int TMP_BUF_SIZE = 0x10000; -static UBYTE *tmp_buf = NULL; - - -/* - * Initialization - */ - -void SysInit(void) -{ - // Create port and temporary buffer - the_port = CreateMsgPort(); - tmp_buf = (UBYTE *)AllocMem(TMP_BUF_SIZE, MEMF_CHIP | MEMF_PUBLIC); - if (the_port == NULL || tmp_buf == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } -} - - -/* - * Deinitialization - */ - -void SysExit(void) -{ - // Delete port and temporary buffer - if (the_port) { - DeleteMsgPort(the_port); - the_port = NULL; - } - if (tmp_buf) { - FreeMem(tmp_buf, TMP_BUF_SIZE); - tmp_buf = NULL; - } -} - - -/* - * This gets called when no "floppy" prefs items are found - * It scans for available floppy drives and adds appropriate prefs items - */ - -void SysAddFloppyPrefs(void) -{ - for (int i=0; i<4; i++) { - ULONG id = GetUnitID(i); - if (id == DRT_150RPM) { // We need an HD drive - char str[256]; - sprintf(str, "/dev/mfm.device/%d/0/0/2880/512", i); - PrefsAddString("floppy", str); - } - } -} - - -/* - * This gets called when no "disk" prefs items are found - * It scans for available HFS volumes and adds appropriate prefs items - */ - -void SysAddDiskPrefs(void) -{ - // AmigaOS doesn't support MacOS partitioning, so this probably doesn't make much sense... -} - - -/* - * This gets called when no "cdrom" prefs items are found - * It scans for available CD-ROM drives and adds appropriate prefs items - */ - -void SysAddCDROMPrefs(void) -{ - // Don't scan for drives if nocdrom option given - if (PrefsFindBool("nocdrom")) - return; - - //!! -} - - -/* - * Add default serial prefs (must be added, even if no ports present) - */ - -void SysAddSerialPrefs(void) -{ - PrefsAddString("seriala", "serial.device/0"); - PrefsAddString("serialb", "*parallel.device/0"); -} - - -/* - * Open file/device, create new file handle (returns NULL on error) - * - * Format for device names: /dev////// - */ - -void *Sys_open(const char *name, bool read_only) -{ - bool is_file = (strstr(name, "/dev/") != name); - - D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write")); - - // File or device? - if (is_file) { - - // File, open it and get stats - BPTR f = Open((char *)name, MODE_OLDFILE); - if (!f) - return NULL; - if (!ExamineFH(f, &FIB)) { - Close(f); - return NULL; - } - - // Check if file is write protected - if (FIB.fib_Protection & FIBF_WRITE) - read_only = true; - - // Create file_handle - file_handle *fh = new file_handle; - fh->f = f; - fh->is_file = true; - fh->read_only = read_only; - - // Detect disk image file layout - loff_t size = FIB.fib_Size; - Seek(fh->f, 0, OFFSET_BEGINNING); - Read(fh->f, tmp_buf, 256); - FileDiskLayout(size, tmp_buf, fh->start_byte, fh->size); - return fh; - - } else { - - // Device, parse string - char dev_name[256]; - ULONG dev_unit = 0, dev_flags = 0, dev_start = 0, dev_size = 16, dev_bsize = 512; - if (sscanf(name, "/dev/%[^/]/%ld/%ld/%ld/%ld/%ld", dev_name, &dev_unit, &dev_flags, &dev_start, &dev_size, &dev_bsize) < 2) - return NULL; - - // Create IORequest - struct IOStdReq *io = (struct IOStdReq *)CreateIORequest(the_port, sizeof(struct IOExtTD)); - if (io == NULL) - return NULL; - - // Open device - if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)io, dev_flags)) { - D(bug(" couldn't open device\n")); - DeleteIORequest(io); - return NULL; - } - - // Check for new style device - bool is_nsd = false, does_64bit = false; - struct NSDeviceQueryResult nsdqr; - nsdqr.DevQueryFormat = 0; - nsdqr.SizeAvailable = 0; - io->io_Command = NSCMD_DEVICEQUERY; - io->io_Length = sizeof(nsdqr); - io->io_Data = (APTR)&nsdqr; - LONG error = DoIO((struct IORequest *)io); - D(bug("DEVICEQUERY returned %ld (length %ld, actual %ld)\n", error, io->io_Length, io->io_Actual)); - if ((!error) && (io->io_Actual >= 16) && (io->io_Actual <= sizeof(nsdqr)) && (nsdqr.SizeAvailable == io->io_Actual)) { - - // Looks like an NSD - is_nsd = true; - D(bug(" new style device, type %ld\n", nsdqr.DeviceType)); - - // We only work with trackdisk-like devices - if (nsdqr.DeviceType != NSDEVTYPE_TRACKDISK) { - CloseDevice((struct IORequest *)io); - DeleteIORequest(io); - return NULL; - } - - // Check whether device is 64 bit capable - UWORD *cmdcheck; - for (cmdcheck = nsdqr.SupportedCommands; *cmdcheck; cmdcheck++) { - if (*cmdcheck == NSCMD_TD_READ64) { - D(bug(" supports 64 bit commands\n")); - does_64bit = true; - } - } - } - - // Create file_handle - file_handle *fh = new file_handle; - fh->io = io; - fh->is_file = false; - fh->read_only = read_only; - fh->start_byte = (loff_t)dev_start * dev_bsize; - fh->size = (loff_t)dev_size * dev_bsize; - fh->block_size = dev_bsize; - fh->is_nsd = is_nsd; - fh->does_64bit = does_64bit; - fh->is_ejected = false; - fh->is_2060scsi = (strcmp(dev_name, "2060scsi.device") == 0); - return fh; - } -} - - -/* - * Close file/device, delete file handle - */ - -void Sys_close(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - D(bug("Sys_close(%08lx)\n", arg)); - - // File or device? - if (fh->is_file) { - - // File, simply close it - Close(fh->f); - - } else { - - // Device, close it and delete IORequest - fh->io->io_Command = CMD_UPDATE; - DoIO((struct IORequest *)fh->io); - - fh->io->io_Command = TD_MOTOR; - fh->io->io_Length = 0; - DoIO((struct IORequest *)fh->io); - - CloseDevice((struct IORequest *)fh->io); - DeleteIORequest(fh->io); - } - delete fh; -} - - -/* - * Send one I/O request, using 64-bit addressing if the device supports it - */ - -static loff_t send_io_request(file_handle *fh, bool writing, ULONG length, loff_t offset, APTR data) -{ - if (fh->does_64bit) { - fh->io->io_Command = writing ? NSCMD_TD_WRITE64 : NSCMD_TD_READ64; - fh->io->io_Actual = offset >> 32; - } else { - fh->io->io_Command = writing ? CMD_WRITE : CMD_READ; - fh->io->io_Actual = 0; - } - fh->io->io_Length = length; - fh->io->io_Offset = offset; - fh->io->io_Data = data; - - if (fh->is_2060scsi && fh->block_size == 2048) { - - // 2060scsi.device has serious problems reading CD-ROMs via TD_READ - static struct SCSICmd scsi; - const int SENSE_LENGTH = 256; - static UBYTE sense_buffer[SENSE_LENGTH]; // Buffer for autosense data - static UBYTE cmd_buffer[10] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - D(bug("send_io_request length=%lu offset=%lu\n", length, (ULONG) offset)); - - memset(sense_buffer, 0, sizeof(sense_buffer)); - - scsi.scsi_Command = cmd_buffer; - scsi.scsi_CmdLength = sizeof(cmd_buffer); - scsi.scsi_SenseData = sense_buffer; - scsi.scsi_SenseLength = SENSE_LENGTH; - scsi.scsi_Flags = SCSIF_AUTOSENSE | (writing ? SCSIF_WRITE : SCSIF_READ); - scsi.scsi_Data = (UWORD *) data; - scsi.scsi_Length = length; - - ULONG block_offset = (ULONG) offset / fh->block_size; - ULONG block_length = length / fh->block_size; - - cmd_buffer[2] = block_offset >> 24; - cmd_buffer[3] = block_offset >> 16; - cmd_buffer[4] = block_offset >> 8; - cmd_buffer[5] = block_offset & 0xff; - - cmd_buffer[7] = block_length >> 8; - cmd_buffer[8] = block_length & 0xff; - - fh->io->io_Command = HD_SCSICMD; - fh->io->io_Actual = 0; - fh->io->io_Offset = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - - BYTE result = DoIO((struct IORequest *)fh->io); - - if (result) { - D(bug("send_io_request SCSI FAIL result=%lu\n", result)); - - if (result == HFERR_BadStatus) { - D(bug("send_io_request SCSI Status=%lu\n", scsi.scsi_Status)); - if (scsi.scsi_Status == 2) { - D(bug("send_io_request Sense Key=%02lx\n", sense_buffer[2] & 0x0f)); - D(bug("send_io_request ASC=%02lx ASCQ=%02lx\n", sense_buffer[12], sense_buffer[13])); - } - } - return 0; - } - - D(bug("send_io_request SCSI Actual=%lu\n", scsi.scsi_Actual)); - - if (scsi.scsi_Actual != length) - return 0; - - return scsi.scsi_Actual; - - } else { - -// if (DoIO((struct IORequest *)fh->io) || fh->io->io_Actual != length) - if (DoIO((struct IORequest *)fh->io)) - { - D(bug("send_io_request/%ld: Actual=%lu length=%lu Err=%ld\n", __LINE__, fh->io->io_Actual, length, fh->io->io_Error)); - return 0; - } - return fh->io->io_Actual; - } -} - - -/* - * Read "length" bytes from file/device, starting at "offset", to "buffer", - * returns number of bytes read (or 0) - */ - -size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - { - D(bug("Sys_read/%ld return 0\n", __LINE__)); - return 0; - } - - D(bug("Sys_read/%ld length=%ld\n", __LINE__, length)); - - // File or device? - if (fh->is_file) { - - // File, seek to position - if (Seek(fh->f, offset + fh->start_byte, OFFSET_BEGINNING) == -1) - { - D(bug("Sys_read/%ld return 0\n", __LINE__)); - return 0; - } - - // Read data - LONG actual = Read(fh->f, buffer, length); - if (actual == -1) - { - D(bug("Sys_read/%ld return 0\n", __LINE__)); - return 0; - } - else - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, actual)); - return actual; - } - - } else { - - // Device, pre-read (partial read of first block) necessary? - loff_t pos = offset + fh->start_byte; - size_t actual = 0; - uint32 pre_offset = pos % fh->block_size; - if (pre_offset) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos - pre_offset, tmp_buf) == 0) - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data to destination buffer - size_t pre_length = fh->block_size - pre_offset; - if (pre_length > length) - pre_length = length; - memcpy(buffer, tmp_buf + pre_offset, pre_length); - - // Adjust data pointers - buffer = (uint8 *)buffer + pre_length; - pos += pre_length; - length -= pre_length; - actual += pre_length; - } - - // Main read (complete reads of middle blocks) possible? - if (length >= fh->block_size) { - - // Yes, read blocks - size_t main_length = length & ~(fh->block_size - 1); - if (send_io_request(fh, false, main_length, pos, buffer) == 0) - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Adjust data pointers - buffer = (uint8 *)buffer + main_length; - pos += main_length; - length -= main_length; - actual += main_length; - } - - // Post-read (partial read of last block) necessary? - if (length) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos, tmp_buf) == 0) - { - D(bug("Sys_read/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data to destination buffer - memcpy(buffer, tmp_buf, length); - actual += length; - } - - D(bug("Sys_read/%ld return %ld\n", __LINE__, actual)); - return actual; - } -} - - -/* - * Write "length" bytes from "buffer" to file/device, starting at "offset", - * returns number of bytes written (or 0) - */ - -size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - D(bug("Sys_write/%ld length=%ld\n", __LINE__, length)); - - // File or device? - if (fh->is_file) { - - // File, seek to position if necessary - if (Seek(fh->f, offset + fh->start_byte, OFFSET_BEGINNING) == -1) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Write data - LONG actual = Write(fh->f, buffer, length); - if (actual == -1) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - else - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, actual)); - return actual; - } - - } else { - - // Device, pre-write (partial write of first block) necessary - loff_t pos = offset + fh->start_byte; - size_t actual = 0; - uint32 pre_offset = pos % fh->block_size; - if (pre_offset) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos - pre_offset, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data from source buffer - size_t pre_length = fh->block_size - pre_offset; - if (pre_length > length) - pre_length = length; - memcpy(tmp_buf + pre_offset, buffer, pre_length); - - // Write block back - if (send_io_request(fh, true, fh->block_size, pos - pre_offset, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Adjust data pointers - buffer = (uint8 *)buffer + pre_length; - pos += pre_length; - length -= pre_length; - actual += pre_length; - } - - // Main write (complete writes of middle blocks) possible? - if (length >= fh->block_size) { - - // Yes, write blocks - size_t main_length = length & ~(fh->block_size - 1); - if (send_io_request(fh, true, main_length, pos, buffer) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Adjust data pointers - buffer = (uint8 *)buffer + main_length; - pos += main_length; - length -= main_length; - actual += main_length; - } - - // Post-write (partial write of last block) necessary? - if (length) { - - // Yes, read one block - if (send_io_request(fh, false, fh->block_size, pos, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - - // Copy data from source buffer - memcpy(buffer, tmp_buf, length); - - // Write block back - if (send_io_request(fh, true, fh->block_size, pos, tmp_buf) == 0) - { - D(bug("Sys_write/%ld return %ld\n", __LINE__, 0)); - return 0; - } - actual += length; - } - - D(bug("Sys_write/%ld return %ld\n", __LINE__, actual)); - return actual; - } -} - - -/* - * Return size of file/device (minus header) - */ - -loff_t SysGetFileSize(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - return fh->size; -} - - -/* - * Eject volume (if applicable) - */ - -void SysEject(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Flush buffer, turn off the drive motor and eject volume - fh->io->io_Command = CMD_UPDATE; - DoIO((struct IORequest *)fh->io); - - fh->io->io_Command = TD_MOTOR; - fh->io->io_Length = 0; - DoIO((struct IORequest *)fh->io); - - fh->io->io_Command = TD_EJECT; - fh->io->io_Length = 1; - DoIO((struct IORequest *)fh->io); - - fh->is_ejected = true; - } -} - - -/* - * Format volume (if applicable) - */ - -bool SysFormat(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - //!! - return true; -} - - -/* - * Check if file/device is read-only (this includes the read-only flag on Sys_open()) - */ - -bool SysIsReadOnly(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) { - - // File, return flag given to Sys_open - return fh->read_only; - - } else { - - // Device, check write protection - fh->io->io_Command = TD_PROTSTATUS; - DoIO((struct IORequest *)fh->io); - if (fh->io->io_Actual) - return true; - else - return fh->read_only; - } -} - - -/* - * Check if the given file handle refers to a fixed or a removable disk - */ - -bool SysIsFixedDisk(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - return true; -} - - -/* - * Check if a disk is inserted in the drive (always true for files) - */ - -bool SysIsDiskInserted(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return true; - else { - - // Check medium status - fh->io->io_Command = TD_CHANGESTATE; - fh->io->io_Actual = 0; - DoIO((struct IORequest *)fh->io); - bool inserted = (fh->io->io_Actual == 0); - - if (!inserted) { - // Disk was ejected and has now been taken out - fh->is_ejected = false; - } - - if (fh->is_ejected) { - // Disk was ejected but has not yet been taken out, report it as - // no longer in the drive - return false; - } else - return inserted; - } -} - - -/* - * Prevent medium removal (if applicable) - */ - -void SysPreventRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send PREVENT ALLOW MEDIUM REMOVAL SCSI command - struct SCSICmd scsi; - static const UBYTE the_cmd[6] = {0x1e, 0, 0, 0, 1, 0}; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)the_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - DoIO((struct IORequest *)fh->io); - } -} - - -/* - * Allow medium removal (if applicable) - */ - -void SysAllowRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send PREVENT ALLOW MEDIUM REMOVAL SCSI command - struct SCSICmd scsi; - static const UBYTE the_cmd[6] = {0x1e, 0, 0, 0, 0, 0}; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)the_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - DoIO((struct IORequest *)fh->io); - } -} - - -/* - * Read CD-ROM TOC (binary MSF format, 804 bytes max.) - */ - -bool SysCDReadTOC(void *arg, uint8 *toc) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send READ TOC MSF SCSI command - struct SCSICmd scsi; - static const UBYTE read_toc_cmd[10] = {0x43, 0x02, 0, 0, 0, 0, 0, 0x03, 0x24, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 804; - scsi.scsi_Command = (UBYTE *)read_toc_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - memcpy(toc, tmp_buf, 804); - return true; - } -} - - -/* - * Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard) - */ - -bool SysCDGetPosition(void *arg, uint8 *pos) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send READ SUB-CHANNEL SCSI command - struct SCSICmd scsi; - static const UBYTE read_subq_cmd[10] = {0x42, 0x02, 0x40, 0x01, 0, 0, 0, 0, 0x10, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 16; - scsi.scsi_Command = (UBYTE *)read_subq_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - memcpy(pos, tmp_buf, 16); - return true; - } -} - - -/* - * Play CD audio - */ - -bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send PLAY AUDIO MSF SCSI command - struct SCSICmd scsi; - UBYTE play_cmd[10] = {0x47, 0, 0, start_m, start_s, start_f, end_m, end_s, end_f, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = play_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Pause CD audio - */ - -bool SysCDPause(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send PAUSE RESUME SCSI command - struct SCSICmd scsi; - static const UBYTE pause_cmd[10] = {0x4b, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)pause_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Resume paused CD audio - */ - -bool SysCDResume(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - // Send PAUSE RESUME SCSI command - struct SCSICmd scsi; - static const UBYTE resume_cmd[10] = {0x4b, 0, 0, 0, 0, 0, 0, 0, 1, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = (UBYTE *)resume_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Stop CD audio - */ - -bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return false; - else { - - uint8 end_m = lead_out_m; - uint8 end_s = lead_out_s; - uint8 end_f = lead_out_f + 1; - if (end_f >= 75) { - end_f = 0; - end_s++; - if (end_s >= 60) { - end_s = 0; - end_m++; - } - } - - // Send PLAY AUDIO MSF SCSI command (play first frame of lead-out area) - struct SCSICmd scsi; - UBYTE play_cmd[10] = {0x47, 0, 0, lead_out_m, lead_out_s, lead_out_f, end_m, end_s, end_f, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 0; - scsi.scsi_Command = play_cmd; - scsi.scsi_CmdLength = 10; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return false; - return true; - } -} - - -/* - * Perform CD audio fast-forward/fast-reverse operation starting from specified address - */ - -bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - //!! - return false; -} - - -/* - * Set CD audio volume (0..255 each channel) - */ - -void SysCDSetVolume(void *arg, uint8 left, uint8 right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send MODE SENSE (CD-ROM Audio Control Parameters Page) SCSI command - struct SCSICmd scsi; - static const UBYTE mode_sense_cmd[6] = {0x1a, 0x08, 0x0e, 0, 20, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 20; - scsi.scsi_Command = (UBYTE *)mode_sense_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return; - - tmp_buf[6] = 0x04; // Immed - tmp_buf[9] = 0; // LBA/sec format - tmp_buf[10] = 0; // LBA/sec - tmp_buf[11] = 0; - tmp_buf[13] = left; // Port 0 volume - tmp_buf[15] = right; // Port 1 volume - - // Send MODE SELECT (CD-ROM Audio Control Parameters Page) SCSI command - static const UBYTE mode_select_cmd[6] = {0x15, 0x10, 0, 0, 20, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 20; - scsi.scsi_Command = (UBYTE *)mode_select_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_WRITE; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - DoIO((struct IORequest *)fh->io); - } -} - - -/* - * Get CD audio volume (0..255 each channel) - */ - -void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - - // Send MODE SENSE (CD-ROM Audio Control Parameters Page) SCSI command - struct SCSICmd scsi; - static const UBYTE mode_sense_cmd[6] = {0x1a, 0x08, 0x0e, 0, 20, 0}; - scsi.scsi_Data = (UWORD *)tmp_buf; - scsi.scsi_Length = 20; - scsi.scsi_Command = (UBYTE *)mode_sense_cmd; - scsi.scsi_CmdLength = 6; - scsi.scsi_Flags = SCSIF_READ; - scsi.scsi_Status = 0; - fh->io->io_Data = &scsi; - fh->io->io_Length = sizeof(scsi); - fh->io->io_Command = HD_SCSICMD; - if (DoIO((struct IORequest *)fh->io) || scsi.scsi_Status) - return; - left = tmp_buf[13]; // Port 0 volume - right = tmp_buf[15]; // Port 1 volume - } -} diff --git a/BasiliskII/src/AmigaOS/sysdeps.h b/BasiliskII/src/AmigaOS/sysdeps.h deleted file mode 100644 index 895058301..000000000 --- a/BasiliskII/src/AmigaOS/sysdeps.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * sysdeps.h - System dependent definitions for AmigaOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SYSDEPS_H -#define SYSDEPS_H - -#include -#include -#include -#include -#include -#include -#include - -#include "user_strings_amiga.h" - -// Mac and host address space are the same -#define REAL_ADDRESSING 1 - -// Using 68k natively -#define EMULATED_68K 0 - -// Mac ROM is not write protected -#define ROM_IS_WRITE_PROTECTED 0 -#define USE_SCRATCHMEM_SUBTERFUGE 1 - -// ExtFS is supported -#define SUPPORTS_EXTFS 1 - -// mon is not supported -#undef ENABLE_MON - -// Data types -typedef unsigned char uint8; -typedef signed char int8; -typedef unsigned short uint16; -typedef signed short int16; -typedef unsigned long uint32; -typedef signed long int32; -typedef unsigned long long uint64; -typedef signed long long int64; - -typedef unsigned long long loff_t; - -// Time data type for Time Manager emulation -typedef struct timeval tm_time_t; - -// Endianess conversion (not needed) -#define ntohs(x) (x) -#define ntohl(x) (x) -#define htons(x) (x) -#define htonl(x) (x) - -// Some systems don't define this (ExecBase->AttnFlags) -#ifndef AFF_68060 -#define AFF_68060 (1L<<7) -#endif - -#endif diff --git a/BasiliskII/src/AmigaOS/timer_amiga.cpp b/BasiliskII/src/AmigaOS/timer_amiga.cpp deleted file mode 100644 index ce5fd5156..000000000 --- a/BasiliskII/src/AmigaOS/timer_amiga.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * timer_amiga.cpp - Time Manager emulation, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include - -#include "sysdeps.h" -#include "timer.h" - -#define DEBUG 0 -#include "debug.h" - - -/* - * Return microseconds since boot (64 bit) - */ - -void Microseconds(uint32 &hi, uint32 &lo) -{ - D(bug("Microseconds\n")); - struct timeval tv; - GetSysTime(&tv); - uint64 tl = (uint64)tv.tv_secs * 1000000 + tv.tv_micro; - hi = tl >> 32; - lo = tl; -} - - -/* - * Return local date/time in Mac format (seconds since 1.1.1904) - */ - -uint32 TimerDateTime(void) -{ - ULONG secs, mics; - CurrentTime(&secs, &mics); - return secs + 0x8b31ef80; -} - - -/* - * Get current time - */ - -void timer_current_time(tm_time_t &t) -{ - GetSysTime(&t); -} - - -/* - * Add times - */ - -void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a; - AddTime(&res, &b); -} - - -/* - * Subtract times - */ - -void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a; - SubTime(&res, &b); -} - - -/* - * Compare times (<0: a < b, =0: a = b, >0: a > b) - */ - -int timer_cmp_time(tm_time_t a, tm_time_t b) -{ - return CmpTime(&b, &a); -} - - -/* - * Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t - */ - -void timer_mac2host_time(tm_time_t &res, int32 mactime) -{ - if (mactime > 0) { - res.tv_secs = mactime / 1000; // Time in milliseconds - res.tv_micro = (mactime % 1000) * 1000; - } else { - res.tv_secs = -mactime / 1000000; // Time in negative microseconds - res.tv_micro = -mactime % 1000000; - } -} - - -/* - * Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds) - * A negative input value for hosttime results in a zero return value - * As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds! - */ - -int32 timer_host2mac_time(tm_time_t hosttime) -{ - if (hosttime.tv_secs < 0) - return 0; - else { - uint64 t = (uint64)hosttime.tv_secs * 1000000 + hosttime.tv_micro; - if (t > 0x7fffffff) - return t / 1000; // Time in milliseconds - else - return -t; // Time in negative microseconds - } -} - - -/* - * Suspend emulator thread, virtual CPU in idle mode - */ - -void idle_wait(void) -{ - // XXX if you implement this make sure to call idle_resume() from TriggerInterrupt() -} - - -/* - * Resume execution of emulator thread, events just arrived - */ - -void idle_resume(void) -{ -} diff --git a/BasiliskII/src/AmigaOS/user_strings_amiga.cpp b/BasiliskII/src/AmigaOS/user_strings_amiga.cpp deleted file mode 100644 index 5b41a5879..000000000 --- a/BasiliskII/src/AmigaOS/user_strings_amiga.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * user_strings_amiga.cpp - AmigaOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "user_strings.h" - - -// Platform-specific string definitions -user_string_def platform_strings[] = { - // Common strings that have a platform-specific variant - {STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under AmigaOS. Basilisk II will try to unmount it."}, - {STR_EXTFS_CTRL, "Amiga Root"}, - {STR_EXTFS_NAME, "Amiga Directory Tree"}, - {STR_EXTFS_VOLUME_NAME, "Amiga"}, - - // Purely platform-specific strings - {STR_NO_PREPARE_EMUL_ERR, "PrepareEmul is not installed. Run PrepareEmul and then try again to start Basilisk II."}, - {STR_NO_GADTOOLS_LIB_ERR, "Cannot open gadtools.library V39."}, - {STR_NO_IFFPARSE_LIB_ERR, "Cannot open iffparse.library V39."}, - {STR_NO_ASL_LIB_ERR, "Cannot open asl.library V36."}, - {STR_NO_TIMER_DEV_ERR, "Cannot open timer.device."}, - {STR_NO_P96_MODE_ERR, "The selected screen mode is not a Picasso96 or CyberGraphX mode."}, - {STR_NO_VIDEO_MODE_ERR, "Cannot obtain selected video mode."}, - {STR_WRONG_SCREEN_DEPTH_ERR, "Basilisk II only supports 8, 16 or 24 bit screens."}, - {STR_WRONG_SCREEN_FORMAT_ERR, "Basilisk II only supports big-endian chunky ARGB screen modes."}, - {STR_ENFORCER_RUNNING_ERR, "Enforcer/CyberGuard is running. Remove and then try again to start Basilisk II."}, - - {STR_NOT_ETHERNET_WARN, "The selected network device is not an Ethernet device. Networking will be disabled."}, - {STR_NO_MULTICAST_WARN, "Your Ethernet card does not support multicast and is not usable with AppleTalk. Please report this to the manufacturer of the card."}, - {STR_NO_GTLAYOUT_LIB_WARN, "Cannot open gtlayout.library V39. The preferences editor GUI will not be available."}, - {STR_NO_AHI_WARN, "Cannot open ahi.device V2. Audio output will be disabled."}, - {STR_NO_AHI_CTRL_WARN, "Cannot open AHI control structure. Audio output will be disabled."}, - {STR_NOT_ENOUGH_MEM_WARN, "Could not get %lu MBytes of memory.\nShould I use the largest Block (%lu MBytes) instead ?"}, - - {STR_AHI_MODE_CTRL, "AHI Mode"}, - {STR_SCSI_MEMTYPE_CTRL, "Buffer Memory Type"}, - {STR_MEMTYPE_CHIP_LAB, "Chip"}, - {STR_MEMTYPE_24BITDMA_LAB, "24-Bit DMA"}, - {STR_MEMTYPE_ANY_LAB, "Any"}, - {STR_SCSI_DEVICES_CTRL, "Virtual SCSI Devices"}, - - {-1, NULL} // End marker -}; - - -/* - * Fetch pointer to string, given the string number - */ - -const char *GetString(int num) -{ - // First search for platform-specific string - int i = 0; - while (platform_strings[i].num >= 0) { - if (platform_strings[i].num == num) - return platform_strings[i].str; - i++; - } - - // Not found, search for common string - i = 0; - while (common_strings[i].num >= 0) { - if (common_strings[i].num == num) - return common_strings[i].str; - i++; - } - return NULL; -} diff --git a/BasiliskII/src/AmigaOS/user_strings_amiga.h b/BasiliskII/src/AmigaOS/user_strings_amiga.h deleted file mode 100644 index 8903e5e80..000000000 --- a/BasiliskII/src/AmigaOS/user_strings_amiga.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * user_strings_amiga.h - AmigaOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USER_STRINGS_AMIGA_H -#define USER_STRINGS_AMIGA_H - -enum { - STR_NO_PREPARE_EMUL_ERR = 10000, - STR_NO_GADTOOLS_LIB_ERR, - STR_NO_IFFPARSE_LIB_ERR, - STR_NO_ASL_LIB_ERR, - STR_NO_TIMER_DEV_ERR, - STR_NO_P96_MODE_ERR, - STR_NO_VIDEO_MODE_ERR, - STR_WRONG_SCREEN_DEPTH_ERR, - STR_WRONG_SCREEN_FORMAT_ERR, - STR_ENFORCER_RUNNING_ERR, - - STR_NOT_ETHERNET_WARN, - STR_NO_MULTICAST_WARN, - STR_NO_GTLAYOUT_LIB_WARN, - STR_NO_AHI_WARN, - STR_NO_AHI_CTRL_WARN, - STR_NOT_ENOUGH_MEM_WARN, - - STR_AHI_MODE_CTRL, - STR_SCSI_MEMTYPE_CTRL, - STR_MEMTYPE_CHIP_LAB, - STR_MEMTYPE_24BITDMA_LAB, - STR_MEMTYPE_ANY_LAB, - STR_SCSI_DEVICES_CTRL -}; - -#endif diff --git a/BasiliskII/src/AmigaOS/video_amiga.cpp b/BasiliskII/src/AmigaOS/video_amiga.cpp deleted file mode 100644 index 5e870a9c2..000000000 --- a/BasiliskII/src/AmigaOS/video_amiga.cpp +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * video_amiga.cpp - Video/graphics emulation, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#define __USE_SYSBASE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "adb.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" - -#define DEBUG 0 -#include "debug.h" - - -// Supported video modes -static vector VideoModes; - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_PIP, - DISPLAY_SCREEN_P96, - DISPLAY_SCREEN_CGFX -}; - -// Global variables -static int32 frame_skip; -static UWORD *null_pointer = NULL; // Blank mouse pointer data -static UWORD *current_pointer = (UWORD *)-1; // Currently visible mouse pointer data -static struct Process *periodic_proc = NULL; // Periodic process - -extern struct Task *MainTask; // Pointer to main task (from main_amiga.cpp) - - -// Amiga -> Mac raw keycode translation table -static const uint8 keycode2mac[0x80] = { - 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, 0x1a, // ` 1 2 3 4 5 6 7 - 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x2a, 0xff, 0x52, // 8 9 0 - = \ inv 0 - 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, // Q W E R T Y U I - 0x1f, 0x23, 0x21, 0x1e, 0xff, 0x53, 0x54, 0x55, // O P [ ] inv 1 2 3 - 0x00, 0x01, 0x02, 0x03, 0x05, 0x04, 0x26, 0x28, // A S D F G H J K - 0x25, 0x29, 0x27, 0x2a, 0xff, 0x56, 0x57, 0x58, // L ; ' # inv 4 5 6 - 0x32, 0x06, 0x07, 0x08, 0x09, 0x0b, 0x2d, 0x2e, // < Z X C V B N M - 0x2b, 0x2f, 0x2c, 0xff, 0x41, 0x59, 0x5b, 0x5c, // , . / inv . 7 8 9 - 0x31, 0x33, 0x30, 0x4c, 0x24, 0x35, 0x75, 0xff, // SPC BSP TAB ENT RET ESC DEL inv - 0xff, 0xff, 0x4e, 0xff, 0x3e, 0x3d, 0x3c, 0x3b, // inv inv - inv CUP CDN CRT CLF - 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, 0x62, 0x64, // F1 F2 F3 F4 F5 F6 F7 F8 - 0x65, 0x6d, 0x47, 0x51, 0x4b, 0x43, 0x45, 0x72, // F9 F10 ( ) / * + HLP - 0x38, 0x38, 0x39, 0x36, 0x3a, 0x3a, 0x37, 0x37, // SHL SHR CAP CTL ALL ALR AML AMR - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - - -class Amiga_monitor_desc : public monitor_desc { -public: - Amiga_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id, int default_display_type) - : monitor_desc(available_modes, default_depth, default_id), display_type(default_display_type) {}; - ~Amiga_monitor_desc() {}; - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -public: - int display_type; // See enum above -}; - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(Amiga_monitor_desc &m); - virtual ~driver_base(); - - virtual void set_palette(uint8 *pal, int num) {}; - virtual struct BitMap *get_bitmap() { return NULL; }; -public: - Amiga_monitor_desc &monitor; // Associated video monitor - const video_mode &mode; // Video mode handled by the driver - BOOL init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - struct Window *the_win; -}; - - -class driver_window : public driver_base { -public: - driver_window(Amiga_monitor_desc &m, int width, int height); - ~driver_window(); - - struct BitMap *get_bitmap() { return the_bitmap; }; - -private: - LONG black_pen, white_pen; - struct BitMap *the_bitmap; -}; - -class driver_pip : public driver_base { -public: - driver_pip(Amiga_monitor_desc &m, int width, int height); - ~driver_pip(); - - struct BitMap *get_bitmap() { return the_bitmap; }; - -private: - struct BitMap *the_bitmap; -}; - -class driver_screen_p96 : public driver_base { -public: - driver_screen_p96(Amiga_monitor_desc &m, ULONG mode_id); - ~driver_screen_p96(); - - void set_palette(uint8 *pal, int num); - -private: - struct Screen *the_screen; -}; - -class driver_screen_cgfx : public driver_base { -public: - driver_screen_cgfx(Amiga_monitor_desc &m, ULONG mode_id); - ~driver_screen_cgfx(); - - void set_palette(uint8 *pal, int num); - -private: - struct Screen *the_screen; -}; - - -static driver_base *drv = NULL; // Pointer to currently used driver object - - - -// Prototypes -static void periodic_func(void); -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth); -static void add_modes(uint32 width, uint32 height, video_depth depth); -static ULONG find_mode_for_depth(uint32 width, uint32 height, uint32 depth); -static ULONG bits_from_depth(video_depth depth); -static bool is_valid_modeid(int display_type, ULONG mode_id); -static bool check_modeid_p96(ULONG mode_id); -static bool check_modeid_cgfx(ULONG mode_id); - - -/* - * Initialization - */ - - -bool VideoInit(bool classic) -{ - video_depth default_depth = VDEPTH_1BIT; - int default_width, default_height; - int default_display_type = DISPLAY_WINDOW; - int window_width, window_height; // width and height for window display - ULONG screen_mode_id; // mode ID for screen display - - // Allocate blank mouse pointer data - null_pointer = (UWORD *)AllocMem(12, MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR); - if (null_pointer == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - return false; - } - - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - - // Get screen mode from preferences - const char *mode_str; - if (classic) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - default_width = window_width = 512; - default_height = window_height = 384; - - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &window_width, &window_height) == 2) - default_display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "pip/%d/%d", &window_width, &window_height) == 2 && P96Base) - default_display_type = DISPLAY_PIP; - else if (sscanf(mode_str, "scr/%08lx", &screen_mode_id) == 1 && (CyberGfxBase || P96Base)) { - if (P96Base && p96GetModeIDAttr(screen_mode_id, P96IDA_ISP96)) - default_display_type = DISPLAY_SCREEN_P96; - else if (CyberGfxBase && IsCyberModeID(screen_mode_id)) - default_display_type = DISPLAY_SCREEN_CGFX; - else { - ErrorAlert(STR_NO_P96_MODE_ERR); - return false; - } - } - } - - D(bug("default_display_type %d, window_width %d, window_height %d\n", default_display_type, window_width, window_height)); - - // Construct list of supported modes - switch (default_display_type) { - case DISPLAY_WINDOW: - default_width = window_width; - default_height = window_height; - default_depth = VDEPTH_1BIT; - add_modes(window_width, window_height, VDEPTH_1BIT); - break; - - case DISPLAY_PIP: - default_width = window_width; - default_height = window_height; - default_depth = VDEPTH_16BIT; - add_modes(window_width, window_height, VDEPTH_16BIT); - break; - - case DISPLAY_SCREEN_P96: - case DISPLAY_SCREEN_CGFX: - struct DimensionInfo dimInfo; - DisplayInfoHandle handle = FindDisplayInfo(screen_mode_id); - - if (handle == NULL) - return false; - - if (GetDisplayInfoData(handle, (UBYTE *) &dimInfo, sizeof(dimInfo), DTAG_DIMS, 0) <= 0) - return false; - - default_width = 1 + dimInfo.Nominal.MaxX - dimInfo.Nominal.MinX; - default_height = 1 + dimInfo.Nominal.MaxY - dimInfo.Nominal.MinY; - - switch (dimInfo.MaxDepth) { - case 1: - default_depth = VDEPTH_1BIT; - break; - case 8: - default_depth = VDEPTH_8BIT; - break; - case 15: - case 16: - default_depth = VDEPTH_16BIT; - break; - case 24: - case 32: - default_depth = VDEPTH_32BIT; - break; - } - - for (unsigned d=VDEPTH_8BIT; d<=VDEPTH_32BIT; d++) { - ULONG mode_id = find_mode_for_depth(default_width, default_height, bits_from_depth(video_depth(d))); - - if (is_valid_modeid(default_display_type, mode_id)) - add_modes(default_width, default_height, video_depth(d)); - } - break; - } - -#if DEBUG - bug("Available video modes:\n"); - vector::const_iterator i = VideoModes.begin(), end = VideoModes.end(); - while (i != end) { - bug(" %ld x %ld (ID %02lx), %ld colors\n", i->x, i->y, i->resolution_id, 1 << bits_from_depth(i->depth)); - ++i; - } -#endif - - D(bug("VideoInit/%ld: def_width=%ld def_height=%ld def_depth=%ld\n", \ - __LINE__, default_width, default_height, default_depth)); - - // Find requested default mode and open display - if (VideoModes.size() == 1) { - uint32 default_id ; - - // Create Amiga_monitor_desc for this (the only) display - default_id = VideoModes[0].resolution_id; - D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id)); - Amiga_monitor_desc *monitor = new Amiga_monitor_desc(VideoModes, default_depth, default_id, default_display_type); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); - - } else { - - // Find mode with specified dimensions - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - D(bug("VideoInit/%ld: w=%ld h=%ld d=%ld\n", __LINE__, i->x, i->y, bits_from_depth(i->depth))); - if (i->x == default_width && i->y == default_height && i->depth == default_depth) { - // Create Amiga_monitor_desc for this (the only) display - uint32 default_id = i->resolution_id; - D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id)); - Amiga_monitor_desc *monitor = new Amiga_monitor_desc(VideoModes, default_depth, default_id, default_display_type); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); - } - } - - // Create Amiga_monitor_desc for this (the only) display - uint32 default_id = VideoModes[0].resolution_id; - D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id)); - Amiga_monitor_desc *monitor = new Amiga_monitor_desc(VideoModes, default_depth, default_id, default_display_type); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); - } - - return true; -} - - -bool Amiga_monitor_desc::video_open() -{ - const video_mode &mode = get_current_mode(); - ULONG depth_bits = bits_from_depth(mode.depth); - ULONG ID = find_mode_for_depth(mode.x, mode.y, depth_bits); - - D(bug("video_open/%ld: width=%ld height=%ld depth=%ld ID=%08lx\n", __LINE__, mode.x, mode.y, depth_bits, ID)); - - if (ID == INVALID_ID) { - ErrorAlert(STR_NO_VIDEO_MODE_ERR); - return false; - } - - D(bug("video_open/%ld: display_type=%ld\n", __LINE__, display_type)); - - // Open display - switch (display_type) { - case DISPLAY_WINDOW: - drv = new driver_window(*this, mode.x, mode.y); - break; - - case DISPLAY_PIP: - drv = new driver_pip(*this, mode.x, mode.y); - break; - - case DISPLAY_SCREEN_P96: - drv = new driver_screen_p96(*this, ID); - break; - - case DISPLAY_SCREEN_CGFX: - drv = new driver_screen_cgfx(*this, ID); - break; - } - - D(bug("video_open/%ld: drv=%08lx\n", __LINE__, drv)); - - if (drv == NULL) - return false; - - D(bug("video_open/%ld: init_ok=%ld\n", __LINE__, drv->init_ok)); - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - - // Start periodic process - periodic_proc = CreateNewProcTags( - NP_Entry, (ULONG)periodic_func, - NP_Name, (ULONG)"Basilisk II IDCMP Handler", - NP_Priority, 0, - TAG_END - ); - - D(bug("video_open/%ld: periodic_proc=%08lx\n", __LINE__, periodic_proc)); - - if (periodic_proc == NULL) { - ErrorAlert(STR_NO_MEM_ERR); - return false; - } - - return true; -} - - -void Amiga_monitor_desc::video_close() -{ - // Stop periodic process - if (periodic_proc) { - SetSignal(0, SIGF_SINGLE); - Signal(&periodic_proc->pr_Task, SIGBREAKF_CTRL_C); - Wait(SIGF_SINGLE); - } - - delete drv; - drv = NULL; - - // Free mouse pointer - if (null_pointer) { - FreeMem(null_pointer, 12); - null_pointer = NULL; - } -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); -} - - -/* - * Set palette - */ - -void Amiga_monitor_desc::set_palette(uint8 *pal, int num) -{ - drv->set_palette(pal, num); -} - - -/* - * Switch video mode - */ - -void Amiga_monitor_desc::switch_to_current_mode() -{ - // Close and reopen display - video_close(); - if (!video_open()) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ -} - - -/* - * Video message handling (not neccessary under AmigaOS, handled by periodic_func()) - */ - -void VideoInterrupt(void) -{ -} - - -/* - * Process for window refresh and message handling - */ - -static __saveds void periodic_func(void) -{ - struct MsgPort *timer_port = NULL; - struct timerequest *timer_io = NULL; - struct IntuiMessage *msg; - ULONG win_mask = 0, timer_mask = 0; - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Create message port for window and attach it - struct MsgPort *win_port = CreateMsgPort(); - if (win_port) { - win_mask = 1 << win_port->mp_SigBit; - drv->the_win->UserPort = win_port; - ModifyIDCMP(drv->the_win, IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_RAWKEY | - ((drv->monitor.display_type == DISPLAY_SCREEN_P96 || drv->monitor.display_type == DISPLAY_SCREEN_CGFX) ? IDCMP_DELTAMOVE : 0)); - } - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Start 60Hz timer for window refresh - if (drv->monitor.display_type == DISPLAY_WINDOW) { - timer_port = CreateMsgPort(); - if (timer_port) { - timer_io = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest)); - if (timer_io) { - if (!OpenDevice((UBYTE *) TIMERNAME, UNIT_MICROHZ, (struct IORequest *)timer_io, 0)) { - timer_mask = 1 << timer_port->mp_SigBit; - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16667 * frame_skip; - SendIO((struct IORequest *)timer_io); - } - } - } - } - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Main loop - for (;;) { - const video_mode &mode = drv->monitor.get_current_mode(); - - // Wait for timer and/or window (CTRL_C is used for quitting the task) - ULONG sig = Wait(win_mask | timer_mask | SIGBREAKF_CTRL_C); - - if (sig & SIGBREAKF_CTRL_C) - break; - -// D(bug("periodic_func/%ld: display_type=%ld the_win=%08lx\n", __LINE__, drv->monitor.display_type, drv->the_win)); - - if (sig & timer_mask) { - if (drv->get_bitmap()) { - // Timer tick, update display - BltTemplate(drv->get_bitmap()->Planes[0], 0, - drv->get_bitmap()->BytesPerRow, drv->the_win->RPort, - drv->the_win->BorderLeft, drv->the_win->BorderTop, - mode.x, mode.y); - } - - // Restart timer - timer_io->tr_node.io_Command = TR_ADDREQUEST; - timer_io->tr_time.tv_secs = 0; - timer_io->tr_time.tv_micro = 16667 * frame_skip; - SendIO((struct IORequest *)timer_io); - } - - if (sig & win_mask) { - - // Handle window messages - while (msg = (struct IntuiMessage *)GetMsg(win_port)) { - - // Get data from message and reply - ULONG cl = msg->Class; - UWORD code = msg->Code; - UWORD qualifier = msg->Qualifier; - WORD mx = msg->MouseX; - WORD my = msg->MouseY; - ReplyMsg((struct Message *)msg); - - // Handle message according to class - switch (cl) { - case IDCMP_MOUSEMOVE: - switch (drv->monitor.display_type) { - case DISPLAY_SCREEN_P96: - case DISPLAY_SCREEN_CGFX: -// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx, my)); - ADBMouseMoved(mx, my); - break; - default: -// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop)); - ADBMouseMoved(mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop); - if (mx < drv->the_win->BorderLeft - || my < drv->the_win->BorderTop - || mx >= drv->the_win->BorderLeft + mode.x - || my >= drv->the_win->BorderTop + mode.y) { - if (current_pointer) { - ClearPointer(drv->the_win); - current_pointer = NULL; - } - } else { - if (current_pointer != null_pointer) { - // Hide mouse pointer inside window - SetPointer(drv->the_win, null_pointer, 1, 16, 0, 0); - current_pointer = null_pointer; - } - } - break; - } - break; - - case IDCMP_MOUSEBUTTONS: - if (code == SELECTDOWN) - ADBMouseDown(0); - else if (code == SELECTUP) - ADBMouseUp(0); - else if (code == MENUDOWN) - ADBMouseDown(1); - else if (code == MENUUP) - ADBMouseUp(1); - else if (code == MIDDLEDOWN) - ADBMouseDown(2); - else if (code == MIDDLEUP) - ADBMouseUp(2); - break; - - case IDCMP_RAWKEY: - if (qualifier & IEQUALIFIER_REPEAT) // Keyboard repeat is done by MacOS - break; - if ((qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_LSHIFT | IEQUALIFIER_CONTROL)) == - (IEQUALIFIER_LALT | IEQUALIFIER_LSHIFT | IEQUALIFIER_CONTROL) && code == 0x5f) { - SetInterruptFlag(INTFLAG_NMI); - TriggerInterrupt(); - break; - } - - if (code & IECODE_UP_PREFIX) - ADBKeyUp(keycode2mac[code & 0x7f]); - else - ADBKeyDown(keycode2mac[code & 0x7f]); - break; - } - } - } - } - - D(bug("periodic_func/%ld: \n", __LINE__)); - - // Stop timer - if (timer_io) { - if (!CheckIO((struct IORequest *)timer_io)) - AbortIO((struct IORequest *)timer_io); - WaitIO((struct IORequest *)timer_io); - CloseDevice((struct IORequest *)timer_io); - DeleteIORequest(timer_io); - } - if (timer_port) - DeleteMsgPort(timer_port); - - // Remove port from window and delete it - Forbid(); - msg = (struct IntuiMessage *)win_port->mp_MsgList.lh_Head; - struct Node *succ; - while (succ = msg->ExecMessage.mn_Node.ln_Succ) { - if (msg->IDCMPWindow == drv->the_win) { - Remove((struct Node *)msg); - ReplyMsg((struct Message *)msg); - } - msg = (struct IntuiMessage *)succ; - } - drv->the_win->UserPort = NULL; - ModifyIDCMP(drv->the_win, 0); - Permit(); - DeleteMsgPort(win_port); - - // Main task asked for termination, send signal - Forbid(); - Signal(MainTask, SIGF_SINGLE); -} - - -// Add mode to list of supported modes -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth) -{ - video_mode mode; - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.depth = depth; - - D(bug("Added video mode: w=%ld h=%ld d=%ld\n", width, height, depth)); - - VideoModes.push_back(mode); -} - -// Add standard list of modes for given color depth -static void add_modes(uint32 width, uint32 height, video_depth depth) -{ - D(bug("add_modes: w=%ld h=%ld d=%ld\n", width, height, depth)); - - if (width >= 512 && height >= 384) - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); - if (width >= 640 && height >= 480) - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); - if (width >= 800 && height >= 600) - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); - if (width >= 1024 && height >= 768) - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); - if (width >= 1152 && height >= 870) - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); - if (width >= 1280 && height >= 1024) - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); - if (width >= 1600 && height >= 1200) - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); -} - - -static ULONG find_mode_for_depth(uint32 width, uint32 height, uint32 depth) -{ - ULONG ID = BestModeID(BIDTAG_NominalWidth, width, - BIDTAG_NominalHeight, height, - BIDTAG_Depth, depth, - BIDTAG_DIPFMustNotHave, DIPF_IS_ECS | DIPF_IS_HAM | DIPF_IS_AA, - TAG_END); - - return ID; -} - - -static ULONG bits_from_depth(video_depth depth) -{ - int bits = 1 << depth; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - - return bits; -} - - -static bool is_valid_modeid(int display_type, ULONG mode_id) -{ - if (INVALID_ID == mode_id) - return false; - - switch (display_type) { - case DISPLAY_SCREEN_P96: - return check_modeid_p96(mode_id); - break; - case DISPLAY_SCREEN_CGFX: - return check_modeid_cgfx(mode_id); - break; - default: - return false; - break; - } -} - - -static bool check_modeid_p96(ULONG mode_id) -{ - // Check if the mode is one we can handle - uint32 depth = p96GetModeIDAttr(mode_id, P96IDA_DEPTH); - uint32 format = p96GetModeIDAttr(mode_id, P96IDA_RGBFORMAT); - - D(bug("check_modeid_p96: mode_id=%08lx depth=%ld format=%ld\n", mode_id, depth, format)); - - if (!p96GetModeIDAttr(mode_id, P96IDA_ISP96)) - return false; - - switch (depth) { - case 8: - break; - case 15: - case 16: - if (format != RGBFB_R5G5B5) - return false; - break; - case 24: - case 32: - if (format != RGBFB_A8R8G8B8) - return false; - break; - default: - return false; - } - - return true; -} - - -static bool check_modeid_cgfx(ULONG mode_id) -{ - uint32 depth = GetCyberIDAttr(CYBRIDATTR_DEPTH, mode_id); - uint32 format = GetCyberIDAttr(CYBRIDATTR_PIXFMT, mode_id); - - D(bug("check_modeid_cgfx: mode_id=%08lx depth=%ld format=%ld\n", mode_id, depth, format)); - - if (!IsCyberModeID(mode_id)) - return false; - - switch (depth) { - case 8: - break; - case 15: - case 16: - if (format != PIXFMT_RGB15) - return false; - break; - case 24: - case 32: - if (format != PIXFMT_ARGB32) - return false; - break; - default: - return false; - } - - return true; -} - - -driver_base::driver_base(Amiga_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false) -{ -} - -driver_base::~driver_base() -{ -} - - -// Open window -driver_window::driver_window(Amiga_monitor_desc &m, int width, int height) - : black_pen(-1), white_pen(-1), driver_base(m) -{ - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Open window - the_win = OpenWindowTags(NULL, - WA_Left, 0, WA_Top, 0, - WA_InnerWidth, width, WA_InnerHeight, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_DragBar, true, - WA_DepthGadget, true, - WA_SizeGadget, false, - WA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - TAG_END - ); - if (the_win == NULL) { - init_ok = false; - ErrorAlert(STR_OPEN_WINDOW_ERR); - return; - } - - // Create bitmap ("height + 2" for safety) - the_bitmap = AllocBitMap(width, height + 2, 1, BMF_CLEAR, NULL); - if (the_bitmap == NULL) { - init_ok = false; - ErrorAlert(STR_NO_MEM_ERR); - return; - } - - // Add resolution and set VideoMonitor - monitor.set_mac_frame_base((uint32)the_bitmap->Planes[0]); - - // Set FgPen and BgPen - black_pen = ObtainBestPenA(the_win->WScreen->ViewPort.ColorMap, 0, 0, 0, NULL); - white_pen = ObtainBestPenA(the_win->WScreen->ViewPort.ColorMap, 0xffffffff, 0xffffffff, 0xffffffff, NULL); - SetAPen(the_win->RPort, black_pen); - SetBPen(the_win->RPort, white_pen); - SetDrMd(the_win->RPort, JAM2); - - init_ok = true; -} - - -driver_window::~driver_window() -{ - // Window mode, free bitmap - if (the_bitmap) { - WaitBlit(); - FreeBitMap(the_bitmap); - } - - // Free pens and close window - if (the_win) { - ReleasePen(the_win->WScreen->ViewPort.ColorMap, black_pen); - ReleasePen(the_win->WScreen->ViewPort.ColorMap, white_pen); - - CloseWindow(the_win); - the_win = NULL; - } -} - - -// Open PIP (requires Picasso96) -driver_pip::driver_pip(Amiga_monitor_desc &m, int width, int height) - : driver_base(m) -{ - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - D(bug("driver_pip(%d,%d)\n", width, height)); - - // Open window - ULONG error = 0; - the_win = p96PIP_OpenTags( - P96PIP_SourceFormat, RGBFB_R5G5B5, - P96PIP_SourceWidth, width, - P96PIP_SourceHeight, height, - P96PIP_ErrorCode, (ULONG)&error, - P96PIP_AllowCropping, true, - WA_Left, 0, WA_Top, 0, - WA_InnerWidth, width, WA_InnerHeight, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_DragBar, true, - WA_DepthGadget, true, - WA_SizeGadget, false, - WA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - WA_PubScreenName, (ULONG)"Workbench", - TAG_END - ); - if (the_win == NULL || error) { - init_ok = false; - ErrorAlert(STR_OPEN_WINDOW_ERR); - return; - } - - // Find bitmap - p96PIP_GetTags(the_win, P96PIP_SourceBitMap, (ULONG)&the_bitmap, TAG_END); - - // Add resolution and set VideoMonitor - monitor.set_mac_frame_base(p96GetBitMapAttr(the_bitmap, P96BMA_MEMORY)); - - init_ok = true; -} - -driver_pip::~driver_pip() -{ - // Close PIP - if (the_win) - p96PIP_Close(the_win); -} - - -// Open Picasso96 screen -driver_screen_p96::driver_screen_p96(Amiga_monitor_desc &m, ULONG mode_id) - : driver_base(m) -{ - // Set relative mouse mode - ADBSetRelMouseMode(true); - - // Check if the mode is one we can handle - if (!check_modeid_p96(mode_id)) - { - init_ok = false; - ErrorAlert(STR_WRONG_SCREEN_FORMAT_ERR); - return; - } - - // Yes, get width and height - uint32 depth = p96GetModeIDAttr(mode_id, P96IDA_DEPTH); - uint32 width = p96GetModeIDAttr(mode_id, P96IDA_WIDTH); - uint32 height = p96GetModeIDAttr(mode_id, P96IDA_HEIGHT); - - // Open screen - the_screen = p96OpenScreenTags( - P96SA_DisplayID, mode_id, - P96SA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - P96SA_Quiet, true, - P96SA_NoMemory, true, - P96SA_NoSprite, true, - P96SA_Exclusive, true, - TAG_END - ); - if (the_screen == NULL) { - ErrorAlert(STR_OPEN_SCREEN_ERR); - init_ok = false; - return; - } - - // Open window - the_win = OpenWindowTags(NULL, - WA_Left, 0, WA_Top, 0, - WA_Width, width, WA_Height, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Borderless, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_CustomScreen, (ULONG)the_screen, - TAG_END - ); - if (the_win == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - init_ok = false; - return; - } - - ScreenToFront(the_screen); - - // Add resolution and set VideoMonitor - monitor.set_mac_frame_base(p96GetBitMapAttr(the_screen->RastPort.BitMap, P96BMA_MEMORY)); - - init_ok = true; -} - - -driver_screen_p96::~driver_screen_p96() -{ - // Close window - if (the_win) - { - CloseWindow(the_win); - the_win = NULL; - } - - // Close screen - if (the_screen) { - p96CloseScreen(the_screen); - the_screen = NULL; - } -} - - -void driver_screen_p96::set_palette(uint8 *pal, int num) -{ - // Convert palette to 32 bits - ULONG table[2 + 256 * 3]; - table[0] = num << 16; - table[num * 3 + 1] = 0; - for (int i=0; iViewPort, table); -} - - -// Open CyberGraphX screen -driver_screen_cgfx::driver_screen_cgfx(Amiga_monitor_desc &m, ULONG mode_id) - : driver_base(m) -{ - D(bug("driver_screen_cgfx/%ld: mode_id=%08lx\n", __LINE__, mode_id)); - - // Set absolute mouse mode - ADBSetRelMouseMode(true); - - // Check if the mode is one we can handle - if (!check_modeid_cgfx(mode_id)) - { - ErrorAlert(STR_WRONG_SCREEN_FORMAT_ERR); - init_ok = false; - return; - } - - // Yes, get width and height - uint32 depth = GetCyberIDAttr(CYBRIDATTR_DEPTH, mode_id); - uint32 width = GetCyberIDAttr(CYBRIDATTR_WIDTH, mode_id); - uint32 height = GetCyberIDAttr(CYBRIDATTR_HEIGHT, mode_id); - - // Open screen - the_screen = OpenScreenTags(NULL, - SA_DisplayID, mode_id, - SA_Title, (ULONG)GetString(STR_WINDOW_TITLE), - SA_Quiet, true, - SA_Exclusive, true, - TAG_END - ); - if (the_screen == NULL) { - ErrorAlert(STR_OPEN_SCREEN_ERR); - init_ok = false; - return; - } - - // Open window - the_win = OpenWindowTags(NULL, - WA_Left, 0, WA_Top, 0, - WA_Width, width, WA_Height, height, - WA_SimpleRefresh, true, - WA_NoCareRefresh, true, - WA_Borderless, true, - WA_Activate, true, - WA_RMBTrap, true, - WA_ReportMouse, true, - WA_CustomScreen, (ULONG)the_screen, - TAG_END - ); - if (the_win == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - init_ok = false; - return; - } - - ScreenToFront(the_screen); - static UWORD ptr[] = { 0, 0, 0, 0 }; - SetPointer(the_win, ptr, 0, 0, 0, 0); // Hide mouse pointer - - // Set VideoMonitor - ULONG frame_base; - APTR handle = LockBitMapTags(the_screen->RastPort.BitMap, - LBMI_BASEADDRESS, (ULONG)&frame_base, - TAG_END - ); - UnLockBitMap(handle); - - D(bug("driver_screen_cgfx/%ld: frame_base=%08lx\n", __LINE__, frame_base)); - - monitor.set_mac_frame_base(frame_base); - - init_ok = true; -} - - -driver_screen_cgfx::~driver_screen_cgfx() -{ - D(bug("~driver_screen_cgfx/%ld: \n", __LINE__)); - - // Close window - if (the_win) - { - CloseWindow(the_win); - the_win = NULL; - } - - // Close screen - if (the_screen) { - CloseScreen(the_screen); - the_screen = NULL; - } -} - - -void driver_screen_cgfx::set_palette(uint8 *pal, int num) -{ - // Convert palette to 32 bits - ULONG table[2 + 256 * 3]; - table[0] = num << 16; - table[num * 3 + 1] = 0; - for (int i=0; iViewPort, table); -} diff --git a/BasiliskII/src/AmigaOS/xpram_amiga.cpp b/BasiliskII/src/AmigaOS/xpram_amiga.cpp deleted file mode 100644 index 69195d119..000000000 --- a/BasiliskII/src/AmigaOS/xpram_amiga.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * xpram_amiga.cpp - XPRAM handling, AmigaOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#define __USE_SYSBASE -#include -#include - -#include "sysdeps.h" -#include "xpram.h" - - -// XPRAM file name -#if POWERPC_ROM -static char XPRAM_FILE_NAME[] = "ENV:SheepShaver_NVRAM"; -static char XPRAM_FILE_NAME_ARC[] = "ENVARC:SheepShaver_NVRAM"; -#else -static char XPRAM_FILE_NAME[] = "ENV:BasiliskII_XPRAM"; -static char XPRAM_FILE_NAME_ARC[] = "ENVARC:BasiliskII_XPRAM"; -#endif - - -/* - * Load XPRAM from settings file - */ - -void LoadXPRAM(void) -{ - BPTR fh; - if ((fh = Open(XPRAM_FILE_NAME, MODE_OLDFILE)) != NULL) { - Read(fh, XPRAM, XPRAM_SIZE); - Close(fh); - } -} - - -/* - * Save XPRAM to settings file - */ - -void SaveXPRAM(void) -{ - BPTR fh; - if ((fh = Open(XPRAM_FILE_NAME, MODE_NEWFILE)) != NULL) { - Write(fh, XPRAM, XPRAM_SIZE); - Close(fh); - } - if ((fh = Open(XPRAM_FILE_NAME_ARC, MODE_NEWFILE)) != NULL) { - Write(fh, XPRAM, XPRAM_SIZE); - Close(fh); - } -} - - -/* - * Delete PRAM file - */ - -void ZapPRAM(void) -{ - DeleteFile(XPRAM_FILE_NAME); - DeleteFile(XPRAM_FILE_NAME_ARC); -} diff --git a/BasiliskII/src/BeOS/Makefile b/BasiliskII/src/BeOS/Makefile deleted file mode 100644 index e7feb6363..000000000 --- a/BasiliskII/src/BeOS/Makefile +++ /dev/null @@ -1,151 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= BasiliskII - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= APP - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -MACHINE=$(shell uname -m) -ifeq ($(MACHINE), BePC) - CPUSRCS = ../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp \ - ../uae_cpu/readcpu.cpp ../uae_cpu/fpu/fpu_x86.cpp cpustbl.cpp cpudefs.cpp cpufast.s -else -# CPUSRCS = ../powerrom_cpu/powerrom_cpu.cpp - CPUSRCS = ../uae_cpu/basilisk_glue.cpp ../uae_cpu/newcpu.cpp \ - ../uae_cpu/readcpu.cpp ../uae_cpu/fpu/fpu_uae.cpp cpustbl.cpp cpudefs.cpp cpuemu.cpp -endif -SRCS = ../main.cpp main_beos.cpp ../prefs.cpp ../prefs_items.cpp prefs_beos.cpp \ - prefs_editor_beos.cpp sys_beos.cpp ../rom_patches.cpp ../slot_rom.cpp \ - ../rsrc_patches.cpp ../emul_op.cpp ../macos_util.cpp ../xpram.cpp \ - xpram_beos.cpp ../timer.cpp timer_beos.cpp clip_beos.cpp ../adb.cpp \ - ../serial.cpp serial_beos.cpp ../ether.cpp ether_beos.cpp ../sony.cpp \ - ../disk.cpp ../cdrom.cpp ../scsi.cpp scsi_beos.cpp ../video.cpp \ - video_beos.cpp ../audio.cpp audio_beos.cpp ../extfs.cpp extfs_beos.cpp \ - ../user_strings.cpp user_strings_beos.cpp about_window.cpp \ - $(CPUSRCS) - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS=be game media device textencoding tracker net - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= FPU_X86 SIZEOF_FLOAT=4 SIZEOF_DOUBLE=8 SIZEOF_LONG_DOUBLE=10 - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from -# a source-level debugger -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = -fomit-frame-pointer -fno-PIC - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/system/develop/etc/makefile-engine - - -# special handling of UAE CPU engine -$(OBJ_DIR)/%.o : %.s - $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ -$(OBJ_DIR)/cpuopti: $(OBJ_DIR)/cpuopti.o - $(CC) $(LDFLAGS) -o $(OBJ_DIR)/cpuopti $(OBJ_DIR)/cpuopti.o -$(OBJ_DIR)/build68k: $(OBJ_DIR)/build68k.o - $(CC) $(LDFLAGS) -o $(OBJ_DIR)/build68k $(OBJ_DIR)/build68k.o -$(OBJ_DIR)/gencpu: $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o - $(CC) $(LDFLAGS) -o $(OBJ_DIR)/gencpu $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o -cpudefs.cpp: $(OBJ_DIR)/build68k ../uae_cpu/table68k - $(OBJ_DIR)/build68k <../uae_cpu/table68k >cpudefs.cpp -cpuemu.cpp: $(OBJ_DIR)/gencpu - $(OBJ_DIR)/gencpu -cpustbl.cpp: cpuemu.cpp -cputbl.h: cpuemu.cpp -cpufast.s: cpuemu.cpp $(OBJ_DIR)/cpuopti - $(CXX) $(INCLUDES) -S $(CFLAGS) $< -o cputmp.s - $(OBJ_DIR)/cpuopti $@ || mv cputmp.s $@ - rm -f cputmp.s - -streifenfrei: - -rm -f $(OBJ_DIR)/gencpu $(OBJ_DIR)/build68k $(OBJ_DIR)/cpuopti - -rm -f cpuemu.cpp cpudefs.cpp cputmp.s cpufast*.s cpustbl.cpp cputbl.h diff --git a/BasiliskII/src/BeOS/SheepDriver/Makefile b/BasiliskII/src/BeOS/SheepDriver/Makefile deleted file mode 100644 index 52b2b70ec..000000000 --- a/BasiliskII/src/BeOS/SheepDriver/Makefile +++ /dev/null @@ -1,117 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= sheep - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= DRIVER - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= sheep_driver.c - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - -install: $(TARGET) - cp $(TARGET) /boot/home/config/add-ons/kernel/drivers/bin - ln -sf /boot/home/config/add-ons/kernel/drivers/bin/$(NAME) /boot/home/config/add-ons/kernel/drivers/dev/$(NAME) - -uninstall: - rm /boot/home/config/add-ons/kernel/drivers/bin/$(NAME) - rm /boot/home/config/add-ons/kernel/drivers/dev/$(NAME) diff --git a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.c b/BasiliskII/src/BeOS/SheepDriver/sheep_driver.c deleted file mode 100644 index 859d82e22..000000000 --- a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * sheep_driver.c - Low memory and ROM access driver for SheepShaver and - * Basilisk II on PowerPC systems - * - * SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2002 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __i386__ -#error The sheep driver only runs on PowerPC machines. -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "sheep_driver.h" - -#define DEBUG 0 - -#if DEBUG==1 -#define bug pprintf -#elif DEBUG==2 -#define bug dprintf -#endif - -#if DEBUG -#define D(x) (x) -#else -#define D(x) ; -#endif - -#define PORT_NAME "sheep_driver installed" - - -/* - * For debugging - */ - -static int pprintf(const char* format, ...) -{ - port_id PortNum; - int len, ret; - char Buffer[1024]; - va_list ap; - - if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND) - return(PortNum); - for (len=0; len<1024; len++) - Buffer[len]='\0'; - va_start(ap, format); - vsprintf(Buffer, format, ap); - ret = write_port(PortNum, 0, Buffer, strlen(Buffer)); - return ret; -} - - -/* - * Page table functions - */ - -static uint32 *pte_address = 0; -static uint32 vsid; -static uint32 table_size; - -static status_t map_page(uint32 ea, uint32 ra, uint32 **free_pte, uint32 bits) -{ - int i; - int pte_class; - uint32 hash1, hash2, api, *pteg1, *pteg2; - - D(bug("Trying to map EA %p -> RA %p\n", ea, ra)); - - // Find PTEG addresses for given EA - hash1 = (vsid & 0x7ffff) ^ ((ea >> 12) & 0xffff); - hash2 = ~hash1 & 0x7ffff; - api = (ea >> 22) & 0x3f; - pteg1 = (uint32 *)((uint32)pte_address + ((hash1 << 6) & (table_size - 1))); - pteg2 = (uint32 *)((uint32)pte_address + ((hash2 << 6) & (table_size - 1))); - D(bug("PTEG1 at %p, PTEG2 at %p\n", pteg1, pteg2)); - - // Search all 8 PTEs of each PTEG - *free_pte = NULL; - pte_class = 0; - for (i=0; i<8; i++) { - D(bug(" found %08lx %08lx\n", pteg1[i*2], pteg1[i*2+1])); - if (pteg1[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) { - *free_pte = pteg1 + i*2; - D(bug(" existing PTE found (PTEG1)\n")); - break; - } else if (!pteg1[i*2]) { - *free_pte = pteg1 + i*2; - D(bug(" free PTE found (PTEG1)\n")); - break; - } - } - if (*free_pte == NULL) { - pte_class = 1; - for (i=0; i<8; i++) { - D(bug(" found %08lx %08lx\n", pteg2[i*2], pteg2[i*2+1])); - if (pteg2[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) { - *free_pte = pteg2 + i*2; - D(bug(" existing PTE found (PTEG2)\n")); - break; - } else if (!pteg2[i*2]) { - *free_pte = pteg2 + i*2; - D(bug(" free PTE found (PTEG2)\n")); - break; - } - } - } - - // Remap page - if (*free_pte == NULL) { - D(bug(" No free PTE found :-(\m")); - return B_DEVICE_FULL; - } else { - (*free_pte)[0] = 0x80000000 | (vsid << 7) | (pte_class << 6) | api; - (*free_pte)[1] = ra | bits; - D(bug(" written %08lx %08lx to PTE\n", (*free_pte)[0], (*free_pte)[1])); - return B_NO_ERROR; - } -} - -static status_t remap_page(uint32 *free_pte, uint32 ra, uint32 bits) -{ - D(bug("Remapping PTE %p -> RA %p\n", free_pte, ra)); - - // Remap page - if (free_pte == NULL) { - D(bug(" Invalid PTE :-(\n")); - return B_BAD_ADDRESS; - } else { - free_pte[1] = ra | bits; - D(bug(" written %08lx %08lx to PTE\n", free_pte[0], free_pte[1])); - return B_NO_ERROR; - } -} - - -/* - * Foward declarations for hook functions - */ - -static status_t sheep_open(const char *name, uint32 flags, void **cookie); -static status_t sheep_close(void *cookie); -static status_t sheep_free(void *cookie); -static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len); -static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len); -static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len); - - -/* - * Version of our driver - */ - -int32 api_version = B_CUR_DRIVER_API_VERSION; - - -/* - * Device_hooks structure - has function pointers to the - * various entry points for device operations - */ - -static device_hooks my_device_hooks = { - &sheep_open, - &sheep_close, - &sheep_free, - &sheep_control, - &sheep_read, - &sheep_write, - NULL, - NULL, - NULL, - NULL -}; - - -/* - * List of device names to be returned by publish_devices() - */ - -static char *device_name_list[] = { - "sheep", - 0 -}; - - -/* - * Init - do nothing - */ - -status_t init_hardware(void) -{ -#if DEBUG==2 - set_dprintf_enabled(true); -#endif - D(bug("init_hardware()\n")); - return B_NO_ERROR; -} - -status_t init_driver(void) -{ - D(bug("init_driver()\n")); - return B_NO_ERROR; -} - -void uninit_driver(void) -{ - D(bug("uninit_driver()\n")); -} - - -/* - * publish_devices - return list of device names implemented by this driver - */ - -const char **publish_devices(void) -{ - return device_name_list; -} - - -/* - * find_device - return device hooks for a specific device name - */ - -device_hooks *find_device(const char *name) -{ - if (!strcmp(name, device_name_list[0])) - return &my_device_hooks; - - return NULL; -} - - -/* - * sheep_open - hook function for the open call. - */ - -static status_t sheep_open(const char *name, uint32 flags, void **cookie) -{ - return B_NO_ERROR; -} - - -/* - * sheep_close - hook function for the close call. - */ - -static status_t sheep_close(void *cookie) -{ - return B_NO_ERROR; -} - - -/* - * sheep_free - hook function to free the cookie returned - * by the open hook. Since the open hook did not return - * a cookie, this is a no-op. - */ - -static status_t sheep_free(void *cookie) -{ - return B_NO_ERROR; -} - - -/* - * sheep_control - hook function for the ioctl call - */ - -static asm void inval_tlb(uint32 ea) -{ - isync - tlbie r3 - sync - blr -} - -static asm void tlbsync(void) -{ - machine 604 - tlbsync - sync - blr -} - -static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len) -{ - static void *block; - static void *block_aligned; - physical_entry pe[2]; - system_info sysinfo; - area_id id; - area_info info; - cpu_status cpu_st; - status_t res; - uint32 ra0, ra1; - uint32 *free_pte_0, *free_pte_1; - int i; - - D(bug("control(%d) data %p, len %08x\n", op, data, len)); - - switch (op) { - case SHEEP_UP: - - // Already messed up? Then do nothing now - if (find_port(PORT_NAME) != B_NAME_NOT_FOUND) - return B_NO_ERROR; - - // Get system info - get_system_info(&sysinfo); - - // Prepare replacement memory - block = malloc(B_PAGE_SIZE * 3); - D(bug("3 pages malloc()ed at %p\n", block)); - block_aligned = (void *)(((uint32)block + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE-1)); - D(bug("Address aligned to %p\n", block_aligned)); - res = lock_memory(block_aligned, B_PAGE_SIZE * 2, 0); - if (res < 0) - return res; - - // Get memory mapping - D(bug("Memory locked\n")); - res = get_memory_map(block_aligned, B_PAGE_SIZE * 2, pe, 2); - D(bug("get_memory_map returned %d\n", res)); - if (res != B_NO_ERROR) - return res; - - // Find PTE table area - id = find_area("pte_table"); - get_area_info(id, &info); - pte_address = (uint32 *)info.address; - D(bug("PTE table seems to be at %p\n", pte_address)); - table_size = info.size; - D(bug("PTE table size: %dKB\n", table_size / 1024)); - - // Disable interrupts - cpu_st = disable_interrupts(); - - // Find vsid and real addresses of replacement memory - for (i=0; i> 31),((pte_address[i*2]&0x7fffff80) >> 7), - ((pte_address[i*2]&0x00000040) >> 6),(pte_address[i*2] & 0x3f), - ((pte_address[i*2+1]&0xfffff000) >> 12),((pte_address[i*2+1]&0x00000100) >> 8), - ((pte_address[i*2+1]&0x00000080) >> 7),((pte_address[i*2+1]&0x00000078) >> 3), - (pte_address[i*2+1]&0x00000003))); - vsid = (pte_address[i*2]&0x7fffff80) >> 7; - ra0 = (uint32)pe[0].address & 0xfffff000; - } - if ((uint32)pe[0].size == B_PAGE_SIZE) { - if (((uint32)pe[1].address & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) { - D(bug("Found page 1f PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n", - i << 2, - ((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7), - ((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f), - ((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8), - ((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3), - (pte_address[i*2+1]&0x00000003))); - ra1 = (uint32)pe[1].address & 0xfffff000; - } - } else { - if ((((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) { - D(bug("Found page 1d PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n", - i << 2, - ((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7), - ((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f), - ((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8), - ((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3), - (pte_address[i*2+1]&0x00000003))); - ra1 = ((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000; - } - } - } - - // Map low memory for emulator - free_pte_0 = NULL; - free_pte_1 = NULL; - __sync(); - __isync(); - inval_tlb(0); - inval_tlb(B_PAGE_SIZE); - if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e) - tlbsync(); - res = map_page(0, ra0, &free_pte_0, 0x12); - if (res == B_NO_ERROR) - res = map_page(B_PAGE_SIZE, ra1, &free_pte_1, 0x12); - inval_tlb(0); - inval_tlb(B_PAGE_SIZE); - if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e) - tlbsync(); - __sync(); - __isync(); - - // Restore interrupts - restore_interrupts(cpu_st); - - // Create port so we know that messing was successful - set_port_owner(create_port(1, PORT_NAME), B_SYSTEM_TEAM); - return B_NO_ERROR; - - case SHEEP_DOWN: - return B_NO_ERROR; - - default: - return B_BAD_VALUE; - } -} - - -/* - * sheep_read - hook function for the read call - */ - -static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len) -{ - void *rom_adr; - area_id area; - system_info info; - - D(bug("read() pos %Lx, data %p, len %08x\n", pos, data, *len)); - - get_system_info(&info); - if (info.platform_type == B_BEBOX_PLATFORM) { - *len = 0; - return B_ERROR; - } - if (*len != 0x400000 && pos != 0) { - *len = 0; - return B_BAD_VALUE; - } - area = map_physical_memory("mac_rom", (void *)0xff000000, 0x00400000, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &rom_adr); - D(bug("Mapped ROM to %p, area id %d\n", rom_adr, area)); - if (area < 0) { - *len = 0; - return area; - } - D(bug("Copying ROM\n")); - memcpy(data, rom_adr, *len); - D(bug("Deleting area\n")); - delete_area(area); - return B_NO_ERROR; -} - - -/* - * sheep_write - hook function for the write call - */ - -static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len) -{ - D(bug("write() pos %Lx, data %p, len %08x\n", pos, data, *len)); - return B_READ_ONLY_DEVICE; -} diff --git a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.h b/BasiliskII/src/BeOS/SheepDriver/sheep_driver.h deleted file mode 100644 index 8486a0213..000000000 --- a/BasiliskII/src/BeOS/SheepDriver/sheep_driver.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * sheep_driver.h - Low memory and ROM access driver for SheepShaver and - * Basilisk II on PowerPC systems - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHEEP_DRIVER_H -#define SHEEP_DRIVER_H - -#include - -enum { - SHEEP_UP = B_DEVICE_OP_CODES_END + 1, - SHEEP_DOWN -}; - -#endif diff --git a/BasiliskII/src/BeOS/SheepNet/Makefile b/BasiliskII/src/BeOS/SheepNet/Makefile deleted file mode 100644 index 36b882fc1..000000000 --- a/BasiliskII/src/BeOS/SheepNet/Makefile +++ /dev/null @@ -1,115 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= sheep_net - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= SHARED - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= sheep_net.cpp - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= netdev - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - -install: $(TARGET) - cp $(TARGET) /boot/beos/system/add-ons/net_server/$(NAME) - -uninstall: - rm /boot/beos/system/add-ons/net_server/$(NAME) diff --git a/BasiliskII/src/BeOS/SheepNet/sheep_net.cpp b/BasiliskII/src/BeOS/SheepNet/sheep_net.cpp deleted file mode 100644 index c026293c9..000000000 --- a/BasiliskII/src/BeOS/SheepNet/sheep_net.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* - * sheep_net.cpp - Net server add-on for SheepShaver and Basilisk II - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sheep_net.h" - -#define DEBUG 0 - -#if DEBUG==1 -#define bug pprintf -#elif DEBUG==2 -#define bug kprintf -#endif - -#if DEBUG -#define D(x) (x) -#else -#define D(x) ; -#endif - -static int pprintf(const char* format, ...) -{ - port_id PortNum; - int len,Ret; - char Buffer[1024]; - va_list ap; - - if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND) - return(PortNum); - for (len=0; len<1024; len++) - Buffer[len]='\0'; - va_start(ap, format); - vsprintf(Buffer, format, ap); - Ret = write_port(PortNum, 0, Buffer, strlen(Buffer)); - return(Ret); -} - - -// Constants -#define NETDUMP_PRIO 1 // Default is 0 - -const uint32 buffer_size = (sizeof(net_buffer) / B_PAGE_SIZE + 1) * B_PAGE_SIZE; - - -// SheepNet add-on object -class SheepNetAddOn : public BNetProtocol, BPacketHandler { -public: - void AddDevice(BNetDevice *dev, const char *name); - bool PacketReceived(BNetPacket *buf, BNetDevice *dev); -}; - - -// Global variables -static bool shutdown_now = false; -static bool active = false; - -static thread_id write_thread; // Packet writer -static sem_id write_sem; // Semaphore to trigger packet writing -static BNetDevice *EtherCard = NULL; // The Ethernet card we are attached to -static area_id buffer_area; // Packet buffer area -static net_buffer *net_buffer_ptr; // Pointer to packet buffer - -static uint32 rd_pos; // Current read position in packet buffer -static uint32 wr_pos; // Current write position in packet buffer - - -/* - * Clear packet buffer - */ - -static void clear(void) -{ - int i; - for (i=0;iread[i].cmd = 0; - net_buffer_ptr->read[i].length = 0; - net_buffer_ptr->read[i].card = 0; - net_buffer_ptr->read[i].reserved = 0; - } - for (i=0;iwrite[i].cmd = 0; - net_buffer_ptr->write[i].length = 0; - net_buffer_ptr->write[i].card = 0; - net_buffer_ptr->write[i].reserved = 0; - } - rd_pos = wr_pos = 0; -} - - -/* - * Packet writer thread - */ - -static status_t write_packet_func(void *arg) -{ - while (!shutdown_now) { - - // Read and execute command - net_packet *p = &net_buffer_ptr->write[wr_pos]; - while (p->cmd & IN_USE) { - D(bug("wp: %d\n", wr_pos)); - switch (p->cmd >> 8) { - - case ACTIVATE_SHEEP_NET: - D(bug("activate sheep-net\n")); - active = false; - clear(); - active = true; - goto next; - - case DEACTIVATE_SHEEP_NET: - D(bug("deactivate sheep-net\n")); - active = false; - clear(); - goto next; - - case SHUTDOWN_SHEEP_NET: - D(bug("shutdown sheep-net\n")); - active = false; - clear(); - shutdown_now = true; - goto next; - - case ADD_MULTICAST: { - const char *data = (const char *)p->data; - D(bug("add multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5])); - if (active) { - status_t result; - if ((result = EtherCard->AddMulticastAddress(data)) != B_OK) { - // !! handle error !! error while creating multicast address - D(bug("error while creating multicast address %d\n", result)); - } - } - break; - } - - case REMOVE_MULTICAST: { - const char *data = (const char *)p->data; - D(bug("remove multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5])); - if (active) { - status_t result; - if ((result = EtherCard->RemoveMulticastAddress(data)) != B_OK) { - // !! handle error !! error while removing multicast address - D(bug("error while removing multicast address %d\n", result)); - } - } - break; - } - - case SHEEP_PACKET: { - uint32 length = p->length; - // D(bug("sheep packet %d\n", length)); - if (active) { - BStandardPacket *packet = new BStandardPacket(length); - packet->Write(0, (const char *)p->data, length); - EtherCard->SendPacket(packet); - } - break; - } - - default: - D(bug("error: unknown port packet type\n")); - break; - } - p->cmd = 0; // Free packet - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - p = &net_buffer_ptr->write[wr_pos]; - } - - // Wait for next packet -next: acquire_sem_etc(write_sem, 1, B_TIMEOUT, 25000); - } - return 0; -} - - -/* - * Init the net add-on - */ - -static void init_addon() -{ - int i; - D(bug("init sheep-net\n")); - - // Create packet buffer - if ((buffer_area = create_area("packet buffer", (void **)&net_buffer_ptr, B_ANY_ADDRESS, buffer_size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA)) < B_NO_ERROR) { - D(bug("FATAL ERROR: can't create shared area\n")); - return; - } - - // Init packet buffer - clear(); - EtherCard->Address((char *)net_buffer_ptr->ether_addr); - net_buffer_ptr->read_sem = -1; - net_buffer_ptr->read_ofs = (uint32)(net_buffer_ptr->read) - (uint32)net_buffer_ptr; - net_buffer_ptr->read_packet_size = sizeof(net_packet); - net_buffer_ptr->read_packet_count = READ_PACKET_COUNT; - if ((write_sem = create_sem(0, "ether write")) < B_NO_ERROR) { - D(bug("FATAL ERROR: can't create semaphore\n")); - return; - } - net_buffer_ptr->write_sem = write_sem; - net_buffer_ptr->write_ofs = (uint32)(net_buffer_ptr->write) - (uint32)net_buffer_ptr; - net_buffer_ptr->write_packet_size = sizeof(net_packet); - net_buffer_ptr->write_packet_count = WRITE_PACKET_COUNT; - - // Start packet writer thread - write_thread = spawn_thread(write_packet_func, "sheep_net ether write", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(write_thread); -} - - -/* - * Add-on attached to Ethernet card - */ - -void SheepNetAddOn::AddDevice(BNetDevice *dev, const char *name) -{ - if (dev->Type() != B_ETHER_NET_DEVICE) - return; - if (EtherCard != NULL) { - // !! handle error !! support for multiple ethernet cards ... - D(bug("error: SheepShaver doesn't support multiple Ethernetcards !\n")); - return; - } - EtherCard = dev; - init_addon(); - register_packet_handler(this, dev, NETDUMP_PRIO); -} - - -/* - * Ethernet packet received - */ - -bool SheepNetAddOn::PacketReceived(BNetPacket *pkt, BNetDevice *dev) -{ - if (shutdown_now) { - unregister_packet_handler(this, dev); - return false; - } -// D(bug("read_packet_func %d\n", pkt->Size())); - if (active) { - D(bug("rp: %d\n", rd_pos)); - net_packet *p = &net_buffer_ptr->read[rd_pos]; - if (p->cmd & IN_USE) { - D(bug("error: full read buffer ... lost packet\n")); - } else { - memcpy(p->data, pkt->Data(), pkt->Size()); - p->length = pkt->Size(); - p->cmd = IN_USE | (SHEEP_PACKET << 8); - rd_pos = (rd_pos + 1) % READ_PACKET_COUNT; - release_sem(net_buffer_ptr->read_sem); - } - } - //D(bug("%02x %02x %02x %02x %02x %02x", (uchar) (pkt->Data())[0],(uchar) (pkt->Data())[1],(uchar) (pkt->Data())[2],(uchar) (pkt->Data())[3],(uchar) (pkt->Data())[4],(uchar) (pkt->Data())[5])); - return false; -} - -#pragma export on -extern "C" BNetProtocol *open_protocol(const char *device) -{ - SheepNetAddOn *dev = new SheepNetAddOn; - return dev; -} -#pragma export off diff --git a/BasiliskII/src/BeOS/SheepNet/sheep_net.h b/BasiliskII/src/BeOS/SheepNet/sheep_net.h deleted file mode 100644 index d4585b4dd..000000000 --- a/BasiliskII/src/BeOS/SheepNet/sheep_net.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * sheep_net.h - Net server add-on for SheepShaver and Basilisk II - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SHEEP_NET_H -#define SHEEP_NET_H - -// Net buffer dimensions -#define READ_PACKET_COUNT 10 -#define WRITE_PACKET_COUNT 10 - -// Net packet -struct net_packet { - uint32 cmd; // Command - uint32 length; // Data length - uint32 card; // Network card ID - uint32 reserved; - uint8 data[1584]; -}; - -// Net buffer (shared area) -struct net_buffer { - uint8 ether_addr[6]; // Ethernet address - uint8 filler1[2]; - sem_id read_sem; // Semaphore for read packets - uint32 read_ofs; - uint32 read_packet_size; - uint32 read_packet_count; - sem_id write_sem; // Semaphore for write packets - uint32 write_ofs; - uint32 write_packet_size; - uint32 write_packet_count; - uint8 filler[24]; - net_packet read[READ_PACKET_COUNT]; - net_packet write[WRITE_PACKET_COUNT]; -}; - -// Packet commands -#define SHEEP_PACKET 0 -#define ADD_MULTICAST 1 -#define REMOVE_MULTICAST 2 -#define ACTIVATE_SHEEP_NET 8 -#define DEACTIVATE_SHEEP_NET 9 -#define SHUTDOWN_SHEEP_NET 10 - -#define IN_USE 1 - -#endif diff --git a/BasiliskII/src/BeOS/about_window.cpp b/BasiliskII/src/BeOS/about_window.cpp deleted file mode 100644 index 94f9944e0..000000000 --- a/BasiliskII/src/BeOS/about_window.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * about_window.cpp - "About" window - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "sysdeps.h" -#include "version.h" -#include "user_strings.h" - -/* - * Display "About" window - */ - -void ShowAboutWindow(void) -{ - char str[512]; - sprintf(str, - "Basilisk II\nVersion %d.%d\n\n" - "Copyright " B_UTF8_COPYRIGHT " 1997-2008 Christian Bauer et al.\n" - "E-mail: Christian.Bauer@uni-mainz.de\n" - "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n" - "Basilisk II comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR - ); - BAlert *about = new BAlert("", str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_FROM_LABEL); - BTextView *theText = about->TextView(); - if (theText) { - theText->SetStylable(true); - theText->Select(0, 11); - BFont ourFont; - theText->SetFontAndColor(be_bold_font); - theText->GetFontAndColor(2, &ourFont, NULL); - ourFont.SetSize(24); - theText->SetFontAndColor(&ourFont); - } - about->Go(); -} diff --git a/BasiliskII/src/BeOS/about_window.h b/BasiliskII/src/BeOS/about_window.h deleted file mode 100644 index 1960c9766..000000000 --- a/BasiliskII/src/BeOS/about_window.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * about_window.h - "About" window - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ABOUT_WINDOW_H -#define ABOUT_WINDOW_H - -// Display "About" window -extern void ShowAboutWindow(void); - -#endif diff --git a/BasiliskII/src/BeOS/audio_beos.cpp b/BasiliskII/src/BeOS/audio_beos.cpp deleted file mode 100644 index 026545870..000000000 --- a/BasiliskII/src/BeOS/audio_beos.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * audio_beos.cpp - Audio support, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * Portions written by Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static int audio_irq_done_sem = -1; // Signal from interrupt to streaming thread: data block read -static BSoundPlayer *the_player; - -// Prototypes -static void playbuffer_func(void *arg, void *buf, size_t size, const media_raw_audio_format &format); - - -/* - * Audio manager thread (for calling media kit functions; - * this is not safe under R4 when running on the MacOS stack in kernel space) - */ - -// Message constants -const uint32 MSG_QUIT_AUDIO_MANAGER = 'quit'; -const uint32 MSG_ENTER_STREAM = 'entr'; -const uint32 MSG_EXIT_STREAM = 'exit'; -const uint32 MSG_GET_VOLUME = 'getv'; -const uint32 MSG_SET_VOLUME = 'setv'; - -static thread_id am_thread = -1; -static sem_id am_done_sem = -1; - -static volatile float am_volume; - -static status_t audio_manager(void *arg) -{ - for (;;) { - - // Receive message - thread_id sender; - uint32 code = receive_data(&sender, NULL, 0); - D(bug("Audio manager received %08lx\n", code)); - switch (code) { - case MSG_QUIT_AUDIO_MANAGER: - return 0; - - case MSG_ENTER_STREAM: - the_player->Start(); - break; - - case MSG_EXIT_STREAM: - the_player->Stop(); - break; - - case MSG_GET_VOLUME: - am_volume = the_player->Volume(); - break; - - case MSG_SET_VOLUME: - the_player->SetVolume(am_volume); - break; - } - - // Acknowledge - release_sem(am_done_sem); - } -} - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[0]; - AudioStatus.sample_size = audio_sample_sizes[0]; - AudioStatus.channels = audio_channel_counts[0]; -} - -void AudioInit(void) -{ - // Init audio status and feature flags - audio_sample_rates.push_back(44100 << 16); - audio_sample_sizes.push_back(16); - audio_channel_counts.push_back(2); - set_audio_status_format(); - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphores - audio_irq_done_sem = create_sem(0, "Audio IRQ Done"); - am_done_sem = create_sem(0, "Audio Manager Done"); - - // Start audio manager thread - am_thread = spawn_thread(audio_manager, "Audio Manager", B_NORMAL_PRIORITY, NULL); - resume_thread(am_thread); - - // Start stream - media_raw_audio_format format; - format.frame_rate = AudioStatus.sample_rate >> 16; - format.channel_count = AudioStatus.channels; - format.format = media_raw_audio_format::B_AUDIO_SHORT; - format.byte_order = B_MEDIA_BIG_ENDIAN; - audio_frames_per_block = 4096; - size_t block_size = (AudioStatus.sample_size >> 3) * AudioStatus.channels * audio_frames_per_block; - D(bug("AudioInit: block size %d\n", block_size)); - format.buffer_size = block_size; - the_player = new BSoundPlayer(&format, "MacOS Audio", playbuffer_func, NULL, NULL); - if (the_player->InitCheck() != B_NO_ERROR) { - printf("FATAL: Cannot initialize BSoundPlayer\n"); - delete the_player; - the_player = NULL; - return; - } else - the_player->SetHasData(true); - - // Everything OK - audio_open = true; -} - - -/* - * Deinitialization - */ - -void AudioExit(void) -{ - // Stop stream - if (the_player) { - the_player->Stop(); - delete the_player; - the_player = NULL; - } - - // Stop audio manager - if (am_thread > 0) { - status_t l; - send_data(am_thread, MSG_QUIT_AUDIO_MANAGER, NULL, 0); - wait_for_thread(am_thread, &l); - } - - // Delete semaphores - delete_sem(am_done_sem); - delete_sem(audio_irq_done_sem); -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - while (send_data(am_thread, MSG_ENTER_STREAM, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - while (send_data(am_thread, MSG_EXIT_STREAM, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; -} - - -/* - * Streaming function - */ - -static uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer - -static void playbuffer_func(void *arg, void *buf, size_t size, const media_raw_audio_format &format) -{ - // Check if new buffer is available - if (acquire_sem_etc(audio_irq_done_sem, 1, B_TIMEOUT, 0) == B_NO_ERROR) { - - // Get size of audio data - D(bug("stream: new buffer present\n")); - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - size_t work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: size %d, work_size %d\n", size, work_size)); - if (work_size > size) - work_size = size; - - if (format.format != media_raw_audio_format::B_AUDIO_SHORT) { - D(bug("Wrong audio format %04x\n", format.format)); - return; - } - - // Place data into Media Kit buffer - Mac2Host_memcpy(buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - if (work_size != size) - memset((uint8 *)buf + work_size, 0, size - work_size); - } - - } else - memset(buf, 0, size); - - // Trigger audio interrupt to get new buffer - if (AudioStatus.num_sources) { - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - } -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - release_sem(audio_irq_done_sem); - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. arrays - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - return true; -} - -bool audio_set_sample_size(int index) -{ - return true; -} - -bool audio_set_channels(int index) -{ - return true; -} - - -/* - * Get/set audio info - */ - -bool audio_get_main_mute(void) -{ - return false; -} - -uint32 audio_get_main_volume(void) -{ - if (audio_open) { - while (send_data(am_thread, MSG_GET_VOLUME, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; - return int(am_volume * 256.0) * 0x00010001; - } else - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return false; -} - -uint32 audio_get_speaker_volume(void) -{ - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ -} - -void audio_set_main_volume(uint32 vol) -{ - if (audio_open) { - am_volume = float((vol >> 16) + (vol & 0xffff)) / 512.0; - while (send_data(am_thread, MSG_SET_VOLUME, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(am_done_sem) == B_INTERRUPTED) ; - } -} - -void audio_set_speaker_mute(bool mute) -{ -} - -void audio_set_speaker_volume(uint32 vol) -{ -} diff --git a/BasiliskII/src/BeOS/clip_beos.cpp b/BasiliskII/src/BeOS/clip_beos.cpp deleted file mode 100644 index 10159ec6c..000000000 --- a/BasiliskII/src/BeOS/clip_beos.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * clip_beos.cpp - Clipboard handling, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include - -#include "clip.h" -#include "prefs.h" - -#define DEBUG 1 -#include "debug.h" - - -// Flag: Don't convert clipboard text -static bool no_clip_conversion; - - -/* - * Initialization - */ - -void ClipInit(void) -{ - no_clip_conversion = PrefsFindBool("noclipconversion"); -} - - -/* - * Deinitialization - */ - -void ClipExit(void) -{ -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - D(bug("GetScrap handle %p, type %08x, offset %d\n", handle, type, offset)); -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %08lx, length %ld\n", type, scrap, length)); - if (length <= 0) - return; - - switch (type) { - case 'TEXT': - D(bug(" clipping TEXT\n")); - if (be_clipboard->Lock()) { - be_clipboard->Clear(); - BMessage *clipper = be_clipboard->Data(); - - if (no_clip_conversion) { - - // Only convert CR->LF - char *buf = new char[length]; - for (int i=0; iAddData("text/plain", B_MIME_TYPE, buf, length); - be_clipboard->Commit(); - delete[] buf; - - } else { - - // Convert text from Mac charset to UTF-8 - int32 dest_length = length*3; - int32 state = 0; - char *buf = new char[dest_length]; - if (convert_to_utf8(B_MAC_ROMAN_CONVERSION, (char *)scrap, &length, buf, &dest_length, &state) == B_OK) { - for (int i=0; iAddData("text/plain", B_MIME_TYPE, buf, dest_length); - be_clipboard->Commit(); - } - delete[] buf; - } - be_clipboard->Unlock(); - } - break; - } -} diff --git a/BasiliskII/src/BeOS/ether_beos.cpp b/BasiliskII/src/BeOS/ether_beos.cpp deleted file mode 100644 index ebc85daa6..000000000 --- a/BasiliskII/src/BeOS/ether_beos.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - * ether_beos.cpp - Ethernet device driver, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * Portions written by Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __HAIKU__ -#include -#include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "macos_util.h" -#include "ether.h" -#include "ether_defs.h" - -#include "sheep_net.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// List of attached protocols -struct NetProtocol { - uint16 type; - uint32 handler; -}; - -static BList prot_list; - - -// Global variables -static thread_id read_thread; // Packet reception thread -static bool ether_thread_active = true; // Flag for quitting the reception thread - -static area_id buffer_area; // Packet buffer area -static net_buffer *net_buffer_ptr; // Pointer to packet buffer -static uint32 rd_pos; // Current read position in packet buffer -static uint32 wr_pos; // Current write position in packet buffer -static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing - -static int fd = -1; // UDP socket fd -static bool udp_tunnel = false; - - -// Prototypes -static status_t receive_proc(void *data); - - -/* - * Find protocol in list - */ - -static NetProtocol *find_protocol(uint16 type) -{ - // All 802.2 types are the same - if (type <= 1500) - type = 0; - - // Search list (we could use hashing here but there are usually only three - // handlers installed: 0x0000 for AppleTalk and 0x0800/0x0806 for TCP/IP) - NetProtocol *p; - for (int i=0; (p = (NetProtocol *)prot_list.ItemAt(i)) != NULL; i++) - if (p->type == type) - return p; - return NULL; -} - - -/* - * Remove all protocols - */ - -static void remove_all_protocols(void) -{ - NetProtocol *p; - while ((p = (NetProtocol *)prot_list.RemoveItem((long)0)) != NULL) - delete p; -} - - -/* - * Initialization - */ - -bool ether_init(void) -{ - // Do nothing if no Ethernet device specified - if (PrefsFindString("ether") == NULL) - return false; - - // Find net_server team -i_wanna_try_that_again: - bool found_add_on = false; - team_info t_info; - int32 t_cookie = 0; - image_info i_info; - int32 i_cookie = 0; - while (get_next_team_info(&t_cookie, &t_info) == B_NO_ERROR) { - if (strstr(t_info.args,"net_server")!=NULL) { - - // Check if sheep_net add-on is loaded - while (get_next_image_info(t_info.team, &i_cookie, &i_info) == B_NO_ERROR) { - if (strstr(i_info.name, "sheep_net") != NULL) { - found_add_on = true; - break; - } - } - } - if (found_add_on) break; - } - if (!found_add_on) { - - // Search for sheep_net in network config file - char str[1024]; - bool sheep_net_found = false; - FILE *fin = fopen("/boot/home/config/settings/network", "r"); - while (!feof(fin)) { - fgets(str, 1024, fin); - if (strstr(str, "PROTOCOLS")) - if (strstr(str, "sheep_net")) - sheep_net_found = true; - } - fclose(fin); - - // It was found, so something else must be wrong - if (sheep_net_found) { - WarningAlert(GetString(STR_NO_NET_ADDON_WARN)); - return false; - } - - // Not found, inform the user - if (!ChoiceAlert(GetString(STR_NET_CONFIG_MODIFY_WARN), GetString(STR_OK_BUTTON), GetString(STR_CANCEL_BUTTON))) - return false; - - // Change the network config file and restart the network - fin = fopen("/boot/home/config/settings/network", "r"); - FILE *fout = fopen("/boot/home/config/settings/network.2", "w"); - bool global_found = false; - bool modified = false; - while (!feof(fin)) { - str[0] = 0; - fgets(str, 1024, fin); - if (!global_found && strstr(str, "GLOBAL:")) { - global_found = true; - } else if (global_found && !modified && strstr(str, "PROTOCOLS")) { - str[strlen(str)-1] = 0; - strcat(str, " sheep_net\n"); - modified = true; - } else if (global_found && !modified && strlen(str) > 2 && str[strlen(str) - 2] == ':') { - fputs("\tPROTOCOLS = sheep_net\n", fout); - modified = true; - } - fputs(str, fout); - } - if (!modified) - fputs("\tPROTOCOLS = sheep_net\n", fout); - fclose(fout); - fclose(fin); - remove("/boot/home/config/settings/network.orig"); - rename("/boot/home/config/settings/network", "/boot/home/config/settings/network.orig"); - rename("/boot/home/config/settings/network.2", "/boot/home/config/settings/network"); - - app_info ai; - if (be_roster->GetAppInfo("application/x-vnd.Be-NETS", &ai) == B_OK) { - BMessenger msg(NULL, ai.team); - if (msg.IsValid()) { - while (be_roster->IsRunning("application/x-vnd.Be-NETS")) { - msg.SendMessage(B_QUIT_REQUESTED); - snooze(500000); - } - } - } - BPath path; - find_directory(B_BEOS_BOOT_DIRECTORY, &path); - path.Append("Netscript"); - const char *argv[3] = {"/bin/sh", path.Path(), NULL}; - thread_id net_server = load_image(2, argv, (const char **)environ); - resume_thread(net_server); - status_t l; - wait_for_thread(net_server, &l); - goto i_wanna_try_that_again; - } - - // Set up communications with add-on - area_id handler_buffer; - if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) { - WarningAlert(GetString(STR_NET_ADDON_INIT_FAILED)); - return false; - } - if ((buffer_area = clone_area("local packet buffer", (void **)&net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) { - D(bug("EtherInit: couldn't clone packet area\n")); - WarningAlert(GetString(STR_NET_ADDON_CLONE_FAILED)); - return false; - } - if ((read_sem = create_sem(0, "ether read")) < B_NO_ERROR) { - printf("FATAL: can't create Ethernet semaphore\n"); - return false; - } - net_buffer_ptr->read_sem = read_sem; - write_sem = net_buffer_ptr->write_sem; - read_thread = spawn_thread(receive_proc, "Ethernet Receiver", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(read_thread); - for (int i=0; iwrite[i].cmd = IN_USE | (ACTIVATE_SHEEP_NET << 8); - rd_pos = wr_pos = 0; - release_sem(write_sem); - - // Get Ethernet address - memcpy(ether_addr, net_buffer_ptr->ether_addr, 6); - D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); - - // Everything OK - return true; -} - - -/* - * Deinitialization - */ - -void ether_exit(void) -{ - // Close communications with add-on - for (int i=0; iwrite[i].cmd = IN_USE | (DEACTIVATE_SHEEP_NET << 8); - release_sem(write_sem); - - // Quit reception thread - ether_thread_active = false; - status_t result; - release_sem(read_sem); - wait_for_thread(read_thread, &result); - - delete_sem(read_sem); - delete_area(buffer_area); - - // Remove all protocols - remove_all_protocols(); -} - - -/* - * Reset - */ - -void ether_reset(void) -{ - remove_all_protocols(); -} - - -/* - * Add multicast address - */ - -int16 ether_add_multicast(uint32 pb) -{ - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: Couldn't enable multicast address\n")); - } else { - Mac2Host_memcpy(p->data, pb + eMultiAddr, 6); - p->length = 6; - p->cmd = IN_USE | (ADD_MULTICAST << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - return noErr; -} - - -/* - * Delete multicast address - */ - -int16 ether_del_multicast(uint32 pb) -{ - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: Couldn't enable multicast address\n")); - } else { - Mac2Host_memcpy(p->data, pb + eMultiAddr, 6); - p->length = 6; - p->cmd = IN_USE | (REMOVE_MULTICAST << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - return noErr; -} - - -/* - * Attach protocol handler - */ - -int16 ether_attach_ph(uint16 type, uint32 handler) -{ - // Already attached? - NetProtocol *p = find_protocol(type); - if (p != NULL) - return lapProtErr; - else { - // No, create and attach - p = new NetProtocol; - p->type = type; - p->handler = handler; - prot_list.AddItem(p); - return noErr; - } -} - - -/* - * Detach protocol handler - */ - -int16 ether_detach_ph(uint16 type) -{ - NetProtocol *p = find_protocol(type); - if (p != NULL) { - prot_list.RemoveItem(p); - delete p; - return noErr; - } else - return lapProtErr; -} - - -/* - * Transmit raw ethernet packet - */ - -int16 ether_write(uint32 wds) -{ - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: Couldn't transmit packet (buffer full)\n")); - } else { - - // Copy packet to buffer - int len = ether_wds_to_buffer(wds, p->data); - -#if MONITOR - bug("Sending Ethernet packet:\n"); - for (int i=0; idata[i]); - } - bug("\n"); -#endif - - // Notify add-on - p->length = len; - p->cmd = IN_USE | (SHEEP_PACKET << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - return noErr; -} - - -/* - * Packet reception thread (non-UDP) - */ - -static status_t receive_proc(void *data) -{ - while (ether_thread_active) { - if (net_buffer_ptr->read[rd_pos].cmd & IN_USE) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - acquire_sem_etc(read_sem, 1, B_TIMEOUT, 25000); - } - return 0; -} - - -/* - * Packet reception thread (UDP) - */ - -static status_t receive_proc_udp(void *data) -{ - while (ether_thread_active) { - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - struct timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; - if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - } - return 0; -} - - -/* - * Start UDP packet reception thread - */ - -bool ether_start_udp_thread(int socket_fd) -{ - fd = socket_fd; - udp_tunnel = true; - ether_thread_active = true; - read_thread = spawn_thread(receive_proc_udp, "UDP Receiver", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(read_thread); - return true; -} - - -/* - * Stop UDP packet reception thread - */ - -void ether_stop_udp_thread(void) -{ - ether_thread_active = false; - status_t result; - wait_for_thread(read_thread, &result); -} - - -/* - * Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers - */ - -void EtherInterrupt(void) -{ - D(bug("EtherIRQ\n")); - EthernetPacket ether_packet; - uint32 packet = ether_packet.addr(); - - if (udp_tunnel) { - - ssize_t length; - - // Read packets from socket and hand to ether_udp_read() for processing - while (true) { - struct sockaddr_in from; - socklen_t from_len = sizeof(from); - length = recvfrom(fd, Mac2HostAddr(packet), 1514, 0, (struct sockaddr *)&from, &from_len); - if (length < 14) - break; - ether_udp_read(packet, length, &from); - } - - } else { - - // Call protocol handler for received packets - net_packet *p = &net_buffer_ptr->read[rd_pos]; - while (p->cmd & IN_USE) { - if ((p->cmd >> 8) == SHEEP_PACKET) { - Host2Mac_memcpy(packet, p->data, p->length); -#if MONITOR - bug("Receiving Ethernet packet:\n"); - for (int i=0; ilength; i++) { - bug("%02x ", ReadMacInt8(packet + i)); - } - bug("\n"); -#endif - // Get packet type - uint16 type = ReadMacInt16(packet + 12); - - // Look for protocol - NetProtocol *prot = find_protocol(type); - if (prot == NULL) - goto next; - - // No default handler - if (prot->handler == 0) - goto next; - - // Copy header to RHA - Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14); - D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); - - // Call protocol handler - M68kRegisters r; - r.d[0] = type; // Packet type - r.d[1] = p->length - 14; // Remaining packet length (without header, for ReadPacket) - r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket) - r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA - r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines - D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); - Execute68k(prot->handler, &r); - } -next: p->cmd = 0; // Free packet - rd_pos = (rd_pos + 1) % READ_PACKET_COUNT; - p = &net_buffer_ptr->read[rd_pos]; - } - } - D(bug(" EtherIRQ done\n")); -} diff --git a/BasiliskII/src/BeOS/extfs_beos.cpp b/BasiliskII/src/BeOS/extfs_beos.cpp deleted file mode 100644 index 5b7ab4d62..000000000 --- a/BasiliskII/src/BeOS/extfs_beos.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* - * extfs_beos.cpp - MacOS file system for access native file system access, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "extfs.h" -#include "extfs_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Default Finder flags -const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited; - -// Temporary buffer for transfers from/to kernel space -const int TMP_BUF_SIZE = 0x10000; -static uint8 *tmp_buf = NULL; - - -/* - * Initialization - */ - -void extfs_init(void) -{ - // Allocate temporary buffer - tmp_buf = new uint8[TMP_BUF_SIZE]; -} - - -/* - * Deinitialization - */ - -void extfs_exit(void) -{ - // Delete temporary buffer - delete[] tmp_buf; -} - - -/* - * Add component to path name - */ - -void add_path_component(char *path, const char *component) -{ - int l = strlen(path); - if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') { - path[l] = '/'; - path[l+1] = 0; - } - strncat(path, component, MAX_PATH_LENGTH-1); -} - - -/* - * Get/set finder info for file/directory specified by full path - */ - -struct mime2type { - const char *mime; - uint32 type; - uint32 creator; - bool reversible; // type -> mime translation possible -}; - -static const mime2type m2t_translation[] = { - {"application/x-compress", 'ZIVM', 'LZIV', true}, - {"application/x-gzip", 'Gzip', 'Gzip', true}, - {"application/x-macbinary", 'BINA', '????', false}, - {"application/mac-binhex40", 'TEXT', 'SITx', false}, - {"application/pdf", 'PDF ', 'CARO', true}, - {"application/postscript", 'TEXT', 'ttxt', false}, - {"application/x-stuffit", 'SIT!', 'SITx', true}, - {"application/x-tar", 'TARF', 'TAR ', true}, - {"application/x-uuencode", 'TEXT', 'SITx', false}, - {"application/zip", 'ZIP ', 'ZIP ', true}, - {"audio/x-8svx", '8SVX', 'SNDM', true}, - {"audio/x-aifc", 'AIFC', 'TVOD', true}, - {"audio/x-aiff", 'AIFF', 'TVOD', true}, - {"audio/basic", 'ULAW', 'TVOD', true}, - {"audio/x-midi", 'MIDI', 'TVOD', true}, - {"audio/x-mpeg", 'MPG ', 'TVOD', true}, - {"audio/x-wav", 'WAVE', 'TVOD', true}, - {"image/x-bmp", 'BMPf', 'ogle', true}, - {"image/gif", 'GIFf', 'ogle', true}, - {"image/x-ilbm", 'ILBM', 'GKON', true}, - {"image/jpeg", 'JPEG', 'ogle', true}, - {"image/jpeg", 'JFIF', 'ogle', true}, - {"image/x-photoshop", '8BPS', '8BIM', true}, - {"image/pict", 'PICT', 'ogle', true}, - {"image/png", 'PNGf', 'ogle', true}, - {"image/x-sgi", '.SGI', 'ogle', true}, - {"image/x-targa", 'TPIC', 'ogle', true}, - {"image/tiff", 'TIFF', 'ogle', true}, - {"text/html", 'TEXT', 'MOSS', false}, - {"text/plain", 'TEXT', 'ttxt', true}, - {"text/rtf", 'TEXT', 'MSWD', false}, - {"text/x-source-code", 'TEXT', 'R*ch', false}, - {"video/mpeg", 'MPEG', 'TVOD', true}, - {"video/quicktime", 'MooV', 'TVOD', true}, - {"video/x-flc", 'FLI ', 'TVOD', true}, - {"video/x-msvideo", 'VfW ', 'TVOD', true}, - {NULL, 0, 0, false} // End marker -}; - -void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Set default finder info - Mac_memset(finfo, 0, SIZEOF_FInfo); - if (fxinfo) - Mac_memset(fxinfo, 0, SIZEOF_FXInfo); - WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); - WriteMacInt32(finfo + fdLocation, (uint32)-1); - - // Open file - int fd = open(path, O_RDONLY); - if (fd < 0) - return; - - if (!is_dir) { - - // Read BeOS MIME type - ssize_t actual = fs_read_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, tmp_buf, 256); - tmp_buf[255] = 0; - - if (actual > 0) { - - // Translate MIME type to MacOS type/creator - uint8 mactype[4]; - if (sscanf((char *)tmp_buf, "application/x-MacOS-%c%c%c%c", mactype, mactype+1, mactype+2, mactype+3) == 4) { - - // MacOS style type - WriteMacInt32(finfo + fdType, (mactype[0] << 24) | (mactype[1] << 16) | (mactype[2] << 8) | mactype[3]); - - } else { - - // MIME string, look in table - for (int i=0; m2t_translation[i].mime; i++) { - if (!strcmp((char *)tmp_buf, m2t_translation[i].mime)) { - WriteMacInt32(finfo + fdType, m2t_translation[i].type); - WriteMacInt32(finfo + fdCreator, m2t_translation[i].creator); - break; - } - } - } - } - - // Override file type with MACOS:CREATOR attribute - if (fs_read_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4) == 4) - WriteMacInt32(finfo + fdCreator, (tmp_buf[0] << 24) | (tmp_buf[1] << 16) | (tmp_buf[2] << 8) | tmp_buf[3]); - } - - // Read MACOS:HFS_FLAGS attribute - if (fs_read_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2) == 2) - WriteMacInt16(finfo + fdFlags, (tmp_buf[0] << 8) | tmp_buf[1]); - - // Close file - close(fd); -} - -void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) -{ - // Open file - int fd = open(path, O_WRONLY); - if (fd < 0) - return; - - if (!is_dir) { - - // Set BEOS:TYPE attribute - uint32 type = ReadMacInt32(finfo + fdType); - if (type) { - for (int i=0; m2t_translation[i].mime; i++) { - if (m2t_translation[i].type == type && m2t_translation[i].reversible) { - fs_write_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, m2t_translation[i].mime, strlen(m2t_translation[i].mime) + 1); - break; - } - } - } - - // Set MACOS:CREATOR attribute - uint32 creator = ReadMacInt32(finfo + fdCreator); - if (creator) { - tmp_buf[0] = creator >> 24; - tmp_buf[1] = creator >> 16; - tmp_buf[2] = creator >> 8; - tmp_buf[3] = creator; - fs_write_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4); - } - } - - // Write MACOS:HFS_FLAGS attribute - uint16 flags = ReadMacInt16(finfo + fdFlags); - if (flags != DEFAULT_FINDER_FLAGS) { - tmp_buf[0] = flags >> 8; - tmp_buf[1] = flags; - fs_write_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2); - } else - fs_remove_attr(fd, "MACOS:HFS_FLAGS"); - - // Close file - close(fd); -} - - -/* - * Resource fork emulation functions - */ - -uint32 get_rfork_size(const char *path) -{ - // Open file - int fd = open(path, O_RDONLY); - if (fd < 0) - return 0; - - // Get size of MACOS:RFORK attribute - struct attr_info info; - if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0) - info.size = 0; - - // Close file and return size - close(fd); - return info.size; -} - -int open_rfork(const char *path, int flag) -{ - // Open original file - int fd = open(path, flag); - if (fd < 0) - return -1; - - // Open temporary file for resource fork - char rname[L_tmpnam]; - tmpnam(rname); - int rfd = open(rname, O_RDWR | O_CREAT | O_TRUNC, 0666); - if (rfd < 0) { - close(fd); - return -1; - } - unlink(rname); // File will be deleted when closed - - // Get size of MACOS:RFORK attribute - struct attr_info info; - if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0) - info.size = 0; - - // Copy resource data from attribute to temporary file - if (info.size > 0) { - - // Allocate buffer - void *buf = malloc(info.size); - if (buf == NULL) { - close(rfd); - close(fd); - return -1; - } - - // Copy data - fs_read_attr(fd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, info.size); - write(rfd, buf, info.size); - lseek(rfd, 0, SEEK_SET); - - // Free buffer - if (buf) - free(buf); - } - - // Close original file - close(fd); - return rfd; -} - -void close_rfork(const char *path, int fd) -{ - if (fd < 0) - return; - - // Get size of temporary file - struct stat st; - if (fstat(fd, &st) < 0) - st.st_size = 0; - - // Open original file - int ofd = open(path, O_WRONLY); - if (ofd > 0) { - - // Copy resource data to MACOS:RFORK attribute - if (st.st_size > 0) { - - // Allocate buffer - void *buf = malloc(st.st_size); - if (buf == NULL) { - close(ofd); - close(fd); - return; - } - - // Copy data - lseek(fd, 0, SEEK_SET); - read(fd, buf, st.st_size); - fs_write_attr(ofd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, st.st_size); - - // Free buffer - if (buf) - free(buf); - - } else - fs_remove_attr(ofd, "MACOS:RFORK"); - - // Close original file - close(ofd); - } - - // Close temporary file - close(fd); -} - - -/* - * Read "length" bytes from file to "buffer", - * returns number of bytes read (or -1 on error) - */ - -static inline ssize_t sread(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = read(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -ssize_t extfs_read(int fd, void *buffer, size_t length) -{ - // Buffer in kernel space? - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - ssize_t actual = 0; - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - ssize_t res = sread(fd, tmp_buf, transfer_size); - if (res < 0) - return res; - memcpy(buffer, tmp_buf, res); - buffer = (void *)((uint8 *)buffer + res); - length -= res; - actual += res; - if (res != transfer_size) - return actual; - } - return actual; - - } else { - - // No, transfer directly - return sread(fd, buffer, length); - } -} - - -/* - * Write "length" bytes from "buffer" to file, - * returns number of bytes written (or -1 on error) - */ - -static inline ssize_t swrite(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = write(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -ssize_t extfs_write(int fd, void *buffer, size_t length) -{ - // Buffer in kernel space? - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - ssize_t actual = 0; - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - memcpy(tmp_buf, buffer, transfer_size); - ssize_t res = swrite(fd, tmp_buf, transfer_size); - if (res < 0) - return res; - buffer = (void *)((uint8 *)buffer + res); - length -= res; - actual += res; - if (res != transfer_size) - return actual; - } - return actual; - - } else { - - // No, transfer directly - return swrite(fd, buffer, length); - } -} - - -/* - * Remove file/directory, returns false on error (and sets errno) - */ - -bool extfs_remove(const char *path) -{ - if (remove(path) < 0) { - if (errno == EISDIR) - return rmdir(path) == 0; - else - return false; - } - return true; -} - - -/* - * Rename/move file/directory, returns false on error (and sets errno) - */ - -bool extfs_rename(const char *old_path, const char *new_path) -{ - return rename(old_path, new_path) == 0; -} - -/* - * Strings (filenames) conversion - */ - -// Convert from the host OS filename encoding to MacRoman -const char *host_encoding_to_macroman(const char *filename) -{ - int32 state = 0; - static char buffer[512]; - int32 size = sizeof(buffer) - 1; - int32 insize = strlen(filename); - convert_from_utf8(B_MAC_ROMAN_CONVERSION, filename, &insize, buffer, &size, &state); - buffer[size] = 0; - return buffer; -} - -// Convert from MacRoman to host OS filename encoding -const char *macroman_to_host_encoding(const char *filename) -{ - int32 state = 0; - static char buffer[512]; - int32 insize = strlen(filename); - int32 size = sizeof(buffer) - 1; - convert_to_utf8(B_MAC_ROMAN_CONVERSION, filename, &insize, buffer, &size, &state); - buffer[size] = 0; - return buffer; -} diff --git a/BasiliskII/src/BeOS/main_beos.cpp b/BasiliskII/src/BeOS/main_beos.cpp deleted file mode 100644 index 507e3bde0..000000000 --- a/BasiliskII/src/BeOS/main_beos.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/* - * main_beos.cpp - Startup code for BeOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "xpram.h" -#include "timer.h" -#include "video.h" -#include "rom_patches.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "sys.h" -#include "user_strings.h" -#include "version.h" -#include "main.h" - -#include "sheep_driver.h" - -#define DEBUG 0 -#include "debug.h" - - -// Constants -const char APP_SIGNATURE[] = "application/x-vnd.cebix-BasiliskII"; -const char ROM_FILE_NAME[] = "ROM"; -const char RAM_AREA_NAME[] = "Macintosh RAM"; -const char ROM_AREA_NAME[] = "Macintosh ROM"; -const uint32 MSG_START = 'strt'; // Emulator start message -const uint32 ROM_AREA_SIZE = 0x500000; // Enough to hold PowerMac ROM (for powerrom_cpu) - -// Prototypes -#if __POWERPC__ -static void sigsegv_handler(vregs *r); -#endif - - -// Application object -class BasiliskII : public BApplication { -public: - BasiliskII() : BApplication(APP_SIGNATURE) - { - // Find application directory and cwd to it - app_info the_info; - GetAppInfo(&the_info); - BEntry the_file(&the_info.ref); - BEntry the_dir; - the_file.GetParent(&the_dir); - BPath the_path; - the_dir.GetPath(&the_path); - chdir(the_path.Path()); - - // Initialize other variables - rom_area = ram_area = -1; - xpram_thread = tick_thread = -1; - xpram_thread_active = true; - tick_thread_active = true; - AllowQuitting = true; - } - virtual void ReadyToRun(void); - virtual void MessageReceived(BMessage *msg); - void StartEmulator(void); - virtual bool QuitRequested(void); - virtual void Quit(void); - - thread_id xpram_thread; // XPRAM watchdog - thread_id tick_thread; // 60Hz thread - - volatile bool xpram_thread_active; // Flag for quitting the XPRAM thread - volatile bool tick_thread_active; // Flag for quitting the 60Hz thread - - bool AllowQuitting; // Flag: Alt-Q quitting allowed - -private: - static status_t emul_func(void *arg); - static status_t tick_func(void *arg); - static status_t xpram_func(void *arg); - static void sigsegv_invoc(int sig, void *arg, vregs *r); - - void init_rom(void); - void load_rom(void); - - area_id rom_area; // ROM area ID - area_id ram_area; // RAM area ID - - struct sigaction sigsegv_action; // Data access exception signal (of emulator thread) - - // Exceptions - class area_error {}; - class file_open_error {}; - class file_read_error {}; - class rom_size_error {}; - - char* vmdir; -}; - -static BasiliskII *the_app; - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - -// Global variables for PowerROM CPU -thread_id emul_thread = -1; // Emulator thread - -#if __POWERPC__ -int sheep_fd = -1; // fd of sheep driver -#endif - - -/* - * Create application object and start it - */ - -int main(int argc, char **argv) -{ - the_app = new BasiliskII(); - the_app->Run(); - delete the_app; - return 0; -} - - -/* - * Run application - */ - -void BasiliskII::ReadyToRun(void) -{ - // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; - srand(real_time_clock()); - tzset(); - - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - - // Delete old areas - area_id old_ram_area = find_area(RAM_AREA_NAME); - if (old_ram_area > 0) - delete_area(old_ram_area); - area_id old_rom_area = find_area(ROM_AREA_NAME); - if (old_rom_area > 0) - delete_area(old_rom_area); - - // Read preferences - int argc = 0; - char **argv = NULL; - PrefsInit(vmdir, argc, argv); - - // Init system routines - SysInit(); - - // Show preferences editor (or start emulator directly) - if (!PrefsFindBool("nogui")) - PrefsEditor(); - else - PostMessage(MSG_START); -} - - -/* - * Message received - */ - -void BasiliskII::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case MSG_START: - StartEmulator(); - break; - default: - BApplication::MessageReceived(msg); - } -} - - -/* - * Start emulator - */ - -void BasiliskII::StartEmulator(void) -{ - char str[256]; - -#if REAL_ADDRESSING - // Open sheep driver and remap low memory - sheep_fd = open("/dev/sheep", 0); - if (sheep_fd < 0) { - sprintf(str, GetString(STR_NO_SHEEP_DRIVER_ERR), strerror(sheep_fd), sheep_fd); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - status_t res = ioctl(sheep_fd, SHEEP_UP); - if (res < 0) { - sprintf(str, GetString(STR_SHEEP_UP_ERR), strerror(res), res); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } -#endif - - // Create area for Mac RAM - RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - - RAMBaseHost = (uint8 *)0x10000000; - ram_area = create_area(RAM_AREA_NAME, (void **)&RAMBaseHost, B_BASE_ADDRESS, RAMSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (ram_area < 0) { - ErrorAlert(STR_NO_RAM_AREA_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } - D(bug("RAM area %ld at %p\n", ram_area, RAMBaseHost)); - - // Create area and load Mac ROM - try { - init_rom(); - } catch (area_error) { - ErrorAlert(STR_NO_ROM_AREA_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (file_open_error) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (file_read_error) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (rom_size_error) { - ErrorAlert(STR_ROM_SIZE_ERR); - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Initialize everything - if (!InitAll(NULL)) { - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Write protect ROM - set_area_protection(rom_area, B_READ_AREA); - - // Disallow quitting with Alt-Q from now on - AllowQuitting = false; - - // Start XPRAM watchdog thread - xpram_thread = spawn_thread(xpram_func, "XPRAM Watchdog", B_LOW_PRIORITY, this); - resume_thread(xpram_thread); - - // Start 60Hz interrupt - tick_thread = spawn_thread(tick_func, "60Hz", B_REAL_TIME_PRIORITY, this); - resume_thread(tick_thread); - - // Start emulator thread - emul_thread = spawn_thread(emul_func, "MacOS", B_NORMAL_PRIORITY, this); - resume_thread(emul_thread); -} - - -/* - * Quit emulator - */ - -void QuitEmulator(void) -{ - the_app->AllowQuitting = true; - be_app->PostMessage(B_QUIT_REQUESTED); - exit_thread(0); -} - -bool BasiliskII::QuitRequested(void) -{ - if (AllowQuitting) - return BApplication::QuitRequested(); - else - return false; -} - -void BasiliskII::Quit(void) -{ - status_t l; - - // Stop 60Hz interrupt - if (tick_thread > 0) { - tick_thread_active = false; - wait_for_thread(tick_thread, &l); - } - - // Wait for emulator thread to finish - if (emul_thread > 0) - wait_for_thread(emul_thread, &l); - - // Exit 680x0 emulation - Exit680x0(); - - // Stop XPRAM watchdog thread - if (xpram_thread > 0) { - xpram_thread_active = false; - suspend_thread(xpram_thread); // Wake thread up from snooze() - snooze(1000); - resume_thread(xpram_thread); - wait_for_thread(xpram_thread, &l); - } - - // Deinitialize everything - ExitAll(); - - // Delete ROM area - if (rom_area >= 0) - delete_area(rom_area); - - // Delete RAM area - if (ram_area >= 0) - delete_area(ram_area); - -#if REAL_ADDRESSING - // Unmap low memory and close memory mess driver - if (sheep_fd >= 0) { - ioctl(sheep_fd, SHEEP_DOWN); - close(sheep_fd); - } -#endif - - // Exit system routines - SysExit(); - - // Exit preferences - PrefsExit(); - - BApplication::Quit(); -} - - -/* - * Create area for ROM (sets rom_area) and load ROM file - * - * area_error : Cannot create area - * file_open_error: Cannot open ROM file - * file_read_error: Cannot read ROM file - */ - -void BasiliskII::init_rom(void) -{ - // Create area for ROM - ROMBaseHost = (uint8 *)0x40800000; - rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBaseHost, B_BASE_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (rom_area < 0) - throw area_error(); - D(bug("ROM area %ld at %p\n", rom_area, ROMBaseHost)); - - // Load ROM - load_rom(); -} - - -/* - * Load ROM file - * - * file_open_error: Cannot open ROM file - * file_read_error: Cannot read ROM file - */ - -void BasiliskII::load_rom(void) -{ - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - - // Try to open ROM file - BFile file(rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); - if (file.InitCheck() != B_NO_ERROR) - throw file_open_error(); - - printf(GetString(STR_READING_ROM_FILE)); - - // Is the ROM size correct? - off_t rom_size = 0; - file.GetSize(&rom_size); - if (rom_size != 64*1024 && rom_size != 128*1024 && rom_size != 256*1024 && rom_size != 512*1024 && rom_size != 1024*1024) - throw rom_size_error(); - - uint8 *rom = new uint8[rom_size]; // Reading directly into the area doesn't work - ssize_t actual = file.Read((void *)rom, rom_size); - if (actual == rom_size) - memcpy(ROMBaseHost, rom, rom_size); - delete[] rom; - if (actual != rom_size) - throw file_read_error(); - ROMSize = rom_size; -} - - -/* - * Emulator thread function - */ - -status_t BasiliskII::emul_func(void *arg) -{ - BasiliskII *obj = (BasiliskII *)arg; - -#if __POWERPC__ - // Install data access signal handler - sigemptyset(&obj->sigsegv_action.sa_mask); - obj->sigsegv_action.sa_handler = (__signal_func_ptr)(obj->sigsegv_invoc); - obj->sigsegv_action.sa_flags = 0; - obj->sigsegv_action.sa_userdata = arg; - sigaction(SIGSEGV, &obj->sigsegv_action, NULL); -#endif - - // Exceptions will send signals - disable_debugger(true); - - // Start 68k and jump to ROM boot routine - Start680x0(); - - // Quit program - obj->AllowQuitting = true; - be_app->PostMessage(B_QUIT_REQUESTED); - return 0; -} - - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size) -{ -} - - -/* - * Mutexes - */ - -struct B2_mutex { - int dummy; //!! -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - - -/* - * Interrupt flags (must be handled atomically!) - */ - -uint32 InterruptFlags = 0; - -void SetInterruptFlag(uint32 flag) -{ - atomic_or((int32 *)&InterruptFlags, flag); -} - -void ClearInterruptFlag(uint32 flag) -{ - atomic_and((int32 *)&InterruptFlags, ~flag); -} - - -/* - * 60Hz thread (really 60.15Hz) - */ - -status_t BasiliskII::tick_func(void *arg) -{ - BasiliskII *obj = (BasiliskII *)arg; - int tick_counter = 0; - bigtime_t current = system_time(); - - while (obj->tick_thread_active) { - - // Wait - current += 16625; - snooze_until(current, B_SYSTEM_TIMEBASE); - - // Pseudo Mac 1Hz interrupt, update local time - if (++tick_counter > 60) { - tick_counter = 0; - WriteMacInt32(0x20c, TimerDateTime()); - SetInterruptFlag(INTFLAG_1HZ); - TriggerInterrupt(); - } - - // Trigger 60Hz interrupt - SetInterruptFlag(INTFLAG_60HZ); - TriggerInterrupt(); - } - return 0; -} - - -/* - * XPRAM watchdog thread (saves XPRAM every minute) - */ - -status_t BasiliskII::xpram_func(void *arg) -{ - uint8 last_xpram[XPRAM_SIZE]; - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - - while (((BasiliskII *)arg)->xpram_thread_active) { - snooze(60*1000000); - if (memcmp(last_xpram, XPRAM, XPRAM_SIZE)) { - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - SaveXPRAM(); - } - } - return 0; -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_ERROR_PREFIX), text); - return; - } - VideoQuitFullScreen(); - char str[256]; - sprintf(str, GetString(STR_GUI_ERROR_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_ERROR_ALERT_TITLE), str, GetString(STR_QUIT_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); - alert->Go(); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return; - } - char str[256]; - sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - alert->Go(); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - char str[256]; - sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, pos, neg, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - return alert->Go() == 0; -} - - -/* - * SEGV handler - */ - -#if __POWERPC__ -static uint32 segv_r[32]; - -asm void BasiliskII::sigsegv_invoc(register int sig, register void *arg, register vregs *r) -{ - mflr r0 - stw r0,8(r1) - stwu r1,-56(r1) - - lwz r3,segv_r(r2) - stmw r13,13*4(r3) - - mr r3,r5 - bl sigsegv_handler - - lwz r3,segv_r(r2) - lmw r13,13*4(r3) - - lwz r0,56+8(r1) - mtlr r0 - addi r1,r1,56 - blr -} - -static void sigsegv_handler(vregs *r) -{ - // Fetch volatile registers - segv_r[0] = r->r0; - segv_r[1] = r->r1; - segv_r[2] = r->r2; - segv_r[3] = r->r3; - segv_r[4] = r->r4; - segv_r[5] = r->r5; - segv_r[6] = r->r6; - segv_r[7] = r->r7; - segv_r[8] = r->r8; - segv_r[9] = r->r9; - segv_r[10] = r->r10; - segv_r[11] = r->r11; - segv_r[12] = r->r12; - - // Get opcode and divide into fields - uint32 opcode = *(uint32 *)r->pc; - uint32 primop = opcode >> 26; - uint32 exop = (opcode >> 1) & 0x3ff; - uint32 ra = (opcode >> 16) & 0x1f; - uint32 rb = (opcode >> 11) & 0x1f; - uint32 rd = (opcode >> 21) & 0x1f; - uint32 imm = opcode & 0xffff; - - // Analyze opcode - enum { - TYPE_UNKNOWN, - TYPE_LOAD, - TYPE_STORE - } transfer_type = TYPE_UNKNOWN; - enum { - SIZE_UNKNOWN, - SIZE_BYTE, - SIZE_HALFWORD, - SIZE_WORD - } transfer_size = SIZE_UNKNOWN; - enum { - MODE_UNKNOWN, - MODE_NORM, - MODE_U, - MODE_X, - MODE_UX - } addr_mode = MODE_UNKNOWN; - switch (primop) { - case 31: - switch (exop) { - case 23: // lwzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 55: // lwzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 87: // lbzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 119: // lbzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 151: // stwx - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 183: // stwux - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 215: // stbx - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 247: // stbux - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 279: // lhzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 311: // lhzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - case 343: // lhax - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 375: // lhaux - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - case 407: // sthx - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 439: // sthux - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - } - break; - - case 32: // lwz - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 33: // lwzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 34: // lbz - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 35: // lbzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 36: // stw - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 37: // stwu - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 38: // stb - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 39: // stbu - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 40: // lhz - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 41: // lhzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - case 42: // lha - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 43: // lhau - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - case 44: // sth - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 45: // sthu - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - } - - // Calculate effective address - uint32 addr = 0; - switch (addr_mode) { - case MODE_X: - case MODE_UX: - if (ra == 0) - addr = segv_r[rb]; - else - addr = segv_r[ra] + segv_r[rb]; - break; - case MODE_NORM: - case MODE_U: - if (ra == 0) - addr = (int32)(int16)imm; - else - addr = segv_r[ra] + (int32)(int16)imm; - break; - } - - // Ignore ROM writes - if (transfer_type == TYPE_STORE && addr >= (uint32)ROMBaseHost && addr < (uint32)ROMBaseHost + ROMSize) { -// D(bug("WARNING: %s write access to ROM at %p, 68k pc %p\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc)); - if (addr_mode == MODE_U || addr_mode == MODE_UX) - segv_r[ra] = addr; - r->pc += 4; - goto rti; - } - - // For all other errors, jump into debugger - char str[256]; - sprintf(str, "SIGSEGV\n" - " pc %08lx lr %08lx ctr %08lx msr %08lx\n" - " xer %08lx cr %08lx fpscr %08lx\n" - " r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n" - " r4 %08lx r5 %08lx r6 %08lx r7 %08lx\n" - " r8 %08lx r9 %08lx r10 %08lx r11 %08lx\n" - " r12 %08lx r13 %08lx r14 %08lx r15 %08lx\n" - " r16 %08lx r17 %08lx r18 %08lx r19 %08lx\n" - " r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" - " r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" - " r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", - r->pc, r->lr, r->ctr, r->msr, - r->xer, r->cr, r->fpscr, - r->r0, r->r1, r->r2, r->r3, - r->r4, r->r5, r->r6, r->r7, - r->r8, r->r9, r->r10, r->r11, - r->r12, segv_r[13], segv_r[14], segv_r[15], - segv_r[16], segv_r[17], segv_r[18], segv_r[19], - segv_r[20], segv_r[21], segv_r[22], segv_r[23], - segv_r[24], segv_r[25], segv_r[26], segv_r[27], - segv_r[28], segv_r[29], segv_r[30], segv_r[31]); - disable_debugger(false); - debugger(str); - QuitEmulator(); - return; - -rti: - // Restore volatile registers - r->r0 = segv_r[0]; - r->r1 = segv_r[1]; - r->r2 = segv_r[2]; - r->r3 = segv_r[3]; - r->r4 = segv_r[4]; - r->r5 = segv_r[5]; - r->r6 = segv_r[6]; - r->r7 = segv_r[7]; - r->r8 = segv_r[8]; - r->r9 = segv_r[9]; - r->r10 = segv_r[10]; - r->r11 = segv_r[11]; - r->r12 = segv_r[12]; -} -#endif diff --git a/BasiliskII/src/BeOS/prefs_beos.cpp b/BasiliskII/src/BeOS/prefs_beos.cpp deleted file mode 100644 index 9a74d6431..000000000 --- a/BasiliskII/src/BeOS/prefs_beos.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * prefs_beos.cpp - Preferences handling, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "sysdeps.h" -#include "prefs.h" -#include "main.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { - {"powerrom", TYPE_STRING, false, "path of PowerMac ROM"}, - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Preferences file name and path -const char PREFS_FILE_NAME[] = "BasiliskII_prefs"; -static BPath prefs_path; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(const char* vmdir) -{ -#if 0 - if (vmdir) { - prefs_path.SetTo(vmdir); - prefs_path.Append("prefs"); - FILE *prefs = fopen(prefs_path.Path(), "r"); - if (!prefs) { - printf("No file at %s found.\n", prefs_path.Path()); - exit(1); - } - LoadPrefsFromStream(prefs); - fclose(prefs); - return; - } -#endif - - // Construct prefs path - find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true); - prefs_path.Append(PREFS_FILE_NAME); - - // Read preferences from settings file - FILE *f = fopen(prefs_path.Path(), "r"); - if (f != NULL) { - - // Prefs file found, load settings - LoadPrefsFromStream(f); - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - } -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = fopen(prefs_path.Path(), "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsReplaceString("extfs", "/boot"); -} diff --git a/BasiliskII/src/BeOS/prefs_editor_beos.cpp b/BasiliskII/src/BeOS/prefs_editor_beos.cpp deleted file mode 100644 index a40e4748d..000000000 --- a/BasiliskII/src/BeOS/prefs_editor_beos.cpp +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * prefs_editor_beos.cpp - Preferences editor, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "cdrom.h" -#include "xpram.h" -#include "prefs.h" -#include "about_window.h" -#include "user_strings.h" -#include "prefs_editor.h" - - -// Special colors -const rgb_color fill_color = {216, 216, 216, 0}; -const rgb_color slider_fill_color = {102, 152, 255, 0}; - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_SCREEN -}; - -// Window messages -const uint32 MSG_OK = 'okok'; // "Start" clicked -const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked -const uint32 MSG_ZAP_PRAM = 'zprm'; - -const int NUM_PANES = 4; - -const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane -const uint32 MSG_VOLUME_INVOKED = 'voli'; -const uint32 MSG_ADD_VOLUME = 'addv'; -const uint32 MSG_CREATE_VOLUME = 'crev'; -const uint32 MSG_REMOVE_VOLUME = 'remv'; -const uint32 MSG_ADD_VOLUME_PANEL = 'advp'; -const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp'; -const uint32 MSG_DEVICE_NAME = 'devn'; -const uint32 MSG_BOOT_ANY = 'bany'; -const uint32 MSG_BOOT_CDROM = 'bcdr'; -const uint32 MSG_NOCDROM = 'nocd'; - -const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics/Sound" pane -const uint32 MSG_REF_7_5HZ = ' 7Hz'; -const uint32 MSG_REF_10HZ = '10Hz'; -const uint32 MSG_REF_15HZ = '15Hz'; -const uint32 MSG_REF_30HZ = '30Hz'; -const uint32 MSG_VIDEO_WINDOW = 'vtyw'; -const uint32 MSG_VIDEO_SCREEN = 'vtys'; -const uint32 MSG_SCREEN_MODE = 'sm\0\0'; -const uint32 MSG_NOSOUND = 'nosn'; - -const uint32 MSG_SER_A = 'sera'; // "Serial/Network" pane -const uint32 MSG_SER_B = 'serb'; -const uint32 MSG_ETHER = 'ethr'; -const uint32 MSG_UDPTUNNEL = 'udpt'; - -const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory/Misc" pane -const uint32 MSG_MODELID_5 = 'mi05'; -const uint32 MSG_MODELID_14 = 'mi14'; -const uint32 MSG_CPU_68020 = 'cpu2'; -const uint32 MSG_CPU_68020_FPU = 'cpf2'; -const uint32 MSG_CPU_68030 = 'cpu3'; -const uint32 MSG_CPU_68030_FPU = 'cpf3'; -const uint32 MSG_CPU_68040 = 'cpu4'; - - -// RAM size slider class -class RAMSlider : public BSlider { -public: - RAMSlider(BRect frame, const char *name, const char *label, BMessage *message, - int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB, - uint32 resizingMode = B_FOLLOW_LEFT | - B_FOLLOW_TOP, - uint32 flags = B_NAVIGABLE | B_WILL_DRAW | - B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags) - { - update_text = (char *)malloc(256); - } - - virtual ~RAMSlider() - { - if (update_text) - free(update_text); - } - - virtual char *UpdateText(void) const - { - if (update_text) { - sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value()); - } - return update_text; - } - -private: - char *update_text; -}; - - -// Volumes list view class -class VolumeListView : public BListView { -public: - VolumeListView(BRect frame, const char *name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE) - : BListView(frame, name, type, resizeMask, flags) - {} - - // Handle dropped files and volumes - virtual void MessageReceived(BMessage *msg) - { - if (msg->what == B_SIMPLE_DATA) { - BMessage msg2(MSG_ADD_VOLUME_PANEL); - entry_ref ref; - for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++) - msg2.AddRef("refs", &ref); - Window()->PostMessage(&msg2); - } else - BListView::MessageReceived(msg); - } -}; - - -// Number-entry BTextControl -class NumberControl : public BTextControl { -public: - NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message) - : BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) - { - SetDivider(divider); - for (int c=0; c<256; c++) - if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW) - ((BTextView *)ChildAt(0))->DisallowChar(c); - SetValue(value); - } - - // Set integer value - void SetValue(long value) - { - char str[32]; - sprintf(str, "%ld", value); - SetText(str); - } - - // Get integer value - long Value(void) - { - return atol(Text()); - } -}; - - -// Path-entry BTextControl -class PathControl : public BTextControl { -public: - PathControl(bool dir_ctrl_, BRect frame, const char *name, const char *label, const char *text, BMessage *message) : BTextControl(frame, name, label, text, message), dir_ctrl(dir_ctrl_) - { - for (int c=0; c<' '; c++) - if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW) - ((BTextView *)ChildAt(0))->DisallowChar(c); - } - - virtual void MessageReceived(BMessage *msg) - { - if (msg->what == B_SIMPLE_DATA) { - entry_ref the_ref; - BEntry the_entry; - - // Look for dropped refs - if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) { - if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) { - BPath the_path; - the_entry.GetPath(&the_path); - SetText(the_path.Path()); - } - } else - BTextControl::MessageReceived(msg); - - MakeFocus(); - } else - BTextControl::MessageReceived(msg); - } - -private: - bool dir_ctrl; -}; - - -// Preferences window class -class PrefsWindow : public BWindow { -public: - PrefsWindow(uint32 msg); - virtual ~PrefsWindow(); - virtual void MessageReceived(BMessage *msg); - -private: - void read_volumes_prefs(void); - void hide_show_graphics_ctrls(void); - void read_graphics_prefs(void); - void hide_show_serial_ctrls(void); - void read_serial_prefs(void); - void add_serial_names(BPopUpMenu *menu, uint32 msg); - void read_memory_prefs(void); - - BView *create_volumes_pane(void); - BView *create_graphics_pane(void); - BView *create_serial_pane(void); - BView *create_memory_pane(void); - - uint32 ok_message; - bool send_quit_on_close; - - system_info sys_info; - BMessenger this_messenger; - BView *top; - BRect top_frame; - BTabView *pane_tabs; - BView *panes[NUM_PANES]; - int current_pane; - - VolumeListView *volume_list; - BCheckBox *nocdrom_checkbox; - BMenuField *frameskip_menu; - NumberControl *display_x_ctrl; - NumberControl *display_y_ctrl; - BMenuField *scr_mode_menu; - BCheckBox *nosound_checkbox; - BCheckBox *ether_checkbox; - BCheckBox *udptunnel_checkbox; - NumberControl *udpport_ctrl; - RAMSlider *ramsize_slider; - PathControl *extfs_control; - PathControl *rom_control; - BCheckBox *fpu_checkbox; - - BFilePanel *add_volume_panel; - BFilePanel *create_volume_panel; - - uint32 max_ramsize; // In MB - int display_type; - int scr_mode_bit; -}; - - -/* - * Show preferences editor (asynchronously) - * Under BeOS, the return value is ignored. Instead, a message is sent to the - * application when the user clicks on "Start" or "Quit" - */ - -bool PrefsEditor(void) -{ - new PrefsWindow('strt'); - return true; -} - - -/* - * Preferences window constructor - */ - -PrefsWindow::PrefsWindow(uint32 msg) : BWindow(BRect(0, 0, 400, 289), GetString(STR_PREFS_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), this_messenger(this) -{ - int i; - ok_message = msg; - send_quit_on_close = true; - get_system_info(&sys_info); - - // Move window to right position - Lock(); - MoveTo(80, 80); - - // Set up menus - BMenuBar *bar = new BMenuBar(Bounds(), "menu"); - BMenu *menu = new BMenu(GetString(STR_PREFS_MENU)); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED))); - menu->AddItem(new BSeparatorItem); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK))); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM))); - menu->AddItem(new BSeparatorItem); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q')); - bar->AddItem(menu); - AddChild(bar); - SetKeyMenuBar(bar); - int mbar_height = int(bar->Bounds().bottom) + 1; - - // Resize window to fit menu bar - ResizeBy(0, mbar_height); - - // Light gray background - BRect b = Bounds(); - top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW); - AddChild(top); - top->SetViewColor(fill_color); - top_frame = top->Bounds(); - - // Create panes - panes[0] = create_volumes_pane(); - panes[1] = create_graphics_pane(); - panes[2] = create_serial_pane(); - panes[3] = create_memory_pane(); - - // Prefs item tab view - pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL); - for (i=0; iAddTab(panes[i]); - top->AddChild(pane_tabs); - - volume_list->Select(0); - - // Create volume file panels - add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL)); - add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON)); - add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE)); - create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL)); - create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON)); - create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE)); - - create_volume_panel->Window()->Lock(); - BView *background = create_volume_panel->Window()->ChildAt(0); - background->FindView("PoseView")->ResizeBy(0, -30); - background->FindView("VScrollBar")->ResizeBy(0, -30); - background->FindView("CountVw")->MoveBy(0, -30); - BView *v = background->FindView("HScrollBar"); - if (v) - v->MoveBy(0, -30); - else { - i = 0; - while ((v = background->ChildAt(i++)) != NULL) { - if (v->Name() == NULL || v->Name()[0] == 0) { - v->MoveBy(0, -30); // unnamed horizontal scroll bar - break; - } - } - } - BView *filename = background->FindView("text view"); - BRect fnr(filename->Frame()); - fnr.OffsetBy(0, -30); - NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL); - background->AddChild(nc); - create_volume_panel->Window()->Unlock(); - - // "Start" button - BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK)); - top->AddChild(button); - SetDefaultButton(button); - - // "Quit" button - top->AddChild(new BButton(BRect(top_frame.right-90, top_frame.bottom-35, top_frame.right-20, top_frame.bottom-10), "cancel", GetString(STR_QUIT_BUTTON), new BMessage(MSG_CANCEL))); - - Unlock(); - Show(); -} - - -/* - * Preferences window destructor - */ - -PrefsWindow::~PrefsWindow() -{ - delete add_volume_panel; - delete create_volume_panel; - if (send_quit_on_close) - be_app->PostMessage(B_QUIT_REQUESTED); -} - - -/* - * Create "Volumes" pane - */ - -void PrefsWindow::read_volumes_prefs(void) -{ - PrefsReplaceString("extfs", extfs_control->Text()); -} - -BView *PrefsWindow::create_volumes_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - const char *str; - int32 index = 0; - volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 113), "volumes"); - while ((str = PrefsFindString("disk", index++)) != NULL) - volume_list->AddItem(new BStringItem(str)); - volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED)); - volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED)); - pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true)); - - pane->AddChild(new BButton(BRect(10, 118, pane->Bounds().right/3, 138), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME))); - pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 118, pane->Bounds().right*2/3, 138), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME))); - pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 118, pane->Bounds().right-11, 138), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME))); - - extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL); - extfs_control->SetDivider(90); - pane->AddChild(extfs_control); - - BMenuField *menu_field; - BPopUpMenu *menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu); - menu_field->SetDivider(90); - menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY))); - menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM))); - pane->AddChild(menu_field); - int32 i32 = PrefsFindInt32("bootdriver"); - BMenuItem *item; - if (i32 == 0) { - if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == CDROMRefNum) { - if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL) - item->SetMarked(true); - } - - nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM)); - pane->AddChild(nocdrom_checkbox); - nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF); - - return pane; -} - - -/* - * Create "Graphics/Sound" pane - */ - -// Screen mode list -struct scr_mode_desc { - int mode_mask; - int str; -}; - -static const scr_mode_desc scr_mode[] = { - {B_8_BIT_640x480, STR_8_BIT_640x480_LAB}, - {B_8_BIT_800x600, STR_8_BIT_800x600_LAB}, - {B_8_BIT_1024x768, STR_8_BIT_1024x768_LAB}, - {B_8_BIT_1152x900, STR_8_BIT_1152x900_LAB}, - {B_8_BIT_1280x1024, STR_8_BIT_1280x1024_LAB}, - {B_8_BIT_1600x1200, STR_8_BIT_1600x1200_LAB}, - {B_15_BIT_640x480, STR_15_BIT_640x480_LAB}, - {B_15_BIT_800x600, STR_15_BIT_800x600_LAB}, - {B_15_BIT_1024x768, STR_15_BIT_1024x768_LAB}, - {B_15_BIT_1152x900, STR_15_BIT_1152x900_LAB}, - {B_15_BIT_1280x1024, STR_15_BIT_1280x1024_LAB}, - {B_15_BIT_1600x1200, STR_15_BIT_1600x1200_LAB}, - {B_32_BIT_640x480, STR_24_BIT_640x480_LAB}, - {B_32_BIT_800x600, STR_24_BIT_800x600_LAB}, - {B_32_BIT_1024x768, STR_24_BIT_1024x768_LAB}, - {B_32_BIT_1152x900, STR_24_BIT_1152x900_LAB}, - {B_32_BIT_1280x1024, STR_24_BIT_1280x1024_LAB}, - {B_32_BIT_1600x1200, STR_24_BIT_1600x1200_LAB}, - {0, 0} // End marker -}; - -void PrefsWindow::hide_show_graphics_ctrls(void) -{ - if (display_type == DISPLAY_WINDOW) { - if (!scr_mode_menu->IsHidden()) - scr_mode_menu->Hide(); - if (frameskip_menu->IsHidden()) - frameskip_menu->Show(); - if (display_x_ctrl->IsHidden()) - display_x_ctrl->Show(); - if (display_y_ctrl->IsHidden()) - display_y_ctrl->Show(); - } else { - if (!frameskip_menu->IsHidden()) - frameskip_menu->Hide(); - if (!display_x_ctrl->IsHidden()) - display_x_ctrl->Hide(); - if (!display_y_ctrl->IsHidden()) - display_y_ctrl->Hide(); - if (scr_mode_menu->IsHidden()) - scr_mode_menu->Show(); - } -} - -void PrefsWindow::read_graphics_prefs(void) -{ - char str[64]; - if (display_type == DISPLAY_WINDOW) { - sprintf(str, "win/%d/%d", display_x_ctrl->Value(), display_y_ctrl->Value()); - } else { - sprintf(str, "scr/%d", scr_mode_bit); - } - PrefsReplaceString("screen", str); -} - -BView *PrefsWindow::create_graphics_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - const char *mode_str = PrefsFindString("screen"); - int width = 512, height = 384; - scr_mode_bit = 0; - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1) - display_type = DISPLAY_SCREEN; - } - - BMenuField *menu_field; - BMenuItem *item; - BPopUpMenu *menu; - - menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 5, right, 20), "videotype", GetString(STR_VIDEO_TYPE_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(item = new BMenuItem(GetString(STR_WINDOW_LAB), new BMessage(MSG_VIDEO_WINDOW))); - if (display_type == DISPLAY_WINDOW) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_FULLSCREEN_LAB), new BMessage(MSG_VIDEO_SCREEN))); - if (display_type == DISPLAY_SCREEN) - item->SetMarked(true); - pane->AddChild(menu_field); - - menu = new BPopUpMenu(""); - frameskip_menu = new BMenuField(BRect(10, 26, right, 41), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu); - frameskip_menu->SetDivider(120); - menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); - pane->AddChild(frameskip_menu); - int32 i32 = PrefsFindInt32("frameskip"); - if (i32 == 12) { - if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 8) { - if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 6) { - if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 4) { - if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 2) { - if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) - item->SetMarked(true); - } - - display_x_ctrl = new NumberControl(BRect(10, 48, right / 2, 66), 118, "width", GetString(STR_DISPLAY_X_CTRL), width, NULL); - pane->AddChild(display_x_ctrl); - display_y_ctrl = new NumberControl(BRect(10, 69, right / 2, 87), 118, "height", GetString(STR_DISPLAY_Y_CTRL), height, NULL); - pane->AddChild(display_y_ctrl); - - menu = new BPopUpMenu(""); - scr_mode_menu = new BMenuField(BRect(10, 26, right, 41), "screenmode", GetString(STR_SCREEN_MODE_CTRL), menu); - scr_mode_menu->SetDivider(120); - for (int i=0; scr_mode[i].mode_mask; i++) { - menu->AddItem(item = new BMenuItem(GetString(scr_mode[i].str), new BMessage(MSG_SCREEN_MODE + i))); - if (scr_mode[i].mode_mask & (1 << scr_mode_bit)) - item->SetMarked(true); - } - pane->AddChild(scr_mode_menu); - - nosound_checkbox = new BCheckBox(BRect(10, 90, right, 105), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND)); - pane->AddChild(nosound_checkbox); - nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF); - - hide_show_graphics_ctrls(); - return pane; -} - - -/* - * Create "Serial/Network" pane - */ - -void PrefsWindow::hide_show_serial_ctrls(void) -{ - if (udptunnel_checkbox->Value() == B_CONTROL_ON) { - ether_checkbox->SetEnabled(false); - udpport_ctrl->SetEnabled(true); - } else { - ether_checkbox->SetEnabled(true); - udpport_ctrl->SetEnabled(false); - } -} - -void PrefsWindow::read_serial_prefs(void) -{ - PrefsReplaceInt32("udpport", udpport_ctrl->Value()); -} - -void PrefsWindow::add_serial_names(BPopUpMenu *menu, uint32 msg) -{ - BSerialPort *port = new BSerialPort; - char name[B_PATH_NAME_LENGTH]; - for (int i=0; iCountDevices(); i++) { - port->GetDeviceName(i, name); - menu->AddItem(new BMenuItem(name, new BMessage(msg))); - } - BDirectory dir; - BEntry entry; - dir.SetTo("/dev/parallel"); - if (dir.InitCheck() == B_NO_ERROR) { - dir.Rewind(); - while (dir.GetNextEntry(&entry) >= 0) { - if (!entry.IsDirectory()) { - entry.GetName(name); - menu->AddItem(new BMenuItem(name, new BMessage(msg))); - } - } - } - delete port; -} - -static void set_serial_label(BPopUpMenu *menu, const char *prefs_name) -{ - const char *str; - BMenuItem *item; - if ((str = PrefsFindString(prefs_name)) != NULL) - if ((item = menu->FindItem(str)) != NULL) - item->SetMarked(true); -} - -BView *PrefsWindow::create_serial_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BMenuField *menu_field; - BPopUpMenu *menu_a = new BPopUpMenu(""); - add_serial_names(menu_a, MSG_SER_A); - menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERIALA_CTRL), menu_a); - menu_field->SetDivider(90); - pane->AddChild(menu_field); - set_serial_label(menu_a, "seriala"); - - BPopUpMenu *menu_b = new BPopUpMenu(""); - add_serial_names(menu_b, MSG_SER_B); - menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERIALB_CTRL), menu_b); - menu_field->SetDivider(90); - pane->AddChild(menu_field); - set_serial_label(menu_b, "serialb"); - - ether_checkbox = new BCheckBox(BRect(10, 47, right, 62), "ether", GetString(STR_ETHER_ENABLE_CTRL), new BMessage(MSG_ETHER)); - pane->AddChild(ether_checkbox); - ether_checkbox->SetValue(PrefsFindString("ether") ? B_CONTROL_ON : B_CONTROL_OFF); - - udptunnel_checkbox = new BCheckBox(BRect(10, 67, right, 72), "udptunnel", GetString(STR_UDPTUNNEL_CTRL), new BMessage(MSG_UDPTUNNEL)); - pane->AddChild(udptunnel_checkbox); - udptunnel_checkbox->SetValue(PrefsFindBool("udptunnel") ? B_CONTROL_ON : B_CONTROL_OFF); - - udpport_ctrl = new NumberControl(BRect(10, 87, right / 2, 105), 118, "udpport", GetString(STR_UDPPORT_CTRL), PrefsFindInt32("udpport"), NULL); - pane->AddChild(udpport_ctrl); - - hide_show_serial_ctrls(); - return pane; -} - - -/* - * Create "Memory" pane - */ - -void PrefsWindow::read_memory_prefs(void) -{ - const char *str = rom_control->Text(); - if (strlen(str)) - PrefsReplaceString("rom", str); - else - PrefsRemoveItem("rom"); -} - -BView *PrefsWindow::create_memory_pane(void) -{ - char str[256], str2[256]; - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BEntry entry("/boot/var/swap"); - off_t swap_space; - if (entry.GetSize(&swap_space) == B_NO_ERROR) - max_ramsize = swap_space / (1024 * 1024) - 8; - else - max_ramsize = sys_info.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8; - - int32 value = PrefsFindInt32("ramsize") / (1024 * 1024); - - ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 1, max_ramsize, B_TRIANGLE_THUMB); - ramsize_slider->SetValue(value); - ramsize_slider->UseFillColor(true, &slider_fill_color); - sprintf(str, GetString(STR_RAMSIZE_FMT), 1); - sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize); - ramsize_slider->SetLimitLabels(str, str2); - pane->AddChild(ramsize_slider); - - BMenuField *menu_field; - BMenuItem *item; - BPopUpMenu *menu; - - int id = PrefsFindInt32("modelid"); - menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 60, right, 75), "modelid", GetString(STR_MODELID_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_5_LAB), new BMessage(MSG_MODELID_5))); - if (id == 5) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_14_LAB), new BMessage(MSG_MODELID_14))); - if (id == 14) - item->SetMarked(true); - pane->AddChild(menu_field); - - int cpu = PrefsFindInt32("cpu"); - bool fpu = PrefsFindBool("fpu"); - menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 82, right, 97), "cpu", GetString(STR_CPU_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_LAB), new BMessage(MSG_CPU_68020))); - if (cpu == 2 && !fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_FPU_LAB), new BMessage(MSG_CPU_68020_FPU))); - if (cpu == 2 && fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_LAB), new BMessage(MSG_CPU_68030))); - if (cpu == 3 && !fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_FPU_LAB), new BMessage(MSG_CPU_68030_FPU))); - if (cpu == 3 && fpu) - item->SetMarked(true); - menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68040_LAB), new BMessage(MSG_CPU_68040))); - if (cpu == 4) - item->SetMarked(true); - pane->AddChild(menu_field); - - rom_control = new PathControl(false, BRect(10, 104, right, 119), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL); - rom_control->SetDivider(117); - pane->AddChild(rom_control); - - return pane; -} - - -/* - * Message from controls/menus received - */ - -void PrefsWindow::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case MSG_OK: { // "Start" button clicked - read_volumes_prefs(); - read_memory_prefs(); - read_graphics_prefs(); - SavePrefs(); - send_quit_on_close = false; - PostMessage(B_QUIT_REQUESTED); - be_app->PostMessage(ok_message); - break; - } - - case MSG_CANCEL: // "Quit" button clicked - send_quit_on_close = false; - PostMessage(B_QUIT_REQUESTED); - be_app->PostMessage(B_QUIT_REQUESTED); - break; - - case B_ABOUT_REQUESTED: { // "About" menu item selected - ShowAboutWindow(); - break; - } - - case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected - ZapPRAM(); - break; - - case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag - int selected = volume_list->CurrentSelection(); - if (selected >= 0) { - const char *str = PrefsFindString("disk", selected); - BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); - delete item; - char newstr[256]; - if (str[0] == '*') - strcpy(newstr, str+1); - else { - strcpy(newstr, "*"); - strcat(newstr, str); - } - PrefsReplaceString("disk", newstr, selected); - volume_list->AddItem(new BStringItem(newstr), selected); - volume_list->Select(selected); - } - break; - } - - case MSG_ADD_VOLUME: - add_volume_panel->Show(); - break; - - case MSG_CREATE_VOLUME: - create_volume_panel->Show(); - break; - - case MSG_ADD_VOLUME_PANEL: { - entry_ref ref; - if (msg->FindRef("refs", &ref) == B_NO_ERROR) { - BEntry entry(&ref, true); - BPath path; - entry.GetPath(&path); - if (entry.IsFile()) { - PrefsAddString("disk", path.Path()); - volume_list->AddItem(new BStringItem(path.Path())); - } else if (entry.IsDirectory()) { - BVolume volume; - if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) { - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - if (volume.Device() == info.dev) { - PrefsAddString("disk", info.device_name); - volume_list->AddItem(new BStringItem(info.device_name)); - } - } - } - } - } - break; - } - - case MSG_CREATE_VOLUME_PANEL: { - entry_ref dir; - if (msg->FindRef("directory", &dir) == B_NO_ERROR) { - BEntry entry(&dir, true); - BPath path; - entry.GetPath(&path); - path.Append(msg->FindString("name")); - - create_volume_panel->Window()->Lock(); - BView *background = create_volume_panel->Window()->ChildAt(0); - NumberControl *v = (NumberControl *)background->FindView("hardfile_size"); - int size = v->Value(); - - char cmd[1024]; - sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size); - int ret = system(cmd); - if (ret == 0) { - PrefsAddString("disk", path.Path()); - volume_list->AddItem(new BStringItem(path.Path())); - } else { - sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret)); - WarningAlert(cmd); - } - } - break; - } - - case MSG_REMOVE_VOLUME: { - int selected = volume_list->CurrentSelection(); - if (selected >= 0) { - PrefsRemoveItem("disk", selected); - BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); - delete item; - volume_list->Select(selected); - } - break; - } - - case MSG_BOOT_ANY: - PrefsReplaceInt32("bootdriver", 0); - break; - - case MSG_BOOT_CDROM: - PrefsReplaceInt32("bootdriver", CDROMRefNum); - break; - - case MSG_NOCDROM: - PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_VIDEO_WINDOW: - display_type = DISPLAY_WINDOW; - hide_show_graphics_ctrls(); - break; - - case MSG_VIDEO_SCREEN: - display_type = DISPLAY_SCREEN; - hide_show_graphics_ctrls(); - break; - - case MSG_REF_5HZ: - PrefsReplaceInt32("frameskip", 12); - break; - - case MSG_REF_7_5HZ: - PrefsReplaceInt32("frameskip", 8); - break; - - case MSG_REF_10HZ: - PrefsReplaceInt32("frameskip", 6); - break; - - case MSG_REF_15HZ: - PrefsReplaceInt32("frameskip", 4); - break; - - case MSG_REF_30HZ: - PrefsReplaceInt32("frameskip", 2); - break; - - case MSG_NOSOUND: - PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_SER_A: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - PrefsReplaceString("seriala", source->Label()); - break; - } - - case MSG_SER_B: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - PrefsReplaceString("serialb", source->Label()); - break; - } - - case MSG_ETHER: - if (ether_checkbox->Value() == B_CONTROL_ON) - PrefsReplaceString("ether", "yes"); - else - PrefsRemoveItem("ether"); - break; - - case MSG_UDPTUNNEL: - PrefsReplaceBool("udptunnel", udptunnel_checkbox->Value() == B_CONTROL_ON); - hide_show_serial_ctrls(); - break; - - case MSG_RAMSIZE: - PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024); - break; - - case MSG_MODELID_5: - PrefsReplaceInt32("modelid", 5); - break; - - case MSG_MODELID_14: - PrefsReplaceInt32("modelid", 14); - break; - - case MSG_CPU_68020: - PrefsReplaceInt32("cpu", 2); - PrefsReplaceBool("fpu", false); - break; - - case MSG_CPU_68020_FPU: - PrefsReplaceInt32("cpu", 2); - PrefsReplaceBool("fpu", true); - break; - - case MSG_CPU_68030: - PrefsReplaceInt32("cpu", 3); - PrefsReplaceBool("fpu", false); - break; - - case MSG_CPU_68030_FPU: - PrefsReplaceInt32("cpu", 3); - PrefsReplaceBool("fpu", true); - break; - - case MSG_CPU_68040: - PrefsReplaceInt32("cpu", 4); - PrefsReplaceBool("fpu", true); - break; - - default: { - // Screen mode messages - if ((msg->what & 0xffff0000) == MSG_SCREEN_MODE) { - int m = msg->what & 0xffff; - uint32 mask = scr_mode[m].mode_mask; - for (int i=0; i<32; i++) - if (mask & (1 << i)) - scr_mode_bit = i; - } else - BWindow::MessageReceived(msg); - } - } -} diff --git a/BasiliskII/src/BeOS/scsi_beos.cpp b/BasiliskII/src/BeOS/scsi_beos.cpp deleted file mode 100644 index 75d1e29ad..000000000 --- a/BasiliskII/src/BeOS/scsi_beos.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * scsi_beos.cpp - SCSI Manager, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#ifdef __HAIKU__ -#include -#else -#include -#endif - -#include "sysdeps.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "scsi.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static raw_device_command rdc; - -static int fds[8*8]; // fd's for 8 units and 8 LUNs each -static int fd; // Active fd (selected target) - -static uint32 buffer_size; // Size of data buffer -static uint8 *buffer = NULL; // Pointer to data buffer - -static uint8 sense_data[256]; // Buffer for autosense data - - -/* - * Initialization - */ - -void SCSIInit(void) -{ - int id, lun; - - // Allocate buffer - buffer = (uint8 *)malloc(buffer_size = 0x10000); - - // Open scsi_raw driver for all 8 units (and all 8 LUNs) - char dev_name[256]; - for (id=0; id<8; id++) { - for (lun=0; lun<8; lun++) - fds[id*8+lun] = -1; - char prefs_name[16]; - sprintf(prefs_name, "scsi%d", id); - const char *str = PrefsFindString(prefs_name); - if (str) { - int bus, unit; - if (sscanf(str, "%d/%d", &bus, &unit) == 2) { - for (lun=0; lun<8; lun++) { - sprintf(dev_name, "/dev/bus/scsi/%d/%d/%d/raw", bus, unit, lun); - D(bug("SCSI %d: Opening %s\n", id, dev_name)); - fds[id*8+lun] = open(dev_name, O_RDWR); - } - } - } - } - - // Reset SCSI bus - SCSIReset(); - - // Init rdc - memset(&rdc, 0, sizeof(rdc)); - rdc.data = buffer; - rdc.sense_data = sense_data; -} - - -/* - * Deinitialization - */ - -void SCSIExit(void) -{ - // Close all devices - for (int i=0; i<8; i++) - for (int j=0; j<8; j++) { - int fd = fds[i*8+j]; - if (fd > 0) - close(fd); - } - - // Free buffer - if (buffer) { - free(buffer); - buffer = NULL; - } -} - - -/* - * Check if requested data size fits into buffer, allocate new buffer if needed - */ - -static bool try_buffer(int size) -{ - if (size <= buffer_size) - return true; - - uint8 *new_buffer = (uint8 *)malloc(size); - if (new_buffer == NULL) - return false; - free(buffer); - buffer = new_buffer; - buffer_size = size; - return true; -} - - -/* - * Set SCSI command to be sent by scsi_send_cmd() - */ - -void scsi_set_cmd(int cmd_length, uint8 *cmd) -{ - rdc.command_length = cmd_length; - memcpy(rdc.command, cmd, cmd_length); -} - - -/* - * Check for presence of SCSI target - */ - -bool scsi_is_target_present(int id) -{ - return fds[id * 8] > 0; -} - - -/* - * Set SCSI target (returns false on error) - */ - -bool scsi_set_target(int id, int lun) -{ - int new_fd = fds[id * 8 + lun]; - if (new_fd < 0) - return false; - if (new_fd != fd) - rdc.cam_status &= ~CAM_AUTOSNS_VALID; // Clear sense data when selecting new target - fd = new_fd; - return true; -} - - -/* - * Send SCSI command to active target (scsi_set_command() must have been called), - * read/write data according to S/G table (returns false on error); timeout is in 1/60 sec - */ - -bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout) -{ - // Check if buffer is large enough, allocate new buffer if needed - if (!try_buffer(data_length)) { - char str[256]; - sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length); - ErrorAlert(str); - return false; - } - - // Process S/G table when writing - if (!reading) { - D(bug(" writing to buffer\n")); - uint8 *buffer_ptr = buffer; - for (int i=0; i -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "serial.h" -#include "serial_defs.h" - -#define DEBUG 0 -#include "debug.h" - -#define MONITOR 0 - - -// Buffer size for kernel-space transfers -const int TMP_BUF_SIZE = 2048; - -// These packets are sent to the input/output threads -const uint32 CMD_READ = 'read'; -const uint32 CMD_WRITE = 'writ'; -const uint32 CMD_QUIT = 'quit'; - -struct ThreadPacket { - uint32 pb; -}; - - -// Driver private variables -class BeSERDPort : public SERDPort { -public: - BeSERDPort(const char *dev) - { - device_name = dev; - if (strstr(dev, "parallel")) { - is_parallel = true; - fd = -1; - device = NULL; - } else { - is_parallel = false; - device = new BSerialPort; - } - device_sem = create_sem(1, "serial port"); - input_thread = output_thread = 0; - } - - virtual ~BeSERDPort() - { - status_t l; - if (input_thread > 0) { - send_data(input_thread, CMD_QUIT, NULL, 0); - suspend_thread(input_thread); // Unblock thread - snooze(1000); - resume_thread(input_thread); - while (wait_for_thread(input_thread, &l) == B_INTERRUPTED) ; - } - if (output_thread > 0) { - send_data(output_thread, CMD_QUIT, NULL, 0); - suspend_thread(output_thread); // Unblock thread - snooze(1000); - resume_thread(output_thread); - while (wait_for_thread(output_thread, &l) == B_INTERRUPTED) ; - } - acquire_sem(device_sem); - delete_sem(device_sem); - delete device; - } - - virtual int16 open(uint16 config); - virtual int16 prime_in(uint32 pb, uint32 dce); - virtual int16 prime_out(uint32 pb, uint32 dce); - virtual int16 control(uint32 pb, uint32 dce, uint16 code); - virtual int16 status(uint32 pb, uint32 dce, uint16 code); - virtual int16 close(void); - -private: - bool configure(uint16 config); - void set_handshake(uint32 s, bool with_dtr); - static status_t input_func(void *arg); - static status_t output_func(void *arg); - - const char *device_name; // Name of BeOS port - BSerialPort *device; // BeOS port object - bool is_parallel; // Flag: Port is parallel, use fd - int fd; // FD for parallel ports - sem_id device_sem; // BSerialPort arbitration - - thread_id input_thread; // Data input thread - thread_id output_thread; // Data output thread - - bool io_killed; // Flag: KillIO called, I/O threads must not call deferred tasks - bool drop_dtr_on_close; // Flag: Negate DTR when driver is closed - - uint8 tmp_in_buf[TMP_BUF_SIZE]; // Buffers for copying from/to kernel space - uint8 tmp_out_buf[TMP_BUF_SIZE]; -}; - - -#if DEBUG -static const int baud_rates[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 31250 -}; -#endif - - -/* - * Initialization - */ - -void SerialInit(void) -{ - // Read serial preferences and create structs for both ports - the_serd_port[0] = new BeSERDPort(PrefsFindString("seriala")); - the_serd_port[1] = new BeSERDPort(PrefsFindString("serialb")); -} - - -/* - * Deinitialization - */ - -void SerialExit(void) -{ - delete (BeSERDPort *)the_serd_port[0]; - delete (BeSERDPort *)the_serd_port[1]; -} - - -/* - * Open serial port - */ - -int16 BeSERDPort::open(uint16 config) -{ - // Don't open NULL name devices - if (device_name == NULL) - return openErr; - - // Init variables - io_killed = false; - drop_dtr_on_close = true; - - // Open port - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (is_parallel) { - char name[256]; - sprintf(name, "/dev/parallel/%s", device_name); - fd = ::open(name, O_WRONLY); - if (fd < 0) { - release_sem(device_sem); - return openErr; - } - } else { - device->SetFlowControl(B_HARDWARE_CONTROL); // Must be set before port is opened - if (device->Open(device_name) > 0) { - device->SetBlocking(true); - device->SetTimeout(10000000); - device->SetDTR(true); - device->SetRTS(true); - } else { - release_sem(device_sem); - return openErr; - } - } - - // Start input/output threads - release_sem(device_sem); - configure(config); - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - while ((input_thread = spawn_thread(input_func, "Serial Input", B_NORMAL_PRIORITY, this)) == B_INTERRUPTED) ; - resume_thread(input_thread); - while ((output_thread = spawn_thread(output_func, "Serial Output", B_NORMAL_PRIORITY, this)) == B_INTERRUPTED) ; - resume_thread(output_thread); - release_sem(device_sem); - return noErr; -} - - -/* - * Read data from port - */ - -int16 BeSERDPort::prime_in(uint32 pb, uint32 dce) -{ - // Send input command to input_thread - read_done = false; - read_pending = true; - ThreadPacket p; - p.pb = pb; - WriteMacInt32(input_dt + serdtDCE, dce); - while (send_data(input_thread, CMD_READ, &p, sizeof(ThreadPacket)) == B_INTERRUPTED) ; - return 1; // Command in progress -} - - -/* - * Write data to port - */ - -int16 BeSERDPort::prime_out(uint32 pb, uint32 dce) -{ - // Send output command to output_thread - write_done = false; - write_pending = true; - ThreadPacket p; - p.pb = pb; - WriteMacInt32(output_dt + serdtDCE, dce); - while (send_data(output_thread, CMD_WRITE, &p, sizeof(ThreadPacket)) == B_INTERRUPTED) ; - return 1; // Command in progress -} - - -/* - * Control calls - */ - -int16 BeSERDPort::control(uint32 pb, uint32 dce, uint16 code) -{ - switch (code) { - case 1: // KillIO - io_killed = true; - suspend_thread(input_thread); // Unblock threads - suspend_thread(output_thread); - snooze(1000); - resume_thread(input_thread); - resume_thread(output_thread); - while (read_pending || write_pending) - snooze(10000); - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->ClearInput(); - device->ClearOutput(); - release_sem(device_sem); - } - io_killed = false; - return noErr; - - case kSERDConfiguration: - if (configure(ReadMacInt16(pb + csParam))) - return noErr; - else - return paramErr; - - case kSERDInputBuffer: - return noErr; // Not supported under BeOS - - case kSERDSerHShake: - set_handshake(pb + csParam, false); - return noErr; - - case kSERDClearBreak: - case kSERDSetBreak: - return noErr; // Not supported under BeOS - - case kSERDBaudRate: - if (!is_parallel) { - uint16 rate = ReadMacInt16(pb + csParam); - data_rate baud_rate; - if (rate <= 50) { - rate = 50; baud_rate = B_50_BPS; - } else if (rate <= 75) { - rate = 75; baud_rate = B_75_BPS; - } else if (rate <= 110) { - rate = 110; baud_rate = B_110_BPS; - } else if (rate <= 134) { - rate = 134; baud_rate = B_134_BPS; - } else if (rate <= 150) { - rate = 150; baud_rate = B_150_BPS; - } else if (rate <= 200) { - rate = 200; baud_rate = B_200_BPS; - } else if (rate <= 300) { - rate = 300; baud_rate = B_300_BPS; - } else if (rate <= 600) { - rate = 600; baud_rate = B_600_BPS; - } else if (rate <= 1200) { - rate = 1200; baud_rate = B_1200_BPS; - } else if (rate <= 1800) { - rate = 1800; baud_rate = B_1800_BPS; - } else if (rate <= 2400) { - rate = 2400; baud_rate = B_2400_BPS; - } else if (rate <= 4800) { - rate = 4800; baud_rate = B_4800_BPS; - } else if (rate <= 9600) { - rate = 9600; baud_rate = B_9600_BPS; - } else if (rate <= 19200) { - rate = 19200; baud_rate = B_19200_BPS; - } else if (rate <= 31250) { - rate = 31250; baud_rate = B_31250_BPS; - } else if (rate <= 38400) { - rate = 38400; baud_rate = B_38400_BPS; - } else if (rate <= 57600) { - rate = 57600; baud_rate = B_57600_BPS; - } - WriteMacInt16(pb + csParam, rate); - acquire_sem(device_sem); - if (device->SetDataRate(baud_rate) == B_OK) { - release_sem(device_sem); - return noErr; - } else { - release_sem(device_sem); - return paramErr; - } - } else - return noErr; - - case kSERDHandshake: - case kSERDHandshakeRS232: - set_handshake(pb + csParam, true); - return noErr; - - case kSERDClockMIDI: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetParityMode(B_NO_PARITY); - device->SetDataBits(B_DATA_BITS_8); - device->SetStopBits(B_STOP_BITS_1); - if (device->SetDataRate(B_31250_BPS) == B_OK) { - release_sem(device_sem); - return noErr; - } else { - release_sem(device_sem); - return paramErr; - } - } else - return noErr; - - case kSERDMiscOptions: - drop_dtr_on_close = !(ReadMacInt8(pb + csParam) & kOptionPreserveDTR); - return noErr; - - case kSERDAssertDTR: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetDTR(true); - release_sem(device_sem); - } - return noErr; - - case kSERDNegateDTR: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetDTR(false); - release_sem(device_sem); - } - return noErr; - - case kSERDSetPEChar: - case kSERDSetPEAltChar: - return noErr; // Not supported under BeOS - - case kSERDResetChannel: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->ClearInput(); - device->ClearOutput(); - release_sem(device_sem); - } - return noErr; - - case kSERDAssertRTS: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetRTS(true); - release_sem(device_sem); - } - return noErr; - - case kSERDNegateRTS: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->SetRTS(false); - release_sem(device_sem); - } - return noErr; - - case kSERD115KBaud: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (device->DataRate() != B_115200_BPS) - if (device->SetDataRate(B_115200_BPS) != B_OK) { - release_sem(device_sem); - return paramErr; - } - release_sem(device_sem); - } - return noErr; - - case kSERD230KBaud: - case kSERDSetHighSpeed: - if (!is_parallel) { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (device->DataRate() != B_230400_BPS) - if (device->SetDataRate(B_230400_BPS) != B_OK) { - release_sem(device_sem); - return paramErr; - } - release_sem(device_sem); - } - return noErr; - - default: - printf("WARNING: SerialControl(): unimplemented control code %d\n", code); - return controlErr; - } -} - - -/* - * Status calls - */ - -int16 BeSERDPort::status(uint32 pb, uint32 dce, uint16 code) -{ - switch (code) { - case kSERDInputCount: - WriteMacInt32(pb + csParam, 0); - if (!is_parallel) { - int32 num = 0; - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - device->NumCharsAvailable(&num); - release_sem(device_sem); - D(bug(" %d bytes in buffer\n", num)); - WriteMacInt32(pb + csParam, num); - } - return noErr; - - case kSERDStatus: { - uint32 p = pb + csParam; - WriteMacInt8(p + staCumErrs, cum_errors); - cum_errors = 0; - WriteMacInt8(p + staXOffSent, 0); - WriteMacInt8(p + staXOffHold, 0); - WriteMacInt8(p + staRdPend, read_pending); - WriteMacInt8(p + staWrPend, write_pending); - if (is_parallel) { - WriteMacInt8(p + staCtsHold, 0); - WriteMacInt8(p + staDsrHold, 0); - WriteMacInt8(p + staModemStatus, dsrEvent | dcdEvent | ctsEvent); - } else { - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - WriteMacInt8(p + staCtsHold, !device->IsCTS()); - WriteMacInt8(p + staDsrHold, !device->IsDSR()); - WriteMacInt8(p + staModemStatus, - (device->IsDSR() ? dsrEvent : 0) - | (device->IsRI() ? riEvent : 0) - | (device->IsDCD() ? dcdEvent : 0) - | (device->IsCTS() ? ctsEvent : 0)); - release_sem(device_sem); - } - return noErr; - } - - default: - printf("WARNING: SerialStatus(): unimplemented status code %d\n", code); - return statusErr; - } -} - - -/* - * Close serial port - */ - -int16 BeSERDPort::close() -{ - // Kill threads - status_t l; - io_killed = true; - if (input_thread > 0) { - while (send_data(input_thread, CMD_QUIT, NULL, 0) == B_INTERRUPTED) ; - if (read_pending) { - suspend_thread(input_thread); // Unblock thread - snooze(1000); - resume_thread(input_thread); - } - while (wait_for_thread(input_thread, &l) == B_INTERRUPTED) ; - } - if (output_thread > 0) { - while (send_data(output_thread, CMD_QUIT, NULL, 0) == B_INTERRUPTED) ; - if (write_pending) { - suspend_thread(output_thread); // Unblock thread - snooze(1000); - resume_thread(output_thread); - } - while (wait_for_thread(output_thread, &l) == B_INTERRUPTED) ; - } - input_thread = output_thread = 0; - - // Close port - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (is_parallel) { - ::close(fd); - fd = -1; - } else { - if (drop_dtr_on_close) - device->SetDTR(false); - device->Close(); - } - release_sem(device_sem); - return noErr; -} - - -/* - * Configure serial port with MacOS config word - */ - -bool BeSERDPort::configure(uint16 config) -{ - D(bug(" configure %04x\n", config)); - if (is_parallel) - return true; - - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - - // Set number of stop bits - switch (config & 0xc000) { - case stop10: - if (device->StopBits() != B_STOP_BITS_1) - device->SetStopBits(B_STOP_BITS_1); - break; - case stop20: - if (device->StopBits() != B_STOP_BITS_2) - device->SetStopBits(B_STOP_BITS_2); - break; - default: - release_sem(device_sem); - return false; - } - - // Set parity mode - switch (config & 0x3000) { - case noParity: - if (device->ParityMode() != B_NO_PARITY) - device->SetParityMode(B_NO_PARITY); - break; - case oddParity: - if (device->ParityMode() != B_ODD_PARITY) - device->SetParityMode(B_ODD_PARITY); - break; - case evenParity: - if (device->ParityMode() != B_EVEN_PARITY) - device->SetParityMode(B_EVEN_PARITY); - break; - default: - release_sem(device_sem); - return false; - } - - // Set number of data bits - switch (config & 0x0c00) { - case data7: - if (device->DataBits() != B_DATA_BITS_7) - device->SetDataBits(B_DATA_BITS_7); - break; - case data8: - if (device->DataBits() != B_DATA_BITS_8) - device->SetDataBits(B_DATA_BITS_8); - break; - default: - release_sem(device_sem); - return false; - } - - // Set baud rate - data_rate baud_rate; - switch (config & 0x03ff) { - case baud150: baud_rate = B_150_BPS; break; - case baud300: baud_rate = B_300_BPS; break; - case baud600: baud_rate = B_600_BPS; break; - case baud1200: baud_rate = B_1200_BPS; break; - case baud1800: baud_rate = B_1800_BPS; break; - case baud2400: baud_rate = B_2400_BPS; break; - case baud4800: baud_rate = B_4800_BPS; break; - case baud9600: baud_rate = B_9600_BPS; break; - case baud19200: baud_rate = B_19200_BPS; break; - case baud38400: baud_rate = B_38400_BPS; break; - case baud57600: baud_rate = B_57600_BPS; break; - default: - release_sem(device_sem); - return false; - } - - D(bug(" baud rate %d, %d stop bits, %s parity, %d data bits\n", baud_rates[baud_rate], device->StopBits() == B_STOP_BITS_1 ? 1 : 2, device->ParityMode() == B_NO_PARITY ? "no" : device->ParityMode() == B_ODD_PARITY ? "odd" : "even", device->DataBits() == B_DATA_BITS_7 ? 7 : 8)); - if (device->DataRate() != baud_rate) { - bool res = device->SetDataRate(baud_rate) == B_OK; - release_sem(device_sem); - return res; - } else { - release_sem(device_sem); - return true; - } -} - - -/* - * Set serial handshaking - */ - -void BeSERDPort::set_handshake(uint32 s, bool with_dtr) -{ - D(bug(" set_handshake %02x %02x %02x %02x %02x %02x %02x %02x\n", - ReadMacInt8(s + 0), ReadMacInt8(s + 1), ReadMacInt8(s + 2), ReadMacInt8(s + 3), - ReadMacInt8(s + 4), ReadMacInt8(s + 5), ReadMacInt8(s + 6), ReadMacInt8(s + 7))); - if (is_parallel) - return; - - uint32 flow; - if (with_dtr) { - if (ReadMacInt8(s + shkFCTS) || ReadMacInt8(s + shkFDTR)) - flow = B_HARDWARE_CONTROL; - else - flow = B_SOFTWARE_CONTROL; - } else { - if (ReadMacInt8(s + shkFCTS)) - flow = B_HARDWARE_CONTROL; - else - flow = B_SOFTWARE_CONTROL; - } - - D(bug(" %sware flow control\n", flow == B_HARDWARE_CONTROL ? "hard" : "soft")); - while (acquire_sem(device_sem) == B_INTERRUPTED) ; - if (device->FlowControl() != flow) { - device->Close(); - device->SetFlowControl(flow); - device->Open(device_name); - } - release_sem(device_sem); -} - - -/* - * Data input thread - */ - -status_t BeSERDPort::input_func(void *arg) -{ - BeSERDPort *s = (BeSERDPort *)arg; - for (;;) { - - // Wait for commands - thread_id sender; - ThreadPacket p; - uint32 code = receive_data(&sender, &p, sizeof(ThreadPacket)); - if (code == CMD_QUIT) - break; - if (code != CMD_READ) - continue; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer)); - uint32 length = ReadMacInt32(p.pb + ioReqCount); - D(bug("input_func waiting for %ld bytes of data...\n", length)); - int32 actual; - - // Buffer in kernel space? - if ((uint32)buf < 0x80000000) { - - // Yes, transfer via buffer - actual = 0; - while (length) { - uint32 transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - int32 transferred; - acquire_sem(s->device_sem); - if (s->is_parallel) { - if ((transferred = read(s->fd, s->tmp_in_buf, transfer_size)) < 0 || s->io_killed) { - // Error - actual = transferred; - release_sem(s->device_sem); - break; - } - } else { - if ((transferred = s->device->Read(s->tmp_in_buf, transfer_size)) < 0 || s->io_killed) { - // Error - actual = transferred; - release_sem(s->device_sem); - break; - } - } - release_sem(s->device_sem); - memcpy(buf, s->tmp_in_buf, transferred); - buf = (void *)((uint8 *)buf + transferred); - length -= transferred; - actual += transferred; - } - - } else { - - // No, transfer directly - acquire_sem(s->device_sem); - if (s->is_parallel) - actual = read(s->fd, buf, length); - else - actual = s->device->Read(buf, length); - release_sem(s->device_sem); - } - - D(bug(" %ld bytes received\n", actual)); - -#if MONITOR - bug("Receiving serial data:\n"); - uint8 *adr = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer)); - for (int i=0; iio_killed) { - - WriteMacInt16(p.pb + ioResult, abortErr); - WriteMacInt32(p.pb + ioActCount, 0); - s->read_pending = s->read_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(p.pb + ioActCount, actual); - WriteMacInt32(s->input_dt + serdtResult, noErr); - } else { - WriteMacInt32(p.pb + ioActCount, 0); - WriteMacInt32(s->input_dt + serdtResult, readErr); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\n")); - s->read_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - return 0; -} - - -/* - * Data output thread - */ - -status_t BeSERDPort::output_func(void *arg) -{ - BeSERDPort *s = (BeSERDPort *)arg; - for (;;) { - - // Wait for commands - thread_id sender; - ThreadPacket p; - uint32 code = receive_data(&sender, &p, sizeof(ThreadPacket)); - if (code == CMD_QUIT) - break; - if (code != CMD_WRITE) - continue; - - // Execute command - void *buf = Mac2HostAddr(ReadMacInt32(p.pb + ioBuffer)); - uint32 length = ReadMacInt32(p.pb + ioReqCount); - D(bug("output_func transmitting %ld bytes of data...\n", length)); - int32 actual; - -#if MONITOR - bug("Sending serial data:\n"); - uint8 *adr = (uint8 *)buf; - for (int i=0; i TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - memcpy(s->tmp_out_buf, buf, transfer_size); - int32 transferred; - acquire_sem(s->device_sem); - if (s->is_parallel) { - if ((transferred = write(s->fd, s->tmp_out_buf, transfer_size)) < transfer_size || s->io_killed) { - if (transferred < 0) // Error - actual = transferred; - else - actual += transferred; - release_sem(s->device_sem); - break; - } - } else { - if ((transferred = s->device->Write(s->tmp_out_buf, transfer_size)) < transfer_size || s->io_killed) { - if (transferred < 0) // Error - actual = transferred; - else - actual += transferred; - release_sem(s->device_sem); - break; - } - } - release_sem(s->device_sem); - if (transferred > transfer_size) // R3 parallel port driver bug - transferred = transfer_size; - buf = (void *)((uint8 *)buf + transferred); - length -= transferred; - actual += transferred; - } - - } else { - - // No, transfer directly - acquire_sem(s->device_sem); - if (s->is_parallel) - actual = write(s->fd, buf, length); - else - actual = s->device->Write(buf, length); - release_sem(s->device_sem); - if (actual > length) // R3 parallel port driver bug - actual = length; - } - - D(bug(" %ld bytes transmitted\n", actual)); - - // KillIO called? Then simply return - if (s->io_killed) { - - WriteMacInt16(p.pb + ioResult, abortErr); - WriteMacInt32(p.pb + ioActCount, 0); - s->write_pending = s->write_done = false; - - } else { - - // Set error code - if (actual >= 0) { - WriteMacInt32(p.pb + ioActCount, actual); - WriteMacInt32(s->output_dt + serdtResult, noErr); - } else { - WriteMacInt32(p.pb + ioActCount, 0); - WriteMacInt32(s->output_dt + serdtResult, writErr); - } - - // Trigger serial interrupt - D(bug(" triggering serial interrupt\n")); - s->write_done = true; - SetInterruptFlag(INTFLAG_SERIAL); - TriggerInterrupt(); - } - } - return 0; -} diff --git a/BasiliskII/src/BeOS/sys_beos.cpp b/BasiliskII/src/BeOS/sys_beos.cpp deleted file mode 100644 index ff6fcb830..000000000 --- a/BasiliskII/src/BeOS/sys_beos.cpp +++ /dev/null @@ -1,841 +0,0 @@ -/* - * sys_beos.cpp - System dependent routines, BeOS implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "sys.h" - -#define DEBUG 0 -#include "debug.h" - -#ifdef __HAIKU__ -#include -#define unmount(x) fs_unmount_volume(x, 0) -#endif - - -// File handles are pointers to these structures -struct file_handle { - file_handle *next; // Pointer to next file handle (must be first in struct!) - const char *name; // File/device name (copied, for mount menu) - int fd; // fd of file/device - bool is_file; // Flag: plain file or /dev/something? - bool read_only; // Copy of Sys_open() flag - loff_t start_byte; // Size of file header (if any) - loff_t file_size; // Size of file data (only valid if is_file is true) -}; - -// Linked list of file handles -static file_handle *first_file_handle; - -// Temporary buffer for transfers from/to kernel space -const int TMP_BUF_SIZE = 0x10000; -static uint8 *tmp_buf; - -// For B_SCSI_PREVENT_ALLOW -static const int32 PREVENT = 1; -static const int32 ALLOW = 0; - - -/* - * Check if device is a mounted HFS volume, get mount name - */ - -static bool is_drive_mounted(const char *dev_name, char *mount_name) -{ - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - if (strcmp(dev_name, info.device_name) == 0) { - status_t err = -1; - BPath mount; - BDirectory dir; - BEntry entry; - node_ref node; - node.device = info.dev; - node.node = info.root; - err = dir.SetTo(&node); - if (!err) - err = dir.GetEntry(&entry); - if (!err) - err = entry.GetPath(&mount); - if (!err) { - strcpy(mount_name, mount.Path()); - return true; - } - } - } - return false; -} - - -/* - * Initialization - */ - -void SysInit(void) -{ - first_file_handle = NULL; - - // Allocate temporary buffer - tmp_buf = new uint8[TMP_BUF_SIZE]; -} - - -/* - * Deinitialization - */ - -void SysExit(void) -{ - delete[] tmp_buf; -} - - -/* - * Create menu of used volumes (for "mount" menu) - */ - -void SysCreateVolumeMenu(BMenu *menu, uint32 msg) -{ - for (file_handle *fh=first_file_handle; fh; fh=fh->next) - if (!SysIsFixedDisk(fh)) - menu->AddItem(new BMenuItem(fh->name, new BMessage(msg))); -} - - -/* - * Mount volume given name from mount menu - */ - -void SysMountVolume(const char *name) -{ - file_handle *fh; - for (fh=first_file_handle; fh && strcmp(fh->name, name); fh=fh->next) ; - if (fh) - MountVolume(fh); -} - - -/* - * This gets called when no "floppy" prefs items are found - * It scans for available floppy drives and adds appropriate prefs items - */ - -void SysAddFloppyPrefs(void) -{ - // Only one floppy drive under BeOS - PrefsAddString("floppy", "/dev/disk/floppy/raw"); -} - - -/* - * This gets called when no "disk" prefs items are found - * It scans for available HFS volumes and adds appropriate prefs items - */ - -void SysAddDiskPrefs(void) -{ - // Let BeOS scan for HFS drives - D(bug("Looking for Mac volumes...\n")); - system("mountvolume -allhfs"); - - // Add all HFS volumes - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - status_t err = -1; - BPath mount; - if (!strcmp(info.fsh_name, "hfs")) { - BDirectory dir; - BEntry entry; - node_ref node; - node.device = info.dev; - node.node = info.root; - err = dir.SetTo(&node); - if (!err) - err = dir.GetEntry(&entry); - if (!err) - err = entry.GetPath(&mount); - } - if (!err) - err = unmount(mount.Path()); - if (!err) { - char dev_name[B_FILE_NAME_LENGTH]; - if (info.flags & B_FS_IS_READONLY) { - dev_name[0] = '*'; - dev_name[1] = 0; - } else - dev_name[0] = 0; - strcat(dev_name, info.device_name); - PrefsAddString("disk", dev_name); - } - } -} - - -/* - * This gets called when no "cdrom" prefs items are found - * It scans for available CD-ROM drives and adds appropriate prefs items - */ - -// Scan directory for CD-ROM drives, add them to prefs -static void scan_for_cdrom_drives(const char *directory) -{ - // Set directory - BDirectory dir; - dir.SetTo(directory); - if (dir.InitCheck() != B_NO_ERROR) - return; - dir.Rewind(); - - // Scan each entry - BEntry entry; - while (dir.GetNextEntry(&entry) >= 0) { - - // Get path and ref for entry - BPath path; - if (entry.GetPath(&path) != B_NO_ERROR) - continue; - const char *name = path.Path(); - entry_ref e; - if (entry.GetRef(&e) != B_NO_ERROR) - continue; - - // Recursively enter subdirectories (except for floppy) - if (entry.IsDirectory()) { - if (!strcmp(e.name, "floppy")) - continue; - scan_for_cdrom_drives(name); - } else { - - D(bug(" checking '%s'\n", name)); - - // Ignore partitions - if (strcmp(e.name, "raw")) - continue; - - // Open device - int fd = open(name, O_RDONLY); - if (fd < 0) - continue; - - // Get geometry and device type - device_geometry g; - if (ioctl(fd, B_GET_GEOMETRY, &g, sizeof(g)) < 0) { - close(fd); - continue; - } - - // Insert to list if it is a CD drive - if (g.device_type == B_CD) - PrefsAddString("cdrom", name); - close(fd); - } - } -} - -void SysAddCDROMPrefs(void) -{ - // Don't scan for drives if nocdrom option given - if (PrefsFindBool("nocdrom")) - return; - - // Look for CD-ROM drives and add prefs items - D(bug("Looking for CD-ROM drives...\n")); - scan_for_cdrom_drives("/dev/disk"); -} - - -/* - * Add default serial prefs (must be added, even if no ports present) - */ - -void SysAddSerialPrefs(void) -{ -#ifdef __HAIKU__ - PrefsAddString("seriala", "serial1"); - PrefsAddString("serialb", "serial2"); -#else - system_info info; - get_system_info(&info); - switch (info.platform_type) { - case B_BEBOX_PLATFORM: - case B_AT_CLONE_PLATFORM: - PrefsAddString("seriala", "serial1"); - PrefsAddString("serialb", "serial2"); - break; - case B_MAC_PLATFORM: - PrefsAddString("seriala", "modem"); - PrefsAddString("serialb", "printer"); - break; - default: - PrefsAddString("seriala", "none"); - PrefsAddString("serialb", "none"); - break; - } -#endif -} - - -/* - * Open file/device, create new file handle (returns NULL on error) - */ - -void *Sys_open(const char *name, bool read_only) -{ - static bool published_all = false; - bool is_file = (strstr(name, "/dev/") != name); - - D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write")); - - // Print warning message and eventually unmount drive when this is an HFS volume mounted under BeOS (double mounting will corrupt the volume) - char mount_name[B_FILE_NAME_LENGTH]; - if (!is_file && !read_only && is_drive_mounted(name, mount_name)) { - char str[256 + B_FILE_NAME_LENGTH]; - sprintf(str, GetString(STR_VOLUME_IS_MOUNTED_WARN), mount_name); - WarningAlert(str); - if (unmount(mount_name) != 0) { - sprintf(str, GetString(STR_CANNOT_UNMOUNT_WARN), mount_name); - WarningAlert(str); - return NULL; - } - } - - int fd = open(name, read_only ? O_RDONLY : O_RDWR); - if (fd < 0 && !published_all) { - // Open failed, create all device nodes and try again, but only the first time - system("mountvolume -publishall"); - published_all = true; - fd = open(name, read_only ? O_RDONLY : O_RDWR); - } - if (fd >= 0) { - file_handle *fh = new file_handle; - fh->name = strdup(name); - fh->fd = fd; - fh->is_file = is_file; - fh->read_only = read_only; - fh->start_byte = 0; - if (fh->is_file) { - // Detect disk image file layout - loff_t size = lseek(fd, 0, SEEK_END); - uint8 data[256]; - lseek(fd, 0, SEEK_SET); - read(fd, data, 256); - FileDiskLayout(size, data, fh->start_byte, fh->file_size); - } - - // Enqueue file handle - fh->next = NULL; - file_handle *q = first_file_handle; - if (q) { - while (q->next) - q = q->next; - q->next = fh; - } else - first_file_handle = fh; - return fh; - } else - return NULL; -} - - -/* - * Close file/device, delete file handle - */ - -void Sys_close(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - // Free device name and close file/device - free((void *)fh->name); - close(fh->fd); - - // Dequeue file handle - file_handle *q = first_file_handle; - if (q == fh) { - first_file_handle = NULL; - delete fh; - return; - } - while (q) { - if (q->next == fh) { - q->next = fh->next; - delete fh; - return; - } - q = q->next; - } -} - - -/* - * Read "length" bytes from file/device, starting at "offset", to "buffer", - * returns number of bytes read (or 0) - */ - -static inline ssize_t sread(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = read(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return 0; - -// D(bug("Sys_read(%08lx, %08lx, %Ld, %d)\n", fh, buffer, offset, length)); - - // Seek to position - if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0) - return 0; - - // Buffer in kernel space? - size_t actual = 0; - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - if (sread(fh->fd, tmp_buf, transfer_size) != transfer_size) - return actual; - memcpy(buffer, tmp_buf, transfer_size); - buffer = (void *)((uint8 *)buffer + transfer_size); - length -= transfer_size; - actual += transfer_size; - } - - } else { - - // No, transfer directly - actual = sread(fh->fd, buffer, length); - if (actual < 0) - actual = 0; - } - return actual; -} - - -/* - * Write "length" bytes from "buffer" to file/device, starting at "offset", - * returns number of bytes written (or 0) - */ - -static inline ssize_t swrite(int fd, void *buf, size_t count) -{ - ssize_t res; - while ((res = write(fd, buf, count)) == B_INTERRUPTED) ; - return res; -} - -size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return 0; - -// D(bug("Sys_write(%08lx, %08lx, %Ld, %d)\n", fh, buffer, offset, length)); - - // Seek to position - if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0) - return 0; - - // Buffer in kernel space? - size_t actual = 0; - if ((uint32)buffer < 0x80000000) { - - // Yes, transfer via buffer - while (length) { - size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length; - memcpy(tmp_buf, buffer, transfer_size); - if (swrite(fh->fd, tmp_buf, transfer_size) != transfer_size) - return actual; - buffer = (void *)((uint8 *)buffer + transfer_size); - length -= transfer_size; - actual += transfer_size; - } - - } else { - - // No, transfer directly - actual = swrite(fh->fd, buffer, length); - if (actual < 0) - actual = 0; - } - return actual; -} - - -/* - * Return size of file/device (minus header) - */ - -loff_t SysGetFileSize(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) - return fh->file_size; - else { - device_geometry g; - if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) - return (loff_t)g.bytes_per_sector * g.sectors_per_track * g.cylinder_count * g.head_count; - else - return 0; - } -} - - -/* - * Eject volume (if applicable) - */ - -void SysEject(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) - ioctl(fh->fd, B_EJECT_DEVICE); -} - - -/* - * Format volume (if applicable) - */ - -bool SysFormat(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) - return ioctl(fh->fd, B_FORMAT_DEVICE) >= 0; - else - return false; -} - - -/* - * Check if file/device is read-only (this includes the read-only flag on Sys_open()) - */ - -bool SysIsReadOnly(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) { - - // File, return flag given to Sys_open - return fh->read_only; - - } else { - - // Device, check write protection - device_geometry g; - if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) - return g.read_only | fh->read_only; - else - return fh->read_only; // Removable but not inserted - } -} - - -/* - * Check if the given file handle refers to a fixed or a removable disk - */ - -bool SysIsFixedDisk(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (fh->is_file) - return true; - else { - device_geometry g; - if (ioctl(fh->fd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) - return !g.removable; - else - return false; // Removable but not inserted - } -} - - -/* - * Check if a disk is inserted in the drive (always true for files) - */ - -bool SysIsDiskInserted(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (fh->is_file) - return true; - else { - status_t l; - if (ioctl(fh->fd, B_GET_MEDIA_STATUS, &l, sizeof(l)) >= 0 && l == B_NO_ERROR) - return true; - else - return false; - } -} - - -/* - * Prevent medium removal (if applicable) - */ - -void SysPreventRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) - ioctl(fh->fd, B_SCSI_PREVENT_ALLOW, &PREVENT, sizeof(PREVENT)); -} - - -/* - * Allow medium removal (if applicable) - */ - -void SysAllowRemoval(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) - ioctl(fh->fd, B_SCSI_PREVENT_ALLOW, &ALLOW, sizeof(ALLOW)); -} - - -/* - * Read CD-ROM TOC (binary MSF format, 804 bytes max.) - */ - -bool SysCDReadTOC(void *arg, uint8 *toc) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - memset(tmp_buf, 0, 804); - if (ioctl(fh->fd, B_SCSI_GET_TOC, tmp_buf, 804) < 0) - return false; - memcpy(toc, tmp_buf, 804); - return true; - } else - return false; -} - - -/* - * Read CD-ROM position data (Sub-Q Channel, 16 bytes, see SCSI standard) - */ - -bool SysCDGetPosition(void *arg, uint8 *pos) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - if (ioctl(fh->fd, B_SCSI_GET_POSITION, tmp_buf, 16) < 0) - return false; - memcpy(pos, tmp_buf, 16); - return true; - } else - return false; -} - - -/* - * Play CD audio - */ - -bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - scsi_play_position *p = (scsi_play_position *)tmp_buf; - p->start_m = start_m; - p->start_s = start_s; - p->start_f = start_f; - p->end_m = end_m; - p->end_s = end_s; - p->end_f = end_f; - return ioctl(fh->fd, B_SCSI_PLAY_POSITION, p, sizeof(scsi_play_position)) == 0; - } else - return false; -} - - -/* - * Pause CD audio - */ - -bool SysCDPause(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return true; - - if (!fh->is_file) - return ioctl(fh->fd, B_SCSI_PAUSE_AUDIO) == 0; - else - return false; -} - - -/* - * Resume paused CD audio - */ - -bool SysCDResume(void *arg) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) - return ioctl(fh->fd, B_SCSI_RESUME_AUDIO) == 0; - else - return false; -} - - -/* - * Stop CD audio - */ - -bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) - return ioctl(fh->fd, B_SCSI_STOP_AUDIO) == 0; - else - return false; -} - - -/* - * Perform CD audio fast-forward/fast-reverse operation starting from specified address - */ - -bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return false; - - if (!fh->is_file) { - scsi_scan *p = (scsi_scan *)tmp_buf; - p->speed = 0; - p->direction = reverse ? -1 : 1; - return ioctl(fh->fd, B_SCSI_SCAN, p, sizeof(scsi_scan)) == 0; - } else - return false; -} - - -/* - * Set CD audio volume (0..255 each channel) - */ - -void SysCDSetVolume(void *arg, uint8 left, uint8 right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - if (!fh->is_file) { - scsi_volume *p = (scsi_volume *)tmp_buf; - p->flags = B_SCSI_PORT0_VOLUME | B_SCSI_PORT1_VOLUME; - p->port0_volume = left; - p->port1_volume = right; - ioctl(fh->fd, B_SCSI_SET_VOLUME, p, sizeof(scsi_volume)); - } -} - - -/* - * Get CD audio volume (0..255 each channel) - */ - -void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) -{ - file_handle *fh = (file_handle *)arg; - if (!fh) - return; - - left = right = 0; - if (!fh->is_file) { - scsi_volume *p = (scsi_volume *)tmp_buf; - p->flags = B_SCSI_PORT0_VOLUME | B_SCSI_PORT1_VOLUME; - if (ioctl(fh->fd, B_SCSI_GET_VOLUME, p, sizeof(scsi_volume)) == 0) { - left = p->port0_volume; - right = p->port1_volume; - } - } -} diff --git a/BasiliskII/src/BeOS/sysdeps.h b/BasiliskII/src/BeOS/sysdeps.h deleted file mode 100644 index ed3ba9c33..000000000 --- a/BasiliskII/src/BeOS/sysdeps.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * sysdeps.h - System dependent definitions for BeOS - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SYSDEPS_H -#define SYSDEPS_H - -#ifdef __POWERPC__ -#define NO_STD_NAMESPACE -#endif - -#include -#include -#include - -#include "user_strings_beos.h" - -// Are the Mac and the host address space the same? -#ifdef __i386__ -#define REAL_ADDRESSING 0 -#undef WORDS_BIGENDIAN -#else -#define REAL_ADDRESSING 1 -#define WORDS_BIGENDIAN 1 -#endif - -// Using 68k emulator -#define EMULATED_68K 1 - -// Mac ROM is write protected -#define ROM_IS_WRITE_PROTECTED 1 - -// ExtFS is supported -#define SUPPORTS_EXTFS 1 - -// BSD socket API is supported -#define SUPPORTS_UDP_TUNNEL 1 - -// mon is not supported -#undef ENABLE_MON - -// Time data type for Time Manager emulation -typedef bigtime_t tm_time_t; - -// 64 bit file offsets -typedef off_t loff_t; - -// Networking types -#define PF_INET AF_INET -#ifndef __HAIKU__ -typedef int socklen_t; -#endif - -// UAE CPU data types -#define uae_s8 int8 -#define uae_u8 uint8 -#define uae_s16 int16 -#define uae_u16 uint16 -#define uae_s32 int32 -#define uae_u32 uint32 -#define uae_s64 int64 -#define uae_u64 uint64 -typedef uae_u32 uaecptr; -#define VAL64(a) (a ## LL) -#define UVAL64(a) (a ## uLL) -typedef uint32 uintptr; -typedef int32 intptr; - -/* Timing functions */ -extern void Delay_usec(uint32 usec); - -// UAE CPU defines -#ifdef __i386__ - -// Intel x86 assembler optimizations -#define X86_PPRO_OPT -static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint32 retval; __asm__ ("bswap %0" : "=r" (retval) : "0" (*a) : "cc"); return retval;} -#ifdef X86_PPRO_OPT -static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("movzwl %w1,%k0\n\tshll $16,%k0\n\tbswap %k0\n" : "=&r" (retval) : "m" (*a) : "cc"); return retval;} -#else -static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("xorl %k0,%k0\n\tmovw %w1,%w0\n\trolw $8,%w0" : "=&r" (retval) : "m" (*a) : "cc"); return retval;} -#endif -#define HAVE_GET_WORD_UNSWAPPED -#define do_get_mem_word_unswapped(a) ((uae_u32)*((uae_u16 *)(a))) -static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v) : "cc"); *a = v;} -#ifdef X86_PPRO_OPT -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("bswap %0" : "=&r" (v) : "0" (v << 16) : "cc"); *a = v;} -#else -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); *a = v;} -#endif - -#define X86_ASSEMBLY -#define UNALIGNED_PROFITABLE -#define OPTIMIZED_FLAGS -#define ASM_SYM(a) __asm__(a) -#define REGPARAM __attribute__((regparm(3))) - -#else - -// PowerPC (memory.cpp not used, so no optimization neccessary) -static inline uae_u32 do_get_mem_long(uae_u32 *a) {return *a;} -static inline uae_u32 do_get_mem_word(uae_u16 *a) {return *a;} -static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {*a = v;} -static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = v;} - -#undef X86_ASSEMBLY -#define UNALIGNED_PROFITABLE -#undef OPTIMIZED_FLAGS -#define ASM_SYM(a) -#define REGPARAM -#endif - -#define do_get_mem_byte(a) ((uae_u32)*((uae_u8 *)(a))) -#define do_put_mem_byte(a, v) (*(uae_u8 *)(a) = (v)) - -#define call_mem_get_func(func, addr) ((*func)(addr)) -#define call_mem_put_func(func, addr, v) ((*func)(addr, v)) -#define __inline__ inline -#define CPU_EMU_SIZE 0 -#undef NO_INLINE_MEMORY_ACCESS -#undef MD_HAVE_MEM_1_FUNCS -#undef USE_COMPILER -#define REGPARAM2 -#define ENUMDECL typedef enum -#define ENUMNAME(name) name -#define write_log printf - -#endif diff --git a/BasiliskII/src/BeOS/timer_beos.cpp b/BasiliskII/src/BeOS/timer_beos.cpp deleted file mode 100644 index f6e71b506..000000000 --- a/BasiliskII/src/BeOS/timer_beos.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * timer_beos.cpp - Time Manager emulation, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "sysdeps.h" -#include "macos_util.h" -#include "timer.h" - -#define DEBUG 0 -#include "debug.h" - - -// From main_beos.cpp -extern thread_id emul_thread; - - -/* - * Return microseconds since boot (64 bit) - */ - -void Microseconds(uint32 &hi, uint32 &lo) -{ - D(bug("Microseconds\n")); - bigtime_t time = system_time(); - hi = time >> 32; - lo = time; -} - - -/* - * Return local date/time in Mac format (seconds since 1.1.1904) - */ - -uint32 TimerDateTime(void) -{ - return TimeToMacTime(time(NULL)); -} - - -/* - * Get current time - */ - -void timer_current_time(tm_time_t &t) -{ - t = system_time(); -} - - -/* - * Add times - */ - -void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a + b; -} - - -/* - * Subtract times - */ - -void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b) -{ - res = a - b; -} - - -/* - * Compare times (<0: a < b, =0: a = b, >0: a > b) - */ - -int timer_cmp_time(tm_time_t a, tm_time_t b) -{ - tm_time_t r = a - b; - return r < 0 ? -1 : (r > 0 ? 1 : 0); -} - - -/* - * Convert Mac time value (>0: microseconds, <0: microseconds) to tm_time_t - */ - -void timer_mac2host_time(tm_time_t &res, int32 mactime) -{ - if (mactime > 0) - res = mactime * 1000; // Time in milliseconds - else - res = -mactime; // Time in negative microseconds -} - - -/* - * Convert positive tm_time_t to Mac time value (>0: microseconds, <0: microseconds) - * A negative input value for hosttime results in a zero return value - * As long as the microseconds value fits in 32 bit, it must not be converted to milliseconds! - */ - -int32 timer_host2mac_time(tm_time_t hosttime) -{ - if (hosttime < 0) - return 0; - else if (hosttime > 0x7fffffff) - return hosttime / 1000; // Time in milliseconds - else - return -hosttime; // Time in negative microseconds -} - - -/* - * Delay by specified number of microseconds (<1 second) - */ - -void Delay_usec(uint32 usec) -{ - snooze(usec); -} - - -/* - * Suspend emulator thread, virtual CPU in idle mode - */ - -void idle_wait(void) -{ -#if 0 - /* - FIXME: add a semaphore (counter) to avoid a B_BAD_THREAD_STATE - return if we call idle_resume() when thread is not suspended? - - Sorry, I can't test -- gb. - */ - suspend_thread(emul_thread); -#endif -} - - -/* - * Resume execution of emulator thread, events just arrived - */ - -void idle_resume(void) -{ -#if 0 - resume_thread(emul_thread); -#endif -} diff --git a/BasiliskII/src/BeOS/user_strings_beos.cpp b/BasiliskII/src/BeOS/user_strings_beos.cpp deleted file mode 100644 index c3694578e..000000000 --- a/BasiliskII/src/BeOS/user_strings_beos.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * user_strings_beos.cpp - BeOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "user_strings.h" - - -// Platform-specific string definitions -user_string_def platform_strings[] = { - // Common strings that have a platform-specific variant - {STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under BeOS. Basilisk II will try to unmount it."}, - {STR_EXTFS_CTRL, "BeOS Root"}, - {STR_EXTFS_NAME, "BeOS Directory Tree"}, - {STR_EXTFS_VOLUME_NAME, "BeOS"}, - - // Purely platform-specific strings - {STR_NO_SHEEP_DRIVER_ERR, "Cannot open /dev/sheep: %s (%08x). Basilisk II is not properly installed."}, - {STR_SHEEP_UP_ERR, "Cannot allocate Low Memory Globals: %s (%08x)."}, - {STR_NO_KERNEL_DATA_ERR, "Cannot create Kernel Data area: %s (%08x)."}, - {STR_NO_NET_ADDON_WARN, "The SheepShaver net server add-on cannot be found. Ethernet will not be available."}, - {STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for Basilisk II, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under Basilisk II)?."}, - {STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."}, - {STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."}, - {STR_VIDEO_FAILED, "Failed to set video mode."}, - - {-1, NULL} // End marker -}; - - -/* - * Fetch pointer to string, given the string number - */ - -const char *GetString(int num) -{ - // First search for platform-specific string - int i = 0; - while (platform_strings[i].num >= 0) { - if (platform_strings[i].num == num) - return platform_strings[i].str; - i++; - } - - // Not found, search for common string - i = 0; - while (common_strings[i].num >= 0) { - if (common_strings[i].num == num) - return common_strings[i].str; - i++; - } - return NULL; -} diff --git a/BasiliskII/src/BeOS/user_strings_beos.h b/BasiliskII/src/BeOS/user_strings_beos.h deleted file mode 100644 index 8de695e93..000000000 --- a/BasiliskII/src/BeOS/user_strings_beos.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * user_strings_beos.h - BeOS-specific localizable strings - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USER_STRINGS_BEOS_H -#define USER_STRINGS_BEOS_H - -enum { - STR_NO_SHEEP_DRIVER_ERR = 10000, - STR_SHEEP_UP_ERR, - STR_NO_KERNEL_DATA_ERR, - STR_NO_NET_ADDON_WARN, - STR_NET_CONFIG_MODIFY_WARN, - STR_NET_ADDON_INIT_FAILED, - STR_NET_ADDON_CLONE_FAILED, - STR_VIDEO_FAILED -}; - -#endif diff --git a/BasiliskII/src/BeOS/video_beos.cpp b/BasiliskII/src/BeOS/video_beos.cpp deleted file mode 100644 index d70ad834b..000000000 --- a/BasiliskII/src/BeOS/video_beos.cpp +++ /dev/null @@ -1,1086 +0,0 @@ -/* - * video_beos.cpp - Video/graphics emulation, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * Portions written by Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "macos_util.h" -#include "prefs.h" -#include "adb.h" -#include "prefs.h" -#include "user_strings.h" -#include "about_window.h" -#include "video.h" - -#include "m68k.h" -#include "memory.h" -#include "readcpu.h" -#include "newcpu.h" - -#define DEBUG 0 -#include "debug.h" - -#define DEBUGGER_AVAILABLE 0 - - -// Messages -const uint32 MSG_REDRAW = 'draw'; -const uint32 MSG_ABOUT_REQUESTED = B_ABOUT_REQUESTED; -const uint32 MSG_REF_5HZ = ' 5Hz'; -const uint32 MSG_REF_7_5HZ = ' 7Hz'; -const uint32 MSG_REF_10HZ = '10Hz'; -const uint32 MSG_REF_15HZ = '15Hz'; -const uint32 MSG_REF_30HZ = '30Hz'; -const uint32 MSG_REF_60HZ = '60Hz'; -const uint32 MSG_MOUNT = 'moun'; -const uint32 MSG_DEBUGGER = 'dbug'; - -// Display types -enum { - DISPLAY_WINDOW, - DISPLAY_SCREEN -}; - -// From sys_beos.cpp -extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg); -extern void SysMountVolume(const char *name); - -// Global variables -static bool classic_mode = false; // Flag: Classic Mac video mode -static int scr_mode_bit = 0; -static vector VideoModes; // Supported video modes - - /* - * monitor_desc subclass for BeOS display - */ - -class BeOS_monitor_desc : public monitor_desc { -public: - BeOS_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~BeOS_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * A simple view class for blitting a bitmap on the screen - */ - -class BitmapView : public BView { -public: - BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "bitmap", B_FOLLOW_NONE, B_WILL_DRAW) - { - the_bitmap = bitmap; - } - virtual void Draw(BRect update) - { - DrawBitmap(the_bitmap, update, update); - } - virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); - -private: - BBitmap *the_bitmap; -}; - - -/* - * Window class - */ - -class MacWindow : public BDirectWindow { -public: - MacWindow(BRect frame, const BeOS_monitor_desc& monitor); - virtual ~MacWindow(); - virtual void MessageReceived(BMessage *msg); - virtual void DirectConnected(direct_buffer_info *info); - virtual void WindowActivated(bool active); - - int32 frame_skip; - bool mouse_in_view; // Flag: Mouse pointer within bitmap view - uint8 remap_mac_be[256]; // For remapping of Mac colors to Be colors - -private: - static status_t tick_func(void *arg); - - thread_id tick_thread; - bool tick_thread_active; // Flag for quitting the tick thread - - BitmapView *main_view; // Main view for bitmap drawing - BBitmap *the_bitmap; // Mac screen bitmap - - uint32 old_scroll_lock_state; - - bool supports_direct_mode; // Flag: Direct frame buffer access supported - sem_id drawing_sem; - - void *bits; - int32 bytes_per_row; - color_space pixel_format; - bool unclipped; - - BeOS_monitor_desc monitor; -}; - - -/* - * Screen class - */ - -class MacScreen : public BWindowScreen { -public: - MacScreen(const BeOS_monitor_desc& monitor, const char *name, int mode_bit, status_t *error); - virtual ~MacScreen(); - virtual void Quit(void); - virtual void ScreenConnected(bool active); - - rgb_color palette[256]; // Color palette, 256 entries - bool palette_changed; - -private: - static status_t tick_func(void *arg); - - thread_id tick_thread; - bool tick_thread_active; // Flag for quitting the tick thread - - BView *main_view; // Main view for GetMouse() - uint8 *frame_backup; // Frame buffer backup when switching from/to different workspace - bool quitting; // Flag for ScreenConnected: We are quitting, don't pause emulator thread - bool screen_active; - bool first_time; - - BeOS_monitor_desc monitor; -}; - - -// Global variables -static int display_type = DISPLAY_WINDOW; // See enum above -static MacWindow *the_window = NULL; // Pointer to the window -static MacScreen *the_screen = NULL; // Pointer to the screen -static sem_id mac_os_lock = -1; // This is used to stop the MacOS thread when the Basilisk workspace is switched out -static uint8 MacCursor[68] = {16, 1}; // Mac cursor image - - -/* - * Initialization - */ - -// Add mode to list of supported modes -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth) -{ - video_mode mode; - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.depth = depth; - VideoModes.push_back(mode); -} - -// Add standard list of windowed modes for given color depth -static void add_window_modes(video_depth depth) -{ -#if 0 - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); -#endif -} - - - -bool VideoInit(bool classic) -{ - classic_mode = classic; - - // Get screen mode from preferences - const char *mode_str; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine type and mode - int default_width = 512, default_height = 384; - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1) - display_type = DISPLAY_SCREEN; - } -#if 0 - if (default_width <= 0) - default_width = DisplayWidth(x_display, screen); - else if (default_width > DisplayWidth(x_display, screen)) - default_width = DisplayWidth(x_display, screen); - if (default_height <= 0) - default_height = DisplayHeight(x_display, screen); - else if (default_height > DisplayHeight(x_display, screen)) - default_height = DisplayHeight(x_display, screen); -#endif - - // Mac screen depth follows BeOS depth - video_depth default_depth = VDEPTH_1BIT; - switch (BScreen().ColorSpace()) { - case B_CMAP8: - default_depth = VDEPTH_8BIT; - break; - case B_RGB15: - default_depth = VDEPTH_16BIT; - break; - case B_RGB32: - default_depth = VDEPTH_32BIT; - break; - default: - fprintf(stderr, "Unknown color space!"); - } - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); - else { - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); -#if 0 - for (unsigned d=VDEPTH_1BIT; d<=VDEPTH_32BIT; d++) { - if (find_visual_for_depth(video_depth(d))) - add_window_modes(video_depth(d)); - } -#endif - } - } else - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); - if (VideoModes.empty()) { - ErrorAlert(STR_VIDEO_FAILED); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - if (i->x == default_width && i->y == default_height && i->depth == default_depth) { - default_id = i->resolution_id; - break; - } - } - if (i == end) { // not found, use first available mode - default_depth = VideoModes[0].depth; - default_id = VideoModes[0].resolution_id; - } - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - int bits = 1 << i->depth; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits)); - } -#endif - - // Create X11_monitor_desc for this (the only) display - BeOS_monitor_desc *monitor = new BeOS_monitor_desc(VideoModes, default_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - -bool BeOS_monitor_desc::video_open() { - // Create semaphore - mac_os_lock = create_sem(0, "MacOS Frame Buffer Lock"); - - const video_mode &mode = get_current_mode(); - - // Open display - switch (display_type) { - case DISPLAY_WINDOW: - the_window = new MacWindow(BRect(0, 0, mode.x-1, mode.y-1), *this); - break; - case DISPLAY_SCREEN: { - status_t screen_error; - the_screen = new MacScreen(*this, GetString(STR_WINDOW_TITLE), scr_mode_bit & 0x1f, &screen_error); - if (screen_error != B_NO_ERROR) { - the_screen->PostMessage(B_QUIT_REQUESTED); - while (the_screen) - snooze(200000); - ErrorAlert(STR_OPEN_SCREEN_ERR); - return false; - } else { - the_screen->Show(); - acquire_sem(mac_os_lock); - } - break; - } - } - return true; -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - // Close display - switch (display_type) { - case DISPLAY_WINDOW: - if (the_window != NULL) { - the_window->PostMessage(B_QUIT_REQUESTED); - while (the_window) - snooze(200000); - } - break; - case DISPLAY_SCREEN: - if (the_screen != NULL) { - the_screen->PostMessage(B_QUIT_REQUESTED); - while (the_screen) - snooze(200000); - } - break; - } - - // Delete semaphore - delete_sem(mac_os_lock); -} - - -/* - * Set palette - */ - -void BeOS_monitor_desc::set_palette(uint8 *pal, int num) -{ - switch (display_type) { - case DISPLAY_WINDOW: { - BScreen screen(the_window); - for (int i=0; i<256; i++) - the_window->remap_mac_be[i] = screen.IndexForColor(pal[i*3], pal[i*3+1], pal[i*3+2]); - break; - } - case DISPLAY_SCREEN: - for (int i=0; i<256; i++) { - the_screen->palette[i].red = pal[i*3]; - the_screen->palette[i].green = pal[i*3+1]; - the_screen->palette[i].blue = pal[i*3+2]; - } - the_screen->palette_changed = true; - break; - } -} - - -/* - * Switch video mode - */ - -void BeOS_monitor_desc::switch_to_current_mode() -{ -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - if (display_type == DISPLAY_SCREEN) { - if (the_screen != NULL) { - the_screen->PostMessage(B_QUIT_REQUESTED); - while (the_screen) - snooze(200000); - } - } -} - - -/* - * Video event handling (not neccessary under BeOS, handled by filter function) - */ - -void VideoInterrupt(void) -{ - release_sem(mac_os_lock); - while (acquire_sem(mac_os_lock) == B_INTERRUPTED) ; -} - - -/* - * Filter function for receiving mouse and keyboard events - */ - -#define MENU_IS_POWER 0 - -// Be -> Mac raw keycode translation table -static const uint8 keycode2mac[0x80] = { - 0xff, 0x35, 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, // inv Esc F1 F2 F3 F4 F5 F6 - 0x62, 0x64, 0x65, 0x6d, 0x67, 0x6f, 0x69, 0x6b, // F7 F8 F9 F10 F11 F12 F13 F14 - 0x71, 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, // F15 ` 1 2 3 4 5 6 - 0x1a, 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x33, 0x72, // 7 8 9 0 - = BSP INS - 0x73, 0x74, 0x47, 0x4b, 0x43, 0x4e, 0x30, 0x0c, // HOM PUP NUM / * - TAB Q - 0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, 0x1f, // W E R T Y U I O - 0x23, 0x21, 0x1e, 0x2a, 0x75, 0x77, 0x79, 0x59, // P [ ] \ DEL END PDN 7 - 0x5b, 0x5c, 0x45, 0x39, 0x00, 0x01, 0x02, 0x03, // 8 9 + CAP A S D F - 0x05, 0x04, 0x26, 0x28, 0x25, 0x29, 0x27, 0x24, // G H J K L ; ' RET - 0x56, 0x57, 0x58, 0x38, 0x06, 0x07, 0x08, 0x09, // 4 5 6 SHL Z X C V - 0x0b, 0x2d, 0x2e, 0x2b, 0x2f, 0x2c, 0x38, 0x3e, // B N M , . / SHR CUP - 0x53, 0x54, 0x55, 0x4c, 0x36, 0x37, 0x31, 0x37, // 1 2 3 ENT CTL ALT SPC ALT - 0x36, 0x3b, 0x3d, 0x3c, 0x52, 0x41, 0x3a, 0x3a, // CTR CLF CDN CRT 0 . CMD CMD -#if MENU_IS_POWER - 0x7f, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv -#else - 0x32, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv -#endif - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - -static const uint8 modifier2mac[0x20] = { -#if MENU_IS_POWER - 0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x7f, // SHF CMD inv CAP F14 NUM OPT MNU -#else - 0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x32, // SHF CMD CTR CAP F14 NUM OPT MNU -#endif - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - -static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter) -{ - switch (msg->what) { - case B_KEY_DOWN: - case B_KEY_UP: { - uint32 be_code = msg->FindInt32("key") & 0xff; - uint32 mac_code = keycode2mac[be_code]; - - // Intercept Ctrl-F1 (mount floppy disk shortcut) - uint32 mods = msg->FindInt32("modifiers"); - if (be_code == 0x02 && (mods & B_CONTROL_KEY)) - SysMountVolume("/dev/disk/floppy/raw"); - - if (mac_code == 0xff) - return B_DISPATCH_MESSAGE; - if (msg->what == B_KEY_DOWN) - ADBKeyDown(mac_code); - else - ADBKeyUp(mac_code); - return B_SKIP_MESSAGE; - } - - case B_MODIFIERS_CHANGED: { - uint32 mods = msg->FindInt32("modifiers"); - uint32 old_mods = msg->FindInt32("be:old_modifiers"); - uint32 changed = mods ^ old_mods; - uint32 mask = 1; - for (int i=0; i<32; i++, mask<<=1) - if (changed & mask) { - uint32 mac_code = modifier2mac[i]; - if (mac_code == 0xff) - continue; - if (mods & mask) - ADBKeyDown(mac_code); - else - ADBKeyUp(mac_code); - } - return B_SKIP_MESSAGE; - } - - case B_MOUSE_MOVED: { - BPoint point; - msg->FindPoint("where", &point); - ADBMouseMoved(int(point.x), int(point.y)); - return B_DISPATCH_MESSAGE; // Otherwise BitmapView::MouseMoved() wouldn't be called - } - - case B_MOUSE_DOWN: { - uint32 buttons = msg->FindInt32("buttons"); - if (buttons & B_PRIMARY_MOUSE_BUTTON) - ADBMouseDown(0); - if (buttons & B_SECONDARY_MOUSE_BUTTON) - ADBMouseDown(1); - if (buttons & B_TERTIARY_MOUSE_BUTTON) - ADBMouseDown(2); - return B_SKIP_MESSAGE; - } - - case B_MOUSE_UP: // B_MOUSE_UP means "all buttons released" - ADBMouseUp(0); - ADBMouseUp(1); - ADBMouseUp(2); - return B_SKIP_MESSAGE; - - default: - return B_DISPATCH_MESSAGE; - } -} - - -/* - * Window constructor - */ - -MacWindow::MacWindow(BRect frame, const BeOS_monitor_desc& monitor) - : BDirectWindow(frame, GetString(STR_WINDOW_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE) - , monitor(monitor) -{ - supports_direct_mode = SupportsWindowMode(); - - // Move window to right position - Lock(); - MoveTo(80, 60); - - // Allocate bitmap and Mac frame buffer - uint32 x = frame.IntegerWidth() + 1; - uint32 y = frame.IntegerHeight() + 1; - int fbsize = x * y; - const video_mode &mode = monitor.get_current_mode(); - switch (mode.depth) { - case VDEPTH_1BIT: - fprintf(stderr, "1BIT SCREEN CREATED"); - the_bitmap = new BBitmap(frame, B_GRAY1); - fbsize /= 8; - break; - case VDEPTH_8BIT: - fprintf(stderr, "8BIT SCREEN CREATED"); - the_bitmap = new BBitmap(frame, B_CMAP8); - break; - case VDEPTH_32BIT: - fprintf(stderr, "32BIT SCREEN CREATED"); - the_bitmap = new BBitmap(frame, B_RGB32_BIG); - fbsize *= 4; - break; - default: - fprintf(stderr, "width: %d", 1 << mode.depth); - debugger("OOPS"); - } - -#if REAL_ADDRESSING - monitor.set_mac_frame_base((uint32)the_bitmap->Bits()); -#else - monitor.set_mac_frame_base(MacFrameBaseMac); -#endif - -#if !REAL_ADDRESSING - // Set variables for UAE memory mapping - MacFrameBaseHost = (uint8*)the_bitmap->Bits(); - MacFrameSize = fbsize; - MacFrameLayout = FLAYOUT_DIRECT; -#endif - - // Create bitmap view - main_view = new BitmapView(frame, the_bitmap); - AddChild(main_view); - main_view->MakeFocus(); - - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - - // Set up menus - BRect bounds = Bounds(); - bounds.OffsetBy(0, bounds.IntegerHeight() + 1); - BMenuItem *item; - BMenuBar *bar = new BMenuBar(bounds, "menu"); - BMenu *menu = new BMenu(GetString(STR_WINDOW_MENU)); - menu->AddItem(new BMenuItem(GetString(STR_WINDOW_ITEM_ABOUT), new BMessage(MSG_ABOUT_REQUESTED))); - menu->AddItem(new BSeparatorItem); - BMenu *submenu = new BMenu(GetString(STR_WINDOW_ITEM_REFRESH)); - submenu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_60HZ_LAB), new BMessage(MSG_REF_60HZ))); - submenu->SetRadioMode(true); - if (frame_skip == 12) { - if ((item = submenu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 8) { - if ((item = submenu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 6) { - if ((item = submenu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 4) { - if ((item = submenu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 2) { - if ((item = submenu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 1) { - if ((item = submenu->FindItem(GetString(STR_REF_60HZ_LAB))) != NULL) - item->SetMarked(true); - } - menu->AddItem(submenu); - submenu = new BMenu(GetString(STR_WINDOW_ITEM_MOUNT)); - SysCreateVolumeMenu(submenu, MSG_MOUNT); - menu->AddItem(submenu); -#if DEBUGGER_AVAILABLE - menu->AddItem(new BMenuItem("Debugger", new BMessage(MSG_DEBUGGER))); -#endif - bar->AddItem(menu); - AddChild(bar); - SetKeyMenuBar(bar); - int mbar_height = bar->Frame().IntegerHeight() + 1; - - // Resize window to fit menu bar - ResizeBy(0, mbar_height); - - // Set absolute mouse mode and get scroll lock state - ADBSetRelMouseMode(false); - mouse_in_view = true; - old_scroll_lock_state = modifiers() & B_SCROLL_LOCK; - if (old_scroll_lock_state) - SetTitle(GetString(STR_WINDOW_TITLE_FROZEN)); - else - SetTitle(GetString(STR_WINDOW_TITLE)); - - // Keep window aligned to 8-byte frame buffer boundaries for faster blitting - SetWindowAlignment(B_BYTE_ALIGNMENT, 8); - - // Create drawing semaphore (for direct mode) - drawing_sem = create_sem(0, "direct frame buffer access"); - - // Start 60Hz interrupt - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "Window Redraw", B_DISPLAY_PRIORITY, this); - resume_thread(tick_thread); - - // Add filter for keyboard and mouse events - BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func); - main_view->AddFilter(filter); - - // Show window - Unlock(); - Show(); - Sync(); -} - - -/* - * Window destructor - */ - -MacWindow::~MacWindow() -{ - // Restore cursor - mouse_in_view = false; - be_app->SetCursor(B_HAND_CURSOR); - - // Hide window - Hide(); - Sync(); - - // Stop 60Hz interrupt - status_t l; - tick_thread_active = false; - delete_sem(drawing_sem); - wait_for_thread(tick_thread, &l); - - // Free bitmap and frame buffer - delete the_bitmap; - - // Tell emulator that we're done - the_window = NULL; -} - - -/* - * Window connected/disconnected - */ - -void MacWindow::DirectConnected(direct_buffer_info *info) -{ - switch (info->buffer_state & B_DIRECT_MODE_MASK) { - case B_DIRECT_STOP: - acquire_sem(drawing_sem); - break; - case B_DIRECT_MODIFY: - acquire_sem(drawing_sem); - case B_DIRECT_START: - bits = (void *)((uint8 *)info->bits + info->window_bounds.top * info->bytes_per_row + info->window_bounds.left * info->bits_per_pixel / 8); - bytes_per_row = info->bytes_per_row; - pixel_format = info->pixel_format; - unclipped = false; - if (info->clip_list_count == 1) - if (memcmp(&info->clip_bounds, &info->window_bounds, sizeof(clipping_rect)) == 0) - unclipped = true; - release_sem(drawing_sem); - break; - } -} - - -/* - * Handle redraw and menu messages - */ - -void MacWindow::MessageReceived(BMessage *msg) -{ - BMessage *msg2; - - switch (msg->what) { - case MSG_REDRAW: { - - // Prevent backlog of messages - MessageQueue()->Lock(); - while ((msg2 = MessageQueue()->FindMessage(MSG_REDRAW, 0)) != NULL) { - MessageQueue()->RemoveMessage(msg2); - delete msg2; - } - MessageQueue()->Unlock(); - - // Convert Mac screen buffer to BeOS palette and blit - const video_mode &mode = monitor.get_current_mode(); - BRect update_rect = BRect(0, 0, mode.x-1, mode.y-1); - main_view->DrawBitmapAsync(the_bitmap, update_rect, update_rect); - break; - } - - case MSG_ABOUT_REQUESTED: { - ShowAboutWindow(); - break; - } - - case MSG_REF_5HZ: - PrefsReplaceInt32("frameskip", frame_skip = 12); - break; - - case MSG_REF_7_5HZ: - PrefsReplaceInt32("frameskip", frame_skip = 8); - break; - - case MSG_REF_10HZ: - PrefsReplaceInt32("frameskip", frame_skip = 6); - break; - - case MSG_REF_15HZ: - PrefsReplaceInt32("frameskip", frame_skip = 4); - break; - - case MSG_REF_30HZ: - PrefsReplaceInt32("frameskip", frame_skip = 2); - break; - - case MSG_REF_60HZ: - PrefsReplaceInt32("frameskip", frame_skip = 1); - break; - - case MSG_MOUNT: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - SysMountVolume(source->Label()); - break; - } - -#if DEBUGGER_AVAILABLE - case MSG_DEBUGGER: - extern int debugging; - debugging = 1; - regs.spcflags |= SPCFLAG_BRK; - break; -#endif - - default: - BDirectWindow::MessageReceived(msg); - } -} - - -/* - * Window activated/deactivated - */ - -void MacWindow::WindowActivated(bool active) -{ - if (active) { - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - } else - frame_skip = 12; // 5Hz in background -} - - -/* - * 60Hz interrupt routine - */ - -status_t MacWindow::tick_func(void *arg) -{ - MacWindow *obj = (MacWindow *)arg; - static int tick_counter = 0; - while (obj->tick_thread_active) { - - tick_counter++; - if (tick_counter >= obj->frame_skip) { - tick_counter = 0; - - // Window title is determined by Scroll Lock state - uint32 scroll_lock_state = modifiers() & B_SCROLL_LOCK; - if (scroll_lock_state != obj->old_scroll_lock_state) { - if (scroll_lock_state) - obj->SetTitle(GetString(STR_WINDOW_TITLE_FROZEN)); - else - obj->SetTitle(GetString(STR_WINDOW_TITLE)); - obj->old_scroll_lock_state = scroll_lock_state; - } - - // Has the Mac started? - if (HasMacStarted()) { - - // Yes, set new cursor image if it was changed - if (memcmp(MacCursor+4, Mac2HostAddr(0x844), 64)) { - Mac2Host_memcpy(MacCursor+4, 0x844, 64); // Cursor image - MacCursor[2] = ReadMacInt8(0x885); // Hotspot - MacCursor[3] = ReadMacInt8(0x887); - be_app->SetCursor(MacCursor); - } - } - - // Refresh screen unless Scroll Lock is down - if (!scroll_lock_state) { - obj->PostMessage(MSG_REDRAW); - } - } - snooze(16666); - } - return 0; -} - - -/* - * Mouse moved in window - */ - -void BitmapView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - switch (transit) { - case B_ENTERED_VIEW: - ((MacWindow *)Window())->mouse_in_view = true; - be_app->SetCursor(MacCursor); - break; - case B_EXITED_VIEW: - ((MacWindow *)Window())->mouse_in_view = false; - be_app->SetCursor(B_HAND_CURSOR); - break; - } -} - - -/* - * Screen constructor - */ - -MacScreen::MacScreen(const BeOS_monitor_desc& monitor, const char *name, int mode_bit, status_t *error) - : BWindowScreen(name, 1 << mode_bit, error), tick_thread(-1) - , monitor(monitor) -{ - // Set all variables - frame_backup = NULL; - palette_changed = false; - screen_active = false; - first_time = true; - quitting = false; - - // Set relative mouse mode - ADBSetRelMouseMode(true); - - // Create view to get mouse events - main_view = new BView(Frame(), NULL, B_FOLLOW_NONE, 0); - AddChild(main_view); - - // Start 60Hz interrupt - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "Polling sucks...", B_DISPLAY_PRIORITY, this); - resume_thread(tick_thread); - - // Add filter for keyboard and mouse events - BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func); - AddCommonFilter(filter); -} - - -/* - * Screen destructor - */ - -MacScreen::~MacScreen() -{ - // Stop 60Hz interrupt - if (tick_thread > 0) { - status_t l; - tick_thread_active = false; - wait_for_thread(tick_thread, &l); - } - - // Tell emulator that we're done - the_screen = NULL; -} - - -/* - * Screen closed - */ - -void MacScreen::Quit(void) -{ - // Tell ScreenConnected() that we are quitting - quitting = true; - BWindowScreen::Quit(); -} - - -/* - * Screen connected/disconnected - */ - -void MacScreen::ScreenConnected(bool active) -{ - graphics_card_info *info = CardInfo(); - screen_active = active; - const video_mode &mode = monitor.get_current_mode(); - - if (active == true) { - - // Set VideoMonitor -#if REAL_ADDRESSING - monitor.set_mac_frame_base((uint32)info->frame_buffer); -#else - monitor.set_mac_frame_base(MacFrameBaseMac); -#endif - -#if !REAL_ADDRESSING - // Set variables for UAE memory mapping - MacFrameBaseHost = (uint8 *)info->frame_buffer; - MacFrameSize = mode.bytes_per_row * mode.y; - switch (info->bits_per_pixel) { - case 15: - MacFrameLayout = FLAYOUT_HOST_555; - break; - case 16: - MacFrameLayout = FLAYOUT_HOST_565; - break; - case 32: - MacFrameLayout = FLAYOUT_HOST_888; - break; - default: - MacFrameLayout = FLAYOUT_DIRECT; - break; - } -#endif - - // Copy from backup store to frame buffer - if (frame_backup != NULL) { - memcpy(info->frame_buffer, frame_backup, mode.bytes_per_row * mode.y); - delete[] frame_backup; - frame_backup = NULL; - } - - // Restore palette - if (mode.depth == VDEPTH_8BIT) - SetColorList(palette); - - // Restart/signal emulator thread - release_sem(mac_os_lock); - - } else { - - if (!quitting) { - - // Stop emulator thread - acquire_sem(mac_os_lock); - - // Create backup store and save frame buffer - frame_backup = new uint8[mode.bytes_per_row * mode.y]; - memcpy(frame_backup, info->frame_buffer, mode.bytes_per_row * mode.y); - } - } -} - - -/* - * Screen 60Hz interrupt routine - */ - -status_t MacScreen::tick_func(void *arg) -{ - MacScreen *obj = (MacScreen *)arg; - while (obj->tick_thread_active) { - - // Wait - snooze(16667); - - // Workspace activated? Then poll the mouse and set the palette if needed - if (!obj->quitting && obj->LockWithTimeout(200000) == B_OK) { - if (obj->screen_active) { - BPoint pt; - uint32 button = 0; - if (obj->palette_changed) { - obj->palette_changed = false; - obj->SetColorList(obj->palette); - } - obj->main_view->GetMouse(&pt, &button); - set_mouse_position(320, 240); - ADBMouseMoved(int(pt.x) - 320, int(pt.y) - 240); - if (button & B_PRIMARY_MOUSE_BUTTON) - ADBMouseDown(0); - if (!(button & B_PRIMARY_MOUSE_BUTTON)) - ADBMouseUp(0); - if (button & B_SECONDARY_MOUSE_BUTTON) - ADBMouseDown(1); - if (!(button & B_SECONDARY_MOUSE_BUTTON)) - ADBMouseUp(1); - if (button & B_TERTIARY_MOUSE_BUTTON) - ADBMouseDown(2); - if (!(button & B_TERTIARY_MOUSE_BUTTON)) - ADBMouseUp(2); - } - obj->Unlock(); - } - } - return 0; -} diff --git a/BasiliskII/src/BeOS/xpram_beos.cpp b/BasiliskII/src/BeOS/xpram_beos.cpp deleted file mode 100644 index 8ee250a47..000000000 --- a/BasiliskII/src/BeOS/xpram_beos.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * xpram_beos.cpp - XPRAM handling, BeOS specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "sysdeps.h" -#include "xpram.h" - - -// XPRAM file name and path -#if POWERPC_ROM -const char XPRAM_FILE_NAME[] = "SheepShaver_NVRAM"; -#else -const char XPRAM_FILE_NAME[] = "BasiliskII_XPRAM"; -#endif -static BPath xpram_path; - - -/* - * Load XPRAM from settings file - */ - -void LoadXPRAM(const char *vmdir) -{ - // Construct XPRAM path - find_directory(B_USER_SETTINGS_DIRECTORY, &xpram_path, true); - xpram_path.Append(XPRAM_FILE_NAME); - - // Load XPRAM from settings file - int fd; - if ((fd = open(xpram_path.Path(), O_RDONLY)) >= 0) { - read(fd, XPRAM, XPRAM_SIZE); - close(fd); - } -} - - -/* - * Save XPRAM to settings file - */ - -void SaveXPRAM(void) -{ - if (xpram_path.InitCheck() != B_NO_ERROR) - return; - int fd; - if ((fd = open(xpram_path.Path(), O_WRONLY | O_CREAT, 0666)) >= 0) { - write(fd, XPRAM, XPRAM_SIZE); - close(fd); - } -} - - -/* - * Delete PRAM file - */ - -void ZapPRAM(void) -{ - // Construct PRAM path - find_directory(B_USER_SETTINGS_DIRECTORY, &xpram_path, true); - xpram_path.Append(XPRAM_FILE_NAME); - - // Delete file - unlink(xpram_path.Path()); -} diff --git a/BasiliskII/src/MacOSX/video_macosx.mm b/BasiliskII/src/MacOSX/video_macosx.mm index 8323038c3..026ae2c85 100644 --- a/BasiliskII/src/MacOSX/video_macosx.mm +++ b/BasiliskII/src/MacOSX/video_macosx.mm @@ -2,7 +2,7 @@ * $Id$ * * video_macosx.mm - Interface between Basilisk II and Cocoa windowing. - * Based on video_amiga.cpp and video_x.cpp + * Based on video_x.cpp * * Basilisk II (C) 1997-2008 Christian Bauer * @@ -51,7 +51,7 @@ // Global variables uint8 display_type = DISPLAY_WINDOW, // These are used by PrefsEditor - frame_skip; + frame_skip; uint16 init_width = MIN_WIDTH, // as well as this code init_height = MIN_HEIGHT, init_depth = 32; @@ -919,7 +919,7 @@ void VideoExit(void) const char *failure = NULL; D(bug("switch_to_current_mode(): width=%d height=%d depth=%d bytes_per_row=%d\n", mode.x, mode.y, bits_from_depth(mode.depth), mode.bytes_per_row)); - + if ( display_type == DISPLAY_SCREEN && originalMode ) { D(NSLog(@"About to call CGDisplayBestModeForParameters()")); @@ -958,7 +958,7 @@ void VideoExit(void) CGColorSpaceRef oldColourSpace = colourSpace; CGDataProviderRef oldProvider = provider; void *oldBuffer = the_buffer; - + if ( video_open(mode) ) { CGImageRelease(oldImageRef); @@ -979,7 +979,7 @@ void VideoExit(void) // if ( CGDisplayMoveCursorToPoint(theDisplay, CGPointMake(15,15)) // == CGDisplayNoErr ) // { - // + // [output fullscreenMouseMove]; // } // else diff --git a/BasiliskII/src/Unix/BasiliskII.1 b/BasiliskII/src/Unix/BasiliskII.1 index 45e402ac9..d5b44b3b1 100644 --- a/BasiliskII/src/Unix/BasiliskII.1 +++ b/BasiliskII/src/Unix/BasiliskII.1 @@ -41,7 +41,7 @@ and a Macintosh ROM image to use Basilisk II. .TP - Emulates extended ADB keyboard and 3-button mouse .TP -- Uses UAE 68k emulation or (under AmigaOS and NetBSD/m68k) real 68k processor +- Uses UAE 68k emulation or real 68k processor .SH OPTIONS .TP .BI "\-\-display " display-name diff --git a/BasiliskII/src/Unix/Irix/audio_irix.cpp b/BasiliskII/src/Unix/Irix/audio_irix.cpp index ebd8eb69e..8b61a2819 100644 --- a/BasiliskII/src/Unix/Irix/audio_irix.cpp +++ b/BasiliskII/src/Unix/Irix/audio_irix.cpp @@ -139,17 +139,17 @@ bool open_audio(void) } alSetChannels(config, audio_channel_counts[audio_channel_count_index]); alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs? - + // Try to open the audio library port = alOpenPort("BasiliskII", "w", config); if (port == NULL) { - fprintf(stderr, "ERROR: Cannot open audio port: %s\n", + fprintf(stderr, "ERROR: Cannot open audio port: %s\n", alGetErrorString(oserror())); WarningAlert(GetString(STR_NO_AUDIO_WARN)); return false; } - + // Set the sample rate pv[0].param = AL_RATE; @@ -180,7 +180,7 @@ bool open_audio(void) // Put a limit on the Mac sound buffer size, to decrease delay #define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer - int target_frames_per_block = + int target_frames_per_block = (audio_sample_rates[audio_sample_rate_index] >> 16) * AUDIO_BUFFER_MSEC / 1000; if (audio_frames_per_block > target_frames_per_block) @@ -190,14 +190,14 @@ bool open_audio(void) alZeroFrames(port, audio_frames_per_block); // so we don't underflow // Try to keep the buffer pretty full - sound_buffer_fill_point = alGetQueueSize(config) - + sound_buffer_fill_point = alGetQueueSize(config) - 2 * audio_frames_per_block; if (sound_buffer_fill_point < 0) sound_buffer_fill_point = alGetQueueSize(config) / 3; D(bug("fill point %d\n", sound_buffer_fill_point)); sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * - audio_channel_counts[audio_channel_count_index] * + audio_channel_counts[audio_channel_count_index] * audio_frames_per_block; set_audio_status_format(); @@ -342,7 +342,7 @@ static void *stream_func(void *arg) goto silence; // Send data to audio library. Convert 8-bit data - // unsigned->signed, using same algorithm as audio_amiga.cpp. + // unsigned->signed // It works fine for 8-bit mono, but not stereo. if (AudioStatus.sample_size == 8) { uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); @@ -473,7 +473,7 @@ static void set_volume(uint32 vol) alGetParamInfo(dev, AL_GAIN, &pi); maxgain = alFixedToDouble(pi.max.ll); - mingain = alFixedToDouble(pi.min.ll); + mingain = alFixedToDouble(pi.min.ll); // Set the new gain values diff --git a/BasiliskII/src/ether.cpp b/BasiliskII/src/ether.cpp index d5471029d..8df8c86bd 100644 --- a/BasiliskII/src/ether.cpp +++ b/BasiliskII/src/ether.cpp @@ -56,12 +56,7 @@ using std::map; #define MONITOR 0 - -#ifdef __BEOS__ -#define CLOSESOCKET closesocket -#else #define CLOSESOCKET close -#endif // Global variables @@ -138,12 +133,8 @@ void EtherInit(void) // Set socket options int on = 1; -#ifdef __BEOS__ - setsockopt(udp_socket, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(on)); -#else setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); ioctl(udp_socket, FIONBIO, &on); -#endif // Start thread for packet reception if (!ether_start_udp_thread(udp_socket)) { diff --git a/BasiliskII/src/extfs.cpp b/BasiliskII/src/extfs.cpp index adc8d4a0d..b3ce3eec0 100644 --- a/BasiliskII/src/extfs.cpp +++ b/BasiliskII/src/extfs.cpp @@ -1053,7 +1053,7 @@ static int16 fs_volume_mount(uint32 pb) // Init VCB WriteMacInt16(vcb + vcbSigWord, 0x4244); -#if defined(__BEOS__) || defined(WIN32) +#if defined(WIN32) WriteMacInt32(vcb + vcbCrDate, TimeToMacTime(root_stat.st_crtime)); #elif defined __APPLE__ && defined __MACH__ WriteMacInt32(vcb + vcbCrDate, get_creation_time(RootPath)); @@ -1118,7 +1118,7 @@ static int16 fs_get_vol_info(uint32 pb, bool hfs) // Fill in struct if (ReadMacInt32(pb + ioNamePtr)) pstrcpy((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), VOLUME_NAME); -#if defined(__BEOS__) || defined(WIN32) +#if defined(WIN32) WriteMacInt32(pb + ioVCrDate, TimeToMacTime(root_stat.st_crtime)); #elif defined __APPLE__ && defined __MACH__ WriteMacInt32(pb + ioVCrDate, get_creation_time(RootPath)); @@ -1312,7 +1312,7 @@ static int16 fs_get_file_info(uint32 pb, bool hfs, uint32 dirID) WriteMacInt8(pb + ioFlAttrib, access(full_path, W_OK) == 0 ? 0 : faLocked); WriteMacInt32(pb + ioDirID, fs_item->id); -#if defined(__BEOS__) || defined(WIN32) +#if defined(WIN32) WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime)); #elif defined __APPLE__ && defined __MACH__ WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path)); @@ -1437,7 +1437,7 @@ static int16 fs_get_cat_info(uint32 pb) WriteMacInt8(pb + ioACUser, 0); WriteMacInt32(pb + ioDirID, fs_item->id); WriteMacInt32(pb + ioFlParID, fs_item->parent_id); -#if defined(__BEOS__) || defined(WIN32) +#if defined(WIN32) WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime)); #elif defined __APPLE__ && defined __MACH__ WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path)); diff --git a/BasiliskII/src/include/debug.h b/BasiliskII/src/include/debug.h index 5200ba011..11fa4df78 100644 --- a/BasiliskII/src/include/debug.h +++ b/BasiliskII/src/include/debug.h @@ -89,18 +89,6 @@ static inline void _cdecl winbug(wchar_t *s, ...) #define bug winbug #define wbug wwinbug -#elif defined(AMIGA) - -// Amiga debugging info goes to serial port (or sushi) -#ifdef __cplusplus -extern "C" { -#endif -extern void kprintf(const char *, ...); -#ifdef __cplusplus -} -#endif -#define bug kprintf - #else // Other systems just print it to stdout diff --git a/BasiliskII/src/powerrom_cpu/cpu_emulation.h b/BasiliskII/src/powerrom_cpu/cpu_emulation.h deleted file mode 100644 index dbddfbbc9..000000000 --- a/BasiliskII/src/powerrom_cpu/cpu_emulation.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * cpu_emulation.h - Definitions for Basilisk II CPU emulation module (Apple PowerMac ROM 680x0 emulator version (BeOS/PPC)) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CPU_EMULATION_H -#define CPU_EMULATION_H - - -/* - * Memory system - */ - -// RAM and ROM pointers (allocated and set by main_*.cpp) -extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0 -extern uint8 *RAMBaseHost; // RAM base (host address space) -extern uint32 RAMSize; // Size of RAM - -extern uint32 ROMBaseMac; // ROM base (Mac address space) -extern uint8 *ROMBaseHost; // ROM base (host address space) -extern uint32 ROMSize; // Size of ROM - -// Mac memory access functions -static inline uint32 ReadMacInt32(uint32 addr) {return ntohl(*(uint32 *)addr);} -static inline uint32 ReadMacInt16(uint32 addr) {return ntohs(*(uint16 *)addr);} -static inline uint32 ReadMacInt8(uint32 addr) {return *(uint8 *)addr;} -static inline void WriteMacInt32(uint32 addr, uint32 l) {*(uint32 *)addr = htonl(l);} -static inline void WriteMacInt16(uint32 addr, uint32 w) {*(uint16 *)addr = htons(w);} -static inline void WriteMacInt8(uint32 addr, uint32 b) {*(uint8 *)addr = b;} -static inline uint8 *Mac2HostAddr(uint32 addr) {return (uint8 *)addr;} -static inline uint32 Host2MacAddr(uint8 *addr) {return (uint32)addr;} - - -/* - * 680x0 emulation - */ - -// Initialization -extern bool Init680x0(void); // This routine may want to look at CPUType/FPUType to set up the apropriate emulation -extern void Exit680x0(void); - -// 680x0 emulation functions -struct M68kRegisters; -extern void Start680x0(void); // Reset and start 680x0 -extern "C" void Execute68k(uint32 addr, M68kRegisters *r); // Execute 68k code from EMUL_OP routine -extern "C" void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute MacOS 68k trap from EMUL_OP routine - -// Interrupt functions -extern void TriggerInterrupt(void); // Trigger interrupt (InterruptFlag must be set first) - -#endif diff --git a/BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp b/BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp deleted file mode 100644 index d91b9049f..000000000 --- a/BasiliskII/src/powerrom_cpu/powerrom_cpu.cpp +++ /dev/null @@ -1,1367 +0,0 @@ -/* - * powerrom_cpu.cpp - Using the 680x0 emulator in PowerMac ROMs for Basilisk II - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include - -#include "sysdeps.h" -#include "cpu_emulation.h" -#include "main.h" -#include "emul_op.h" -#include "prefs.h" -#include "timer.h" -#include "user_strings.h" - -#include "sheep_driver.h" - -#define DEBUG 0 -#include "debug.h" - -// Save FP regs in Execute68k()? -#define SAVE_FP_EXEC_68K 0 - - -// Constants -const char ROM_FILE_NAME[] = "PowerROM"; -const char KERNEL_AREA_NAME[] = "Macintosh Kernel Data"; -const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache"; - -const uint32 ROM_BASE = 0x40800000; // Base address of ROM -const uint32 ROM_SIZE = 0x00400000; // Size of ROM file -const uint32 ROM_AREA_SIZE = 0x00500000; // Size of ROM area - -const uint32 DR_CACHE_BASE = 0x69000000; // Address of DR cache -const uint32 DR_CACHE_SIZE = 0x80000; // Size of DR Cache - -const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack - -// PowerPC opcodes -const uint32 POWERPC_NOP = 0x60000000; -const uint32 POWERPC_ILLEGAL = 0x00000000; -const uint32 POWERPC_BLR = 0x4e800020; -const uint32 POWERPC_BCTR = 0x4e800420; - -// Extra Low Memory Globals -#define MODE_68K 0 // 68k emulator active -#define MODE_EMUL_OP 1 // Within EMUL_OP routine - -#define XLM_RESET_STACK 0x2800 // Reset stack pointer -#define XLM_KERNEL_DATA 0x2804 // Pointer to Kernel Data -#define XLM_TOC 0x2808 // TOC pointer of emulator -#define XLM_RUN_MODE 0x2810 // Current run mode, see enum above -#define XLM_68K_R25 0x2814 // Contents of the 68k emulator's r25 (which contains the interrupt level), saved upon entering EMUL_OP mode, used by Execute68k() and the USR1 signal handler -#define XLM_IRQ_NEST 0x2818 // Interrupt disable nesting counter (>0: disabled) -#define XLM_PVR 0x281c // Theoretical PVR -#define XLM_EMUL_RETURN_PROC 0x2824 // Pointer to EMUL_RETURN routine -#define XLM_EXEC_RETURN_PROC 0x2828 // Pointer to EXEC_RETURN routine -#define XLM_EMUL_OP_PROC 0x282c // Pointer to EMUL_OP routine -#define XLM_EMUL_RETURN_STACK 0x2830 // Stack pointer for EMUL_RETURN - - -// RAM and ROM pointers -uint32 RAMBaseMac; // RAM base (Mac address space) -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM - - -// Emulator Data -struct EmulatorData { - uint32 v[0x400]; -}; - - -// Kernel Data -struct KernelData { - uint32 v[0x400]; - EmulatorData ed; -}; - - -// Exceptions -class file_open_error {}; -class file_read_error {}; -class rom_size_error {}; - - -// Global variables -static void *TOC; // TOC pointer -static uint32 PVR; // Theoretical PVR -static int64 CPUClockSpeed; // Processor clock speed (Hz) -static int64 BusClockSpeed; // Bus clock speed (Hz) -static system_info SysInfo; // System information - -static area_id kernel_area = -1; // Kernel Data area ID -static KernelData *kernel_data = NULL; // Pointer to Kernel Data -static uint32 KernelDataAddr; // Address of Kernel Data -static EmulatorData *emulator_data = NULL; -static area_id dr_cache_area; // DR Cache area ID -static uint32 DRCacheAddr; // Address of DR Cache - -static struct sigaction sigusr1_action; // Interrupt signal (of emulator thread) -static bool ReadyForSignals = false; // Flag: emul_thread ready to receive signals - - -// Prototypes -static void sigusr1_handler(int sig, void *arg, vregs *r); - -// From main_beos.cpp -extern int sheep_fd; // fd of sheep driver -extern thread_id emul_thread; // Emulator thread - - -/* - * Load ROM file (upper 3MB) - * - * file_open_error: Cannot open ROM file (nor use built-in ROM) - * file_read_error: Cannot read ROM file - */ - -// Decode LZSS data -static void decode_lzss(const uint8 *src, uint8 *dest, int size) -{ - char dict[0x1000]; - int run_mask = 0, dict_idx = 0xfee; - for (;;) { - if (run_mask < 0x100) { - // Start new run - if (--size < 0) - break; - run_mask = *src++ | 0xff00; - } - bool bit = run_mask & 1; - run_mask >>= 1; - if (bit) { - // Verbatim copy - if (--size < 0) - break; - int c = *src++; - dict[dict_idx++] = c; - *dest++ = c; - dict_idx &= 0xfff; - } else { - // Copy from dictionary - if (--size < 0) - break; - int idx = *src++; - if (--size < 0) - break; - int cnt = *src++; - idx |= (cnt << 4) & 0xf00; - cnt = (cnt & 0x0f) + 3; - while (cnt--) { - char c = dict[idx++]; - dict[dict_idx++] = c; - *dest++ = c; - idx &= 0xfff; - dict_idx &= 0xfff; - } - } - } -} - -static void load_rom(void) -{ - // Get rom file path from preferences - const char *rom_path = PrefsFindString("powerrom"); - - // Try to open ROM file - BFile file(rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); - if (file.InitCheck() != B_NO_ERROR) { - - // Failed, then ask sheep driver for ROM - uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work - ssize_t actual = read(sheep_fd, (void *)rom, ROM_SIZE); - if (actual == ROM_SIZE) { - // Copy upper 3MB - memcpy((void *)(ROM_BASE + 0x100000), rom + 0x100000, ROM_SIZE - 0x100000); - delete[] rom; - return; - } else - throw file_open_error(); - } - - printf(GetString(STR_READING_ROM_FILE)); - - // Get file size - off_t rom_size = 0; - file.GetSize(&rom_size); - - uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work - ssize_t actual = file.Read((void *)rom, ROM_SIZE); - if (actual == ROM_SIZE) { - // Plain ROM image, copy upper 3MB - memcpy((void *)(ROM_BASE + 0x100000), rom + 0x100000, ROM_SIZE - 0x100000); - delete[] rom; - } else { - if (strncmp((char *)rom, "", 11) == 0) { - // CHRP compressed ROM image - D(bug("CHRP ROM image\n")); - uint32 lzss_offset, lzss_size; - - char *s = strstr((char *)rom, "constant lzss-offset"); - if (s == NULL) - throw rom_size_error(); - s -= 7; - if (sscanf(s, "%06lx", &lzss_offset) != 1) - throw rom_size_error(); - s = strstr((char *)rom, "constant lzss-size"); - if (s == NULL) - throw rom_size_error(); - s -= 7; - if (sscanf(s, "%06lx", &lzss_size) != 1) - throw rom_size_error(); - D(bug("Offset of compressed data: %08lx\n", lzss_offset)); - D(bug("Size of compressed data: %08lx\n", lzss_size)); - - D(bug("Uncompressing ROM...\n")); - uint8 *decoded = new uint8[ROM_SIZE]; - decode_lzss(rom + lzss_offset, decoded, lzss_size); - memcpy((void *)(ROM_BASE + 0x100000), decoded + 0x100000, ROM_SIZE - 0x100000); - delete[] decoded; - delete[] rom; - } else if (rom_size != 4*1024*1024) - throw rom_size_error(); - else - throw file_read_error(); - } -} - - -/* - * Patch PowerMac ROM - */ - -// ROM type -enum { - ROMTYPE_TNT, - ROMTYPE_ALCHEMY, - ROMTYPE_ZANZIBAR, - ROMTYPE_GAZELLE, - ROMTYPE_NEWWORLD -}; -static int ROMType; - -// Nanokernel boot routine patches -static bool patch_nanokernel_boot(void) -{ - uint32 *lp; - int i; - - // Patch ConfigInfo - lp = (uint32 *)(ROM_BASE + 0x30d000); - lp[0x9c >> 2] = KernelDataAddr; // LA_InfoRecord - lp[0xa0 >> 2] = KernelDataAddr; // LA_KernelData - lp[0xa4 >> 2] = KernelDataAddr + 0x1000;// LA_EmulatorData - lp[0xa8 >> 2] = ROM_BASE + 0x480000; // LA_DispatchTable - lp[0xac >> 2] = ROM_BASE + 0x460000; // LA_EmulatorCode - lp[0x360 >> 2] = 0; // Physical RAM base (? on NewWorld ROM, this contains -1) - lp[0xfd8 >> 2] = ROM_BASE + 0x2a; // 68k reset vector - - // Skip SR/BAT/SDR init - if (ROMType == ROMTYPE_GAZELLE || ROMType == ROMTYPE_NEWWORLD) { - lp = (uint32 *)(ROM_BASE + 0x310000); - *lp++ = POWERPC_NOP; - *lp = 0x38000000; - } - static const uint32 sr_init_loc[] = {0x3101b0, 0x3101b0, 0x3101b0, 0x3101ec, 0x310200}; - lp = (uint32 *)(ROM_BASE + 0x310008); - *lp = 0x48000000 | (sr_init_loc[ROMType] - 8) & 0xffff; // b ROM_BASE+0x3101b0 - lp = (uint32 *)(ROM_BASE + sr_init_loc[ROMType]); - *lp++ = 0x80200000 + XLM_KERNEL_DATA; // lwz r1,(pointer to Kernel Data) - *lp++ = 0x3da0dead; // lis r13,0xdead (start of kernel memory) - *lp++ = 0x3dc00010; // lis r14,0x0010 (size of page table) - *lp = 0x3de00010; // lis r15,0x0010 (size of kernel memory) - - // Don't read PVR - static const uint32 pvr_loc[] = {0x3103b0, 0x3103b4, 0x3103b4, 0x310400, 0x310438}; - lp = (uint32 *)(ROM_BASE + pvr_loc[ROMType]); - *lp = 0x81800000 + XLM_PVR; // lwz r12,(theoretical PVR) - - // Set CPU specific data (even if ROM doesn't have support for that CPU) - lp = (uint32 *)(ROM_BASE + pvr_loc[ROMType]); - if (ntohl(lp[6]) != 0x2c0c0001) - return false; - uint32 ofs = lp[7] & 0xffff; - lp[8] = (lp[8] & 0xffff) | 0x48000000; // beq -> b - uint32 loc = (lp[8] & 0xffff) + (uint32)(lp+8) - ROM_BASE; - lp = (uint32 *)(ROM_BASE + ofs + 0x310000); - switch (PVR >> 16) { - case 1: // 601 - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00010040; // Unified caches/Inst cache line size - lp[5] = 0x00400020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x01000002; // TLB total size/TLB assoc - break; - case 3: // 603 - lp[0] = 0x1000; // Page size - lp[1] = 0x2000; // Data cache size - lp[2] = 0x2000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00020002; // Inst cache assoc/Data cache assoc - lp[8] = 0x00400002; // TLB total size/TLB assoc - break; - case 4: // 604 - lp[0] = 0x1000; // Page size - lp[1] = 0x4000; // Data cache size - lp[2] = 0x4000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00040004; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; -// case 5: // 740? - case 6: // 603e - case 7: // 603ev - lp[0] = 0x1000; // Page size - lp[1] = 0x4000; // Data cache size - lp[2] = 0x4000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00040004; // Inst cache assoc/Data cache assoc - lp[8] = 0x00400002; // TLB total size/TLB assoc - break; - case 8: // 750 - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; - case 9: // 604e - case 10: // 604ev5 - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00040004; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; -// case 11: // X704? - case 12: // ??? - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800002; // TLB total size/TLB assoc - break; - case 13: // ??? - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00000020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x01000004; // TLB total size/TLB assoc - break; -// case 50: // 821 -// case 80: // 860 - case 96: // ??? - lp[0] = 0x1000; // Page size - lp[1] = 0x8000; // Data cache size - lp[2] = 0x8000; // Inst cache size - lp[3] = 0x00200020; // Coherency block size/Reservation granule size - lp[4] = 0x00010020; // Unified caches/Inst cache line size - lp[5] = 0x00200020; // Data cache line size/Data cache block size touch - lp[6] = 0x00200020; // Inst cache block size/Data cache block size - lp[7] = 0x00080008; // Inst cache assoc/Data cache assoc - lp[8] = 0x00800004; // TLB total size/TLB assoc - break; - default: - printf("WARNING: Unknown CPU type\n"); - break; - } - - // Don't set SPRG3, don't test MQ - lp = (uint32 *)(ROM_BASE + loc + 0x20); - *lp++ = POWERPC_NOP; - lp++; - *lp++ = POWERPC_NOP; - lp++; - *lp = POWERPC_NOP; - - // Don't read MSR - lp = (uint32 *)(ROM_BASE + loc + 0x40); - *lp = 0x39c00000; // li r14,0 - - // Don't write to DEC - lp = (uint32 *)(ROM_BASE + loc + 0x70); - *lp++ = POWERPC_NOP; - loc = (lp[0] & 0xffff) + (uint32)lp - ROM_BASE; - - // Don't set SPRG3 - lp = (uint32 *)(ROM_BASE + loc + 0x2c); - *lp = POWERPC_NOP; - - // Don't read PVR - static const uint32 pvr_ofs[] = {0x138, 0x138, 0x138, 0x140, 0x148}; - lp = (uint32 *)(ROM_BASE + loc + pvr_ofs[ROMType]); - *lp = 0x82e00000 + XLM_PVR; // lwz r23,(theoretical PVR) - lp = (uint32 *)(ROM_BASE + loc + 0x170); - if (*lp == 0x7eff42a6) // NewWorld ROM - *lp = 0x82e00000 + XLM_PVR; // lwz r23,(theoretical PVR) - lp = (uint32 *)(ROM_BASE + 0x313134); - if (*lp == 0x7e5f42a6) - *lp = 0x82400000 + XLM_PVR; // lwz r18,(theoretical PVR) - lp = (uint32 *)(ROM_BASE + 0x3131f4); - if (*lp == 0x7e5f42a6) // NewWorld ROM - *lp = 0x82400000 + XLM_PVR; // lwz r18,(theoretical PVR) - - // Don't read SDR1 - static const uint32 sdr1_ofs[] = {0x174, 0x174, 0x174, 0x17c, 0x19c}; - lp = (uint32 *)(ROM_BASE + loc + sdr1_ofs[ROMType]); - *lp++ = 0x3d00dead; // lis r8,0xdead (pointer to page table) - *lp++ = 0x3ec0001f; // lis r22,0x001f (size of page table) - *lp = POWERPC_NOP; - - // Don't clear page table - static const uint32 pgtb_ofs[] = {0x198, 0x198, 0x198, 0x1a0, 0x1c4}; - lp = (uint32 *)(ROM_BASE + loc + pgtb_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't invalidate TLB - static const uint32 tlb_ofs[] = {0x1a0, 0x1a0, 0x1a0, 0x1a8, 0x1cc}; - lp = (uint32 *)(ROM_BASE + loc + tlb_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't create RAM descriptor table - static const uint32 desc_ofs[] = {0x350, 0x350, 0x350, 0x358, 0x37c}; - lp = (uint32 *)(ROM_BASE + loc + desc_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't load SRs and BATs - static const uint32 sr_ofs[] = {0x3d8, 0x3d8, 0x3d8, 0x3e0, 0x404}; - lp = (uint32 *)(ROM_BASE + loc + sr_ofs[ROMType]); - *lp = POWERPC_NOP; - - // Don't mess with SRs - static const uint32 sr2_ofs[] = {0x312118, 0x312118, 0x312118, 0x312118, 0x3121b4}; - lp = (uint32 *)(ROM_BASE + sr2_ofs[ROMType]); - *lp = POWERPC_BLR; - - // Don't check performance monitor - static const uint32 pm_ofs[] = {0x313148, 0x313148, 0x313148, 0x313148, 0x313218}; - lp = (uint32 *)(ROM_BASE + pm_ofs[ROMType]); - while (*lp != 0x7e58eba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e78eaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e59eba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e79eaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5aeba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7aeaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5beba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7beaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5feba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7feaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5ceba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7ceaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5deba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7deaa6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e5eeba6) lp++; - *lp++ = POWERPC_NOP; - while (*lp != 0x7e7eeaa6) lp++; - *lp++ = POWERPC_NOP; - - // Jump to 68k emulator - static const uint32 jump68k_ofs[] = {0x40c, 0x40c, 0x40c, 0x414, 0x438}; - lp = (uint32 *)(ROM_BASE + loc + jump68k_ofs[ROMType]); - *lp++ = 0x80610634; // lwz r3,0x0634(r1) (pointer to Emulator Data) - *lp++ = 0x8081119c; // lwz r4,0x119c(r1) (pointer to opcode table) - *lp++ = 0x80011184; // lwz r0,0x1184(r1) (pointer to emulator entry) - *lp++ = 0x7c0903a6; // mtctr r0 - *lp = POWERPC_BCTR; - return true; -} - -// 68k emulator patches -static bool patch_68k_emul(void) -{ - uint32 *lp; - uint32 base; - - // Overwrite twi instructions - static const uint32 twi_loc[] = {0x36e680, 0x36e6c0, 0x36e6c0, 0x36e6c0, 0x36e740}; - base = twi_loc[ROMType]; - lp = (uint32 *)(ROM_BASE + base); - *lp++ = 0x48000000 + 0x36f900 - base; // b 0x36f900 (Emulator start) - *lp++ = POWERPC_ILLEGAL; - *lp++ = 0x48000000 + 0x36fb00 - base - 8; // b 0x36fb00 (Reset opcode) - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - *lp++ = POWERPC_ILLEGAL; - - // Set reset stack pointer - lp = (uint32 *)(ROM_BASE + base + 0xf0); - *lp++ = 0x80200000 + XLM_RESET_STACK; // lwz r1,XLM_RESET_STACK - - // Install EXEC_RETURN and EMUL_OP opcodes - lp = (uint32 *)(ROM_BASE + 0x380000 + (M68K_EXEC_RETURN << 3)); - *lp++ = 0x80000000 + XLM_EXEC_RETURN_PROC; // lwz r0,XLM_EXEC_RETURN_PROC - *lp++ = 0x4bfb6ffc; // b 0x36f800 - for (int i=0; i> 16); // lis r0,xxx - *lp++ = 0x60000000 + ((ROM_BASE + 0x46d0a4) & 0xffff); // ori r0,r0,xxx - *lp++ = 0x7c0903a6; // mtctr r0 - *lp = POWERPC_BCTR; // bctr - return true; -} - -// Nanokernel patches -static bool patch_nanokernel(void) -{ - uint32 *lp; - - // Patch 68k emulator trap routine - lp = (uint32 *)(ROM_BASE + 0x312994); // Always restore FPU state - while (*lp != 0x39260040) lp++; - lp--; - *lp = 0x48000441; // bl 0x00312dd4 - lp = (uint32 *)(ROM_BASE + 0x312dd8); // Don't modify MSR to turn on FPU - while (*lp != 0x810600e4) lp++; - lp--; - *lp++ = POWERPC_NOP; - lp += 2; - *lp++ = POWERPC_NOP; - lp++; - *lp++ = POWERPC_NOP; - *lp++ = POWERPC_NOP; - *lp = POWERPC_NOP; - - // Patch trap return routine - lp = (uint32 *)(ROM_BASE + 0x312c20); - while (*lp != 0x7d5a03a6) lp++; - *lp++ = 0x7d4903a6; // mtctr r10 - *lp++ = 0x7daff120; // mtcr r13 - *lp++ = 0x48000000 + 0x8000 - ((uint32)lp & 0xffff); // b ROM_BASE+0x318000 - uint32 xlp = (uint32)lp & 0xffff; - - lp = (uint32 *)(ROM_BASE + 0x312c50); // Replace rfi - while (*lp != 0x4c000064) lp++; - *lp = POWERPC_BCTR; - - lp = (uint32 *)(ROM_BASE + 0x318000); - *lp++ = 0x81400000 + XLM_IRQ_NEST; // lwz r10,XLM_IRQ_NEST - *lp++ = 0x394affff; // subi r10,r10,1 - *lp++ = 0x91400000 + XLM_IRQ_NEST; // stw r10,XLM_IRQ_NEST - *lp = 0x48000000 + ((xlp - 0x800c) & 0x03fffffc); // b ROM_BASE+0x312c2c - return true; -} - -static bool patch_rom(void) -{ - // Detect ROM type - if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot TNT", 8)) - ROMType = ROMTYPE_TNT; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot Alchemy", 12)) - ROMType = ROMTYPE_ALCHEMY; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot Zanzibar", 13)) - ROMType = ROMTYPE_ZANZIBAR; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "Boot Gazelle", 12)) - ROMType = ROMTYPE_GAZELLE; - else if (!memcmp((void *)(ROM_BASE + 0x30d064), "NewWorld", 8)) - ROMType = ROMTYPE_NEWWORLD; - else - return false; - - // Apply patches - if (!patch_nanokernel_boot()) return false; - if (!patch_68k_emul()) return false; - if (!patch_nanokernel()) return false; - - // Copy 68k emulator to 2MB boundary - memcpy((void *)(ROM_BASE + ROM_SIZE), (void *)(ROM_BASE + ROM_SIZE - 0x100000), 0x100000); - return true; -} - - -/* - * Initialize 680x0 emulation - */ - -static asm void *get_toc(void) -{ - mr r3,r2 - blr -} - -bool Init680x0(void) -{ - char str[256]; - - // Mac address space = host address space - RAMBaseMac = (uint32)RAMBaseHost; - ROMBaseMac = (uint32)ROMBaseHost; - - // Get TOC pointer - TOC = get_toc(); - - // Get system info - get_system_info(&SysInfo); - switch (SysInfo.cpu_type) { - case B_CPU_PPC_601: - PVR = 0x00010000; - break; - case B_CPU_PPC_603: - PVR = 0x00030000; - break; - case B_CPU_PPC_603e: - PVR = 0x00060000; - break; - case B_CPU_PPC_604: - PVR = 0x00040000; - break; - case B_CPU_PPC_604e: - PVR = 0x00090000; - break; - default: - PVR = 0x00040000; - break; - } - CPUClockSpeed = SysInfo.cpu_clock_speed; - BusClockSpeed = SysInfo.bus_clock_speed; - - // Delete old areas - area_id old_kernel_area = find_area(KERNEL_AREA_NAME); - if (old_kernel_area > 0) - delete_area(old_kernel_area); - area_id old_dr_cache_area = find_area(DR_CACHE_AREA_NAME); - if (old_dr_cache_area > 0) - delete_area(old_dr_cache_area); - - // Create area for Kernel Data - kernel_data = (KernelData *)0x68ffe000; - kernel_area = create_area(KERNEL_AREA_NAME, &kernel_data, B_EXACT_ADDRESS, 0x2000, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (kernel_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(kernel_area), kernel_area); - ErrorAlert(str); - return false; - } - emulator_data = &kernel_data->ed; - KernelDataAddr = (uint32)kernel_data; - D(bug("Kernel Data area %ld at %p, Emulator Data at %p\n", kernel_area, kernel_data, emulator_data)); - - // Load PowerMac ROM (upper 3MB) - try { - load_rom(); - } catch (file_open_error) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - return false; - } catch (file_read_error) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - return false; - } catch (rom_size_error) { - ErrorAlert(STR_ROM_SIZE_ERR); - return false; - } - - // Install ROM patches - if (!patch_rom()) { - ErrorAlert("Unsupported PowerMac ROM version"); - return false; - } - - // Create area for DR Cache - DRCacheAddr = DR_CACHE_BASE; - dr_cache_area = create_area(DR_CACHE_AREA_NAME, (void **)&DRCacheAddr, B_EXACT_ADDRESS, DR_CACHE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (dr_cache_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(dr_cache_area), dr_cache_area); - ErrorAlert(str); - return false; - } - D(bug("DR Cache area %ld at %p\n", dr_cache_area, DRCacheAddr)); - - // Initialize Kernel Data - memset(kernel_data, 0, sizeof(KernelData)); - if (ROMType == ROMTYPE_NEWWORLD) { - kernel_data->v[0xc20 >> 2] = RAMSize; - kernel_data->v[0xc24 >> 2] = RAMSize; - kernel_data->v[0xc30 >> 2] = RAMSize; - kernel_data->v[0xc34 >> 2] = RAMSize; - kernel_data->v[0xc38 >> 2] = 0x00010020; - kernel_data->v[0xc3c >> 2] = 0x00200001; - kernel_data->v[0xc40 >> 2] = 0x00010000; - kernel_data->v[0xc50 >> 2] = RAMBaseMac; - kernel_data->v[0xc54 >> 2] = RAMSize; - kernel_data->v[0xf60 >> 2] = PVR; - kernel_data->v[0xf64 >> 2] = CPUClockSpeed; - kernel_data->v[0xf68 >> 2] = BusClockSpeed; - kernel_data->v[0xf6c >> 2] = CPUClockSpeed; - } else { - kernel_data->v[0xc80 >> 2] = RAMSize; - kernel_data->v[0xc84 >> 2] = RAMSize; - kernel_data->v[0xc90 >> 2] = RAMSize; - kernel_data->v[0xc94 >> 2] = RAMSize; - kernel_data->v[0xc98 >> 2] = 0x00010020; - kernel_data->v[0xc9c >> 2] = 0x00200001; - kernel_data->v[0xca0 >> 2] = 0x00010000; - kernel_data->v[0xcb0 >> 2] = RAMBaseMac; - kernel_data->v[0xcb4 >> 2] = RAMSize; - kernel_data->v[0xf80 >> 2] = PVR; - kernel_data->v[0xf84 >> 2] = CPUClockSpeed; - kernel_data->v[0xf88 >> 2] = BusClockSpeed; - kernel_data->v[0xf8c >> 2] = CPUClockSpeed; - } - - // Initialize extra low memory - memset((void *)0x2000, 0, 0x1000); - *(uint32 *)XLM_RESET_STACK = 0x2000; // Reset stack pointer - *(KernelData **)XLM_KERNEL_DATA = kernel_data;// For trap replacement routines - *(void **)XLM_TOC = TOC; // TOC pointer of emulator - *(uint32 *)XLM_PVR = PVR; // Theoretical PVR - - // Clear caches (as we loaded and patched code) - clear_caches((void *)ROM_BASE, ROM_AREA_SIZE, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE); - return true; -} - - -/* - * Deinitialize 680x0 emulation - */ - -void Exit680x0(void) -{ - // Delete DR Cache area - if (dr_cache_area >= 0) - delete_area(dr_cache_area); - - // Delete Kernel Data area - if (kernel_area >= 0) - delete_area(kernel_area); -} - - -/* - * Quit emulator (must only be called from main thread) - */ - -asm void QuitEmulator(void) -{ - lwz r0,XLM_EMUL_RETURN_PROC - mtlr r0 - blr -} - - -/* - * Reset and start 680x0 emulation - */ - -static asm void jump_to_rom(register uint32 entry) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - mfcr r0 - stw r0,4(r1) - stwu r1,-(56+19*4+18*8)(r1) - - // Save PowerPC registers - stmw r13,56(r1) - stfd f14,56+19*4+0*8(r1) - stfd f15,56+19*4+1*8(r1) - stfd f16,56+19*4+2*8(r1) - stfd f17,56+19*4+3*8(r1) - stfd f18,56+19*4+4*8(r1) - stfd f19,56+19*4+5*8(r1) - stfd f20,56+19*4+6*8(r1) - stfd f21,56+19*4+7*8(r1) - stfd f22,56+19*4+8*8(r1) - stfd f23,56+19*4+9*8(r1) - stfd f24,56+19*4+10*8(r1) - stfd f25,56+19*4+11*8(r1) - stfd f26,56+19*4+12*8(r1) - stfd f27,56+19*4+13*8(r1) - stfd f28,56+19*4+14*8(r1) - stfd f29,56+19*4+15*8(r1) - stfd f30,56+19*4+16*8(r1) - stfd f31,56+19*4+17*8(r1) - - // Move entry address to ctr, get pointer to Emulator Data - mtctr r3 - lwz r3,emulator_data(r2) - - // Skip over EMUL_RETURN routine and get its address - bl @1 - - - /* - * EMUL_RETURN: Returned from emulator - */ - - // Restore PowerPC registers - lwz r1,XLM_EMUL_RETURN_STACK - lwz r2,XLM_TOC - lmw r13,56(r1) - lfd f14,56+19*4+0*8(r1) - lfd f15,56+19*4+1*8(r1) - lfd f16,56+19*4+2*8(r1) - lfd f17,56+19*4+3*8(r1) - lfd f18,56+19*4+4*8(r1) - lfd f19,56+19*4+5*8(r1) - lfd f20,56+19*4+6*8(r1) - lfd f21,56+19*4+7*8(r1) - lfd f22,56+19*4+8*8(r1) - lfd f23,56+19*4+9*8(r1) - lfd f24,56+19*4+10*8(r1) - lfd f25,56+19*4+11*8(r1) - lfd f26,56+19*4+12*8(r1) - lfd f27,56+19*4+13*8(r1) - lfd f28,56+19*4+14*8(r1) - lfd f29,56+19*4+15*8(r1) - lfd f30,56+19*4+16*8(r1) - lfd f31,56+19*4+17*8(r1) - - // Exiting from 68k emulator - li r0,1 - stw r0,XLM_IRQ_NEST - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Return to caller of jump_to_rom() - lwz r0,56+19*4+18*8+8(r1) - mtlr r0 - lwz r0,56+19*4+18*8+4(r1) - mtcrf 0xff,r0 - addi r1,r1,56+19*4+18*8 - blr - - - // Save address of EMUL_RETURN routine for 68k emulator patch -@1 mflr r0 - stw r0,XLM_EMUL_RETURN_PROC - - // Skip over EXEC_RETURN routine and get its address - bl @2 - - - /* - * EXEC_RETURN: Returned from 68k routine executed with Execute68k() - */ - - // Save r25 (contains current 68k interrupt level) - stw r25,XLM_68K_R25 - - // Reentering EMUL_OP mode - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Save 68k registers - lwz r4,56+19*4+18*8+12(r1) - stw r8,M68kRegisters.d[0](r4) - stw r9,M68kRegisters.d[1](r4) - stw r10,M68kRegisters.d[2](r4) - stw r11,M68kRegisters.d[3](r4) - stw r12,M68kRegisters.d[4](r4) - stw r13,M68kRegisters.d[5](r4) - stw r14,M68kRegisters.d[6](r4) - stw r15,M68kRegisters.d[7](r4) - stw r16,M68kRegisters.a[0](r4) - stw r17,M68kRegisters.a[1](r4) - stw r18,M68kRegisters.a[2](r4) - stw r19,M68kRegisters.a[3](r4) - stw r20,M68kRegisters.a[4](r4) - stw r21,M68kRegisters.a[5](r4) - stw r22,M68kRegisters.a[6](r4) - - // Restore PowerPC registers - lmw r13,56(r1) -#if SAVE_FP_EXEC_68K - lfd f14,56+19*4+0*8(r1) - lfd f15,56+19*4+1*8(r1) - lfd f16,56+19*4+2*8(r1) - lfd f17,56+19*4+3*8(r1) - lfd f18,56+19*4+4*8(r1) - lfd f19,56+19*4+5*8(r1) - lfd f20,56+19*4+6*8(r1) - lfd f21,56+19*4+7*8(r1) - lfd f22,56+19*4+8*8(r1) - lfd f23,56+19*4+9*8(r1) - lfd f24,56+19*4+10*8(r1) - lfd f25,56+19*4+11*8(r1) - lfd f26,56+19*4+12*8(r1) - lfd f27,56+19*4+13*8(r1) - lfd f28,56+19*4+14*8(r1) - lfd f29,56+19*4+15*8(r1) - lfd f30,56+19*4+16*8(r1) - lfd f31,56+19*4+17*8(r1) -#endif - - // Return to caller - lwz r0,56+19*4+18*8+8(r1) - mtlr r0 - addi r1,r1,56+19*4+18*8 - blr - - - // Stave address of EXEC_RETURN routine for 68k emulator patch -@2 mflr r0 - stw r0,XLM_EXEC_RETURN_PROC - - // Skip over EMUL_OP routine and get its address - bl @3 - - - /* - * EMUL_OP: Execute native routine, selector in r5 (my own private mode switch) - * - * 68k registers are stored in a M68kRegisters struct on the stack - * which the native routine may read and modify - */ - - // Save r25 (contains current 68k interrupt level) - stw r25,XLM_68K_R25 - - // Entering EMUL_OP mode within 68k emulator - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Create PowerPC stack frame, reserve space for M68kRegisters - mr r3,r1 - subi r1,r1,56 // Fake "caller" frame - rlwinm r1,r1,0,0,29 // Align stack - - mfcr r0 - rlwinm r0,r0,0,11,8 - stw r0,4(r1) - mfxer r0 - stw r0,16(r1) - stw r2,12(r1) - stwu r1,-(56+16*4+15*8)(r1) - lwz r2,XLM_TOC - - // Save 68k registers - stw r8,56+M68kRegisters.d[0](r1) - stw r9,56+M68kRegisters.d[1](r1) - stw r10,56+M68kRegisters.d[2](r1) - stw r11,56+M68kRegisters.d[3](r1) - stw r12,56+M68kRegisters.d[4](r1) - stw r13,56+M68kRegisters.d[5](r1) - stw r14,56+M68kRegisters.d[6](r1) - stw r15,56+M68kRegisters.d[7](r1) - stw r16,56+M68kRegisters.a[0](r1) - stw r17,56+M68kRegisters.a[1](r1) - stw r18,56+M68kRegisters.a[2](r1) - stw r19,56+M68kRegisters.a[3](r1) - stw r20,56+M68kRegisters.a[4](r1) - stw r21,56+M68kRegisters.a[5](r1) - stw r22,56+M68kRegisters.a[6](r1) - stw r3,56+M68kRegisters.a[7](r1) - stfd f0,56+16*4+0*8(r1) - stfd f1,56+16*4+1*8(r1) - stfd f2,56+16*4+2*8(r1) - stfd f3,56+16*4+3*8(r1) - stfd f4,56+16*4+4*8(r1) - stfd f5,56+16*4+5*8(r1) - stfd f6,56+16*4+6*8(r1) - stfd f7,56+16*4+7*8(r1) - mffs f0 - stfd f8,56+16*4+8*8(r1) - stfd f9,56+16*4+9*8(r1) - stfd f10,56+16*4+10*8(r1) - stfd f11,56+16*4+11*8(r1) - stfd f12,56+16*4+12*8(r1) - stfd f13,56+16*4+13*8(r1) - stfd f0,56+16*4+14*8(r1) - - // Execute native routine - mr r3,r5 - addi r4,r1,56 - bl EmulOp - - // Restore 68k registers - lwz r8,56+M68kRegisters.d[0](r1) - lwz r9,56+M68kRegisters.d[1](r1) - lwz r10,56+M68kRegisters.d[2](r1) - lwz r11,56+M68kRegisters.d[3](r1) - lwz r12,56+M68kRegisters.d[4](r1) - lwz r13,56+M68kRegisters.d[5](r1) - lwz r14,56+M68kRegisters.d[6](r1) - lwz r15,56+M68kRegisters.d[7](r1) - lwz r16,56+M68kRegisters.a[0](r1) - lwz r17,56+M68kRegisters.a[1](r1) - lwz r18,56+M68kRegisters.a[2](r1) - lwz r19,56+M68kRegisters.a[3](r1) - lwz r20,56+M68kRegisters.a[4](r1) - lwz r21,56+M68kRegisters.a[5](r1) - lwz r22,56+M68kRegisters.a[6](r1) - lwz r3,56+M68kRegisters.a[7](r1) - lfd f13,56+16*4+14*8(r1) - lfd f0,56+16*4+0*8(r1) - lfd f1,56+16*4+1*8(r1) - lfd f2,56+16*4+2*8(r1) - lfd f3,56+16*4+3*8(r1) - lfd f4,56+16*4+4*8(r1) - lfd f5,56+16*4+5*8(r1) - lfd f6,56+16*4+6*8(r1) - lfd f7,56+16*4+7*8(r1) - mtfsf 0xff,f13 - lfd f8,56+16*4+8*8(r1) - lfd f9,56+16*4+9*8(r1) - lfd f10,56+16*4+10*8(r1) - lfd f11,56+16*4+11*8(r1) - lfd f12,56+16*4+12*8(r1) - lfd f13,56+16*4+13*8(r1) - - // Delete PowerPC stack frame - lwz r2,56+16*4+15*8+12(r1) - lwz r0,56+16*4+15*8+16(r1) - mtxer r0 - lwz r0,56+16*4+15*8+4(r1) - mtcrf 0xff,r0 - mr r1,r3 - - // Reeintering 68k emulator - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Set r0 to 0 for 68k emulator - li r0,0 - - // Execute next 68k opcode - rlwimi r29,r27,3,13,28 - lhau r27,2(r24) - mtlr r29 - blr - - - // Save address of EMUL_OP routine for 68k emulator patch -@3 mflr r0 - stw r0,XLM_EMUL_OP_PROC - - // Save stack pointer for EMUL_RETURN - stw r1,XLM_EMUL_RETURN_STACK - - // Preset registers for ROM boot routine - lis r3,0x40b0 // Pointer to ROM boot structure - ori r3,r3,0xd000 - - // 68k emulator is now active - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Jump to ROM - bctr -} - -void Start680x0(void) -{ - // Install interrupt signal handler - sigemptyset(&sigusr1_action.sa_mask); - sigusr1_action.sa_handler = (__signal_func_ptr)(sigusr1_handler); - sigusr1_action.sa_flags = 0; - sigusr1_action.sa_userdata = NULL; - sigaction(SIGUSR1, &sigusr1_action, NULL); - - // Install signal stack - set_signal_stack(malloc(SIG_STACK_SIZE), SIG_STACK_SIZE); - - // We're now ready to receive signals - ReadyForSignals = true; - - D(bug("Jumping to ROM\n")); - jump_to_rom(ROM_BASE + 0x310000); - D(bug("Returned from ROM\n")); - - // We're no longer ready to receive signals - ReadyForSignals = false; -} - - -/* - * Trigger interrupt - */ - -void TriggerInterrupt(void) -{ - idle_resume(); - if (emul_thread > 0 && ReadyForSignals) - send_signal(emul_thread, SIGUSR1); -} - -void TriggerNMI(void) -{ - //!! not implemented yet -} - - -/* - * Execute 68k subroutine - * r->a[7] and r->sr are unused! - */ - -static asm void execute_68k(register uint32 addr, register M68kRegisters *r) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stw r4,12(r1) - stwu r1,-(56+19*4+18*8)(r1) - - // Save PowerPC registers - stmw r13,56(r1) -#if SAVE_FP_EXEC_68K - stfd f14,56+19*4+0*8(r1) - stfd f15,56+19*4+1*8(r1) - stfd f16,56+19*4+2*8(r1) - stfd f17,56+19*4+3*8(r1) - stfd f18,56+19*4+4*8(r1) - stfd f19,56+19*4+5*8(r1) - stfd f20,56+19*4+6*8(r1) - stfd f21,56+19*4+7*8(r1) - stfd f22,56+19*4+8*8(r1) - stfd f23,56+19*4+9*8(r1) - stfd f24,56+19*4+10*8(r1) - stfd f25,56+19*4+11*8(r1) - stfd f26,56+19*4+12*8(r1) - stfd f27,56+19*4+13*8(r1) - stfd f28,56+19*4+14*8(r1) - stfd f29,56+19*4+15*8(r1) - stfd f30,56+19*4+16*8(r1) - stfd f31,56+19*4+17*8(r1) -#endif - - // Set up registers for 68k emulator - lwz r31,XLM_KERNEL_DATA // Pointer to Kernel Data - addi r31,r31,0x1000 // points to Emulator Data - li r0,0 - mtcrf 0xff,r0 - creqv 11,11,11 // Supervisor mode - lwz r8,M68kRegisters.d[0](r4) - lwz r9,M68kRegisters.d[1](r4) - lwz r10,M68kRegisters.d[2](r4) - lwz r11,M68kRegisters.d[3](r4) - lwz r12,M68kRegisters.d[4](r4) - lwz r13,M68kRegisters.d[5](r4) - lwz r14,M68kRegisters.d[6](r4) - lwz r15,M68kRegisters.d[7](r4) - lwz r16,M68kRegisters.a[0](r4) - lwz r17,M68kRegisters.a[1](r4) - lwz r18,M68kRegisters.a[2](r4) - lwz r19,M68kRegisters.a[3](r4) - lwz r20,M68kRegisters.a[4](r4) - lwz r21,M68kRegisters.a[5](r4) - lwz r22,M68kRegisters.a[6](r4) - li r23,0 - mr r24,r3 - lwz r25,XLM_68K_R25 // MSB of SR - li r26,0 - li r28,0 // VBR - lwz r29,0x74(r31) // Pointer to opcode table - lwz r30,0x78(r31) // Address of emulator - - // Reentering 68k emulator - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Set r0 to 0 for 68k emulator - li r0,0 - - // Execute 68k opcode - lha r27,0(r24) - rlwimi r29,r27,3,13,28 - lhau r27,2(r24) - mtlr r29 - blr -} - -void Execute68k(uint32 addr, M68kRegisters *r) -{ - uint16 proc[4] = {M68K_JSR, addr >> 16, addr & 0xffff, M68K_EXEC_RETURN}; - execute_68k((uint32)proc, r); -} - - -/* - * Execute MacOS 68k trap - * r->a[7] and r->sr are unused! - */ - -void Execute68kTrap(uint16 trap, struct M68kRegisters *r) -{ - uint16 proc[2] = {trap, M68K_EXEC_RETURN}; - execute_68k((uint32)proc, r); -} - - -/* - * USR1 handler - */ - -static void sigusr1_handler(int sig, void *arg, vregs *r) -{ - // Do nothing if interrupts are disabled - if ((*(int32 *)XLM_IRQ_NEST) > 0) - return; - - // 68k emulator active? Then trigger 68k interrupt level 1 - if (*(uint32 *)XLM_RUN_MODE == MODE_68K) { - *(uint16 *)(kernel_data->v[0x67c >> 2]) = 1; - r->cr |= kernel_data->v[0x674 >> 2]; - } -} diff --git a/BasiliskII/src/rom_patches.cpp b/BasiliskII/src/rom_patches.cpp index fdedf5e2f..5cfb13e20 100644 --- a/BasiliskII/src/rom_patches.cpp +++ b/BasiliskII/src/rom_patches.cpp @@ -1040,7 +1040,7 @@ static bool patch_rom_32(void) if (PatchHWBases) { extern uint8 *ScratchMem; const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); - + D(bug("LMGlob\tOfs/4\tBase\n")); base = ROMBaseMac + UniversalInfo + ReadMacInt32(ROMBaseMac + UniversalInfo); // decoderInfoPtr wp = (uint16 *)(ROMBaseHost + 0x94a); @@ -1048,7 +1048,7 @@ static bool patch_rom_32(void) int16 ofs = ntohs(*wp++); // offset in decoderInfo (/4) int16 lmg = ntohs(*wp++); // address of LowMem global D(bug("0x%04x\t%d\t0x%08x\n", lmg, ofs, ReadMacInt32(base + ofs*4))); - + // Fake address only if this is not the ASC base if (lmg != 0xcc0) WriteMacInt32(base + ofs*4, ScratchMemBase); @@ -1280,20 +1280,13 @@ static bool patch_rom_32(void) #endif #endif -#if REAL_ADDRESSING && defined(AMIGA) - // Don't overwrite SysBase under AmigaOS - wp = (uint16 *)(ROMBaseHost + 0xccb4); - *wp++ = htons(M68K_NOP); - *wp = htons(M68K_NOP); -#endif - -#if REAL_ADDRESSING && !defined(AMIGA) +#if REAL_ADDRESSING // gb-- Temporary hack to get rid of crashes in Speedometer wp = (uint16 *)(ROMBaseHost + 0xdba2); if (ntohs(*wp) == 0x662c) // bne.b #$2c *wp = htons(0x602c); // bra.b #$2c #endif - + // Don't write to VIA in InitTimeMgr wp = (uint16 *)(ROMBaseHost + 0xb0e2); *wp++ = htons(0x4cdf); // movem.l (sp)+,d0-d5/a0-a4 diff --git a/BasiliskII/src/sony.cpp b/BasiliskII/src/sony.cpp index 804239b78..a8d8220d8 100644 --- a/BasiliskII/src/sony.cpp +++ b/BasiliskII/src/sony.cpp @@ -50,11 +50,7 @@ using std::vector; // Check for inserted disks by polling? -#ifdef AMIGA -#define DISK_INSERT_CHECK 1 -#else #define DISK_INSERT_CHECK 0 -#endif // Floppy disk icon diff --git a/BasiliskII/src/user_strings.cpp b/BasiliskII/src/user_strings.cpp index 1e608b27d..d15cf01d9 100644 --- a/BasiliskII/src/user_strings.cpp +++ b/BasiliskII/src/user_strings.cpp @@ -33,11 +33,7 @@ #include "sysdeps.h" #include "user_strings.h" -#ifdef __BEOS__ -#define ELLIPSIS "\xE2\x80\xA6" -#else #define ELLIPSIS "..." -#endif // Common string definitions diff --git a/SheepShaver/Makefile b/SheepShaver/Makefile index 0a511ff3a..eaf2cab19 100644 --- a/SheepShaver/Makefile +++ b/SheepShaver/Makefile @@ -59,9 +59,6 @@ links: include/prefs.h include/scsi.h include/serial.h \ include/serial_defs.h include/sony.h include/sys.h \ include/timer.h include/xpram.h \ - BeOS/audio_beos.cpp BeOS/extfs_beos.cpp BeOS/scsi_beos.cpp \ - BeOS/serial_beos.cpp BeOS/sys_beos.cpp BeOS/timer_beos.cpp \ - BeOS/xpram_beos.cpp BeOS/SheepDriver BeOS/SheepNet \ CrossPlatform/sigsegv.h CrossPlatform/vm_alloc.h CrossPlatform/vm_alloc.cpp \ CrossPlatform/video_vosf.h CrossPlatform/video_blit.h CrossPlatform/video_blit.cpp \ Unix/audio_oss_esd.cpp \ diff --git a/SheepShaver/doc/BeOS/acknowledgements.html b/SheepShaver/doc/BeOS/acknowledgements.html deleted file mode 100644 index 204e8d207..000000000 --- a/SheepShaver/doc/BeOS/acknowledgements.html +++ /dev/null @@ -1,24 +0,0 @@ - - -Acknowledgements - - - -

Acknowledgements

- -The following persons/companies deserve special thanks from us as they -made a significant contribution to the development of SheepShaver: - -

-

- -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/contact.html b/SheepShaver/doc/BeOS/contact.html deleted file mode 100644 index b4c000750..000000000 --- a/SheepShaver/doc/BeOS/contact.html +++ /dev/null @@ -1,47 +0,0 @@ - - -Contact Information - - - -

Contact Information and Copyright

- -SheepShaver was brought to you by - - -

SheepShaver WWW Site:

-
-www.sheepshaver.com
-
- -

EMail:

-
-Christian.Bauer@uni-mainz.de
-
- -

License

- -

SheepShaver is available under the terms of the GNU General Public License. -See the file "COPYING" that is included in the distribution for details. - -

© Copyright 1997-2004 Christian Bauer and Marc Hellwig - -

Names of hardware and software items mentioned in this manual and -in program texts are in most cases registered trade marks of the respective -companies and not marked as such. So the lack of such a note may not be -used as an indication that these names are free. - -

SheepShaver is not designed, intended, or authorized for use as a component -in systems intended for surgical implant within the body, or other applications intended -to support or sustain life, or for any other application in which the failure of SheepShaver -could create a situation where personal injury or death may occur (so-called "killer application"). - -


-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/graphics.gif b/SheepShaver/doc/BeOS/graphics.gif deleted file mode 100644 index 10a33553808ea9b69dd054448f4fe53f5cb227ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8854 zcmV;HB5B=6Nk%w1VVeO{0mJ|R|NsC0|7QRHGymg8|H}aXuM_C#=-AlU%a{Pbz`(e; zxS*h*n3$NDm;jh&0Emc)fPjE_cz9-J0AOHXSXfv41ejEjAQkdcy;k%kSIn3(Lsq@9ODr*V65?e%=260B`6DH?E*LJ;x9bK(K5dqJ#?@&VvP!;lwxj zF3MVyEuhDbwZ8o-xaMFUbQhriDRYJ)83GB%B&c~Ab0r215)`6TDeqWI0x*5Do4AZ7 z&Xo+=>||q9X3u%fph^|G5a!K!4V+z2c&8)CuV5jGB*&(JNjyd`I6%q}1JGw#Wx~94 zG-2GT$JDab;C7}lw=k8-g}6&eaU|b97XWQ`7(xwP zdz+3bF{kc7ew|@P)^z#>iuN{88y?Y^^)hrL)d{5T3#$>vNDg14J zyGPw;kAAwvCQVT5@yCY$LjvaKUmJ~WXWCqo@im)9bY%A4h8rd)4s-O4c1KpnIG~Vg zM$v{>iSpc(lNuxjXC78JT{V+Z z=-ftfI7H=@81;q7l1+9QRw|l=IVF~ESV<<8%fRH+mc)7Kre?adBIlVH?MUZFF}|1x zmv8pzk0EykDyX1*`e`UGfDWqYqS#C@!=sQ!D(R$@R%+>^jskGNrkr-_>8GHED(a}D zmTKy$sHUpws-Yh0DnJip%Id7N)@tjmxaO+suDtf@>#xA78Y=^uK49#z$R?}ovdlK? z?6c5DEA6z@R%`A5wb*8>?Y7)@>+QGR7AxxmmzHbpx#*^=?z-%@>+ZY69x!aN3>aYV zz4+#<@4o!@>+in+2Q2Ww1Q%@Z!3Za;@WKo??C`@2$2+gQ^#*J4#TaL-@x~l?>@lhm zk6ZD_B$sUR$tb6+GOHm=Jo3sg$1L;AG}mlu%k&yx^Ugf??DNmQ;!Ls5pDGZQ0zfCN z^wLbPEHt@9d#V8gn=+t*s8?^Ab=FOH?e*7Shx+u(opMbo*Jg*U_S$UwJa*KbT8%WP zMmvMFGY8;(wFY(19l>r_AylFJ$K-FbGmijS6h8R1Q-Z@Q{;lD zjrixFhc34NxGuw8GzL^tmpSL0?=3m&f&Wdx+@jZRd+3Uv&3f6dM~*h^St~$+1`*tD z{PAq(E_LIUPhIuoT1Wpo<_ajVIpL5aul@E)E8pqh*dM*A1zD5td+&eqef8knx9>jB z-e>Ij`}EhZa{RwqP`uH_+wcGXCc~evtjCxB0q}qb%$NWZ$iN0BZES+8o&+aI!3tXN zf*8!81~@P#mpp$un8!y1}^bo6qd4tEGN z2=efUK$MvegGj_8l5B`ZOrjDkhQuX0@rk%^J6yBy`>B*#l_{>q!2vRdOXhs;$4j&R}J z=BVJQHKgS;Rl(aE;j-DgRdI7u{G^=Z4mzuQqK%>Ztl29&8BC->Zkp%w9pG-Vzhl<_ zjRFz%Wjp&RP~wr4aLy?bK-xUC`i^SNliE&?Syr0b)p^4UX{cuUx}PRfu9J&^1u|OH$QkW! zFg-x?`d7}b)>5yotL#}Hdr!RXt$$-h?D;bLP02pft0)8OWtYjiYZeuHB_(R!EI`dq z<&>9dy&T?J`&xo(fVQUnUS8K~R^D3nmV#?uRCt@d$%S)k4&Ck62j1?_|hf7kc8Wp9x8)tAWOEdM3 z3d4J4>DB(GR-rlrq;IWorxI#fz*RPV=2IVt&xg?%1CON`WpO!IdQ;nOH^t#Q21uuO zj2s&`xPyDC`HV~04+}P!qK$HVp9)#J4fJ=t^)XkMD$#VN3b`huaXo7V(OjwdR&B=E zn|%dlU!gaEX6_};=6tF+pN!9719Yy2C*xk-xnw4unV{9S=&m)|XNNxjVxCWh=8`@7 zYnNVHrgs+UkAbz)CIdAq6?wQ$ckI(P6Ls56jp;qe>&K&q!=eiZ$1;EVi=UhgxAT``OxSHnJ%S?P`lo+VT?FsD^FrZfiQ&(+;b* z$9?N#XWM1lCbzmH3GQ>}kd5n(cc9xnF;T)Bj4x!hyn%)7dXMyuTC5ku0Hy$a@7vDw z*7m)tNVba={ND%XSicqCs(_o$Vh@kFr4x?sg;TNN7XBmulrKmpI4&UtUO4Igh>ntfoQt zDs_NjdBLo`70C4_vcuN10heS3uSThrb}m$F11 zGsse|QI;08@6QB#*yX%*vcp_=r1jlj2`u8gVmO(6?cLTW%U#LYb)kMQdfR^va_LPN z^SeC&1`54Xkq=(%g}3+NN5$SD_m;SKRo_3w8{6+{ZMn1UvezxwT*>1;Rh`eK*X4@3 z8BgH&ixm9ngEe;5H{Dc!D_-=8E8@VG6~idj{DYs2S);o)du?YK-y1*t$VDBR$ETa= zmw&P5<6PWF58vEe-#58y-<@xNY1_5z2x8;+6s}g+w_V;(OWntg5e(cA5srPk9bJ`FBpZ=)DMDaN2D~0z13HZB|X{Y zVqGSA9u`_0mUzCii@w-bm)D9a!-v#{g_UTDw75+FMO&LFeArcVxz&3xC3|KAKD}sk zK9yD9cw?bQQG*|yxC3LzDKAx$@ph0aDLAOLg)Z4`Fo|Xg@B=l;emA+3HQAFsS&~2*l;=2< zMA?c)d6asXluF5kOxcu9_>@q2gi<+`L0FalR@s7BsYM*5G+miAUkPa^d4|N6g*Ql( zC1aL0h?XRymNm$h9kZ2Gg?$N@k*ShCv=dHs69J^BmmEnvq^B`qsFHB$F@vcCF*!4b znFEOlGjjQKfpdOY2YhK2JezYlo``b<)K67KPuSF!3dx3RxLta8bGay(p~;Y=8B0R< zdlY$^z!HX+$c~u!J%6cFuNi(wSWMxTn0X~)C8c(OLy{p@Tb{_7firpwcAWiqR#*p` z>==j*S&K7gcjcEcve}N)$#c$`bvI>>s*;`3xth>eRfGdy)>(7ANr=4(YG)@si+2Fl zH(|`wjpAc_9{G53HFUiQp1Lxambj4r+r?jQ*LNHPpw3vEtR+6_SyB$yjI%g~py+*6 z=b-O2mVFp=i8qa~H%{89kLKxJ)rn%%F_+F+WQHk=v-ytAbbIkgkSeF53#p)(^?5G3 zWB!RMhdGNhx=_^gQ#Y!63>b+_hmxc+ebZN5fW?n=`J)J?O#+5s+1ENV7o{hIpb<)) z&lym#i7{AuiDPJs4eE^{sG3cyn zt0qaS4p^8#RB$KgGsxvR5>O^7rGwG_VQ}{FIxUiPHVFNQj=9(C$%ceD~S5ES#npt+}r4VYjSo4i{YMwr|s?q7UgVmj0*HbV{w%W?9Qlq$X z>RO)np_Z4lmWz+`x3rr3oFB8JD@scIIfpNrqpae&Gis^?3ba~x%r4_ohu^GQs zyP$Y0y`*a@U7NrE9@ejg%DflaxX`T6x4syn!~HMC;l!Pb|aj>chOLgtbbRn~JaZs)bv8mO%5E zuKAC^La@MuzGi2qX3Vz{d#`KEux(7m>}kctS}M;}m%So47j>BC?K zpVhglf+)ZLAR4vw+q|hP$b*ZU={dHCteuJ6USPYt>dCl2T%=fBO&_^mAx58+*P)K{ zospM|a4V!WCbt%Rbk%#p?KOM#ySRiKpwf(43|!57%eu&$&9+HZA;!(mY-9%f!s8%3r3>yJfSFBre^A}ip+@jX}|cKsNlS)vzN@}jHWWG&ph{|an;Y2 zY)(pCb+02}e)PV*+mquGf3AD%Eb(e+KU}GjeRy@oM969mj+AJpF*(bd%ksz zn5JFQx_#HZo!5|^q0lRJSG`PC`p0`5Hz4b=$sMCC8_5hz$;Exa&pp+^G<0l@c2G?# zkUZ6rjI(XM-KuiQ+LXykw#oK4RIzJ}mwPp%EY3)6qJV76gDTQoO3P?X-$%xESI5f# z`7NlDYPn%M()dlg!CkS-#M5V6w0Tp^a|^O<>&(2h(Xv~4;@waz9pKa~xYk_K*xb~r zJEk4J(#{*u6*_+@ZJ{1q#ol|sQ>)He!_N5UUET%H?JeKEOQj>)SGks_T@?wYNb|M*B>6z zt-QTMZqlY2z4d$H_LSkbb<{)y`AZknZNEBHBdM-D(Zq+6~r+-l?WK!Jl5|rB~hmogR*& zTk71);vhWbTm8oBYQiU7GjsjLcb-LjE!@ib*9;rjdzR}}RM;w+*u{>**xECij@i$) z?98rg&i?Gg7VXk*M%2DToNY7NZtI}UX~Hh8TAbQmEbeQG>j&Pm+}X``95gF6+d3tg zs;*l}Cd)HR>nfZwx9-Mxz1s2A+N}5QrtYF43z_n$Io#Bmf5qeVj_O@q*4iELl*sTd z+sxTr$Pl0JwmH-eZ}Cv>>Oc(ZSx#P>JXPQA$(XgdoWq>&Ew!+Vwr3#{}g6-dyH9zu}78 z%^nWYjvnHWKH>|%?+Yx>Njok3fG2V@>MdPYSb4RONWQBX#mrpy+xnB>^ zJu3ATj_KTe&?Y{Qt1jd{{@V$z(1WkiKyUVQtUJ78<-9}DC|%xIW~G!0VPD2el^*v~ zul2@#<^&9}YQFVsF1UWLqxK%>S(Ckre)^y`#RXqf;fn z)QJB1G9UW$-ROUNiI3|TW|dpOt^;cWf}~# zjg0*U&iKGS{j%Qc>F?L;U&G%%MZ1pRF#NqV6aVP${z1Rn2}JDwhzSCRIFhA#qN%zn zfcwJkI@7f+wy}QmeLbldfWu=VBr;S(AG7IvLZi|twQ9X$o50ku*iELE*)h3nKBLp> zwP=g#8ix-sO3c3F^ZGr%Pja8YeJS}B8Xh7hDjoou2+Gl&*ey~rDO_S^Vpg7LdR}sx ze0qkCG?qLf5tg#jC``b{%1%s%zRu3pa^B*`>Mov=q|U9XXdEA#XdEn?F*F}MMkGU zTNVKWvm^@}ile0tUI}gl2O>+->|hypJAO%f<`3gBjrh#}c#J`jgvEr%1pX_@>|_>s zBIp%M!EfWtYR4#S(-zR@%b-P(MbJlLpHP9zFeGG#&7jnvRjox-w@z8qfjIJUB$E=x z%B28dF8!Leqr`W$G$g@Fkg8X!b+OotCMS-nFf*tD<+*R>z$DVT(d_9pAXa5*;Z9qc z)Eeb!8ZZn#2`#LYvE|+x2CJ4SXDps&oFjdard(#p#J2sILax)btw&zTi_`Clotg=2 zuz<~XOn}sYE4@q8Af3uA_eCYx*mP`_wM4FVeKawe(_2yO3vG5gVc1&BnnjD4Btf1v zgX|r|+gJ&OgGEC=th_u;j`+p%Ls@&5Kt@%8;bk@d(OX@ymRV`kotIjDwmFDWb!45> z7;_U^8-Hw=lClu_Y;gO(NEp?8&N z9ddUDkP_xMWNZ9oailVFWhUd24?dw=e30bSik6~W_?al$uxHW%7EoD*li(SZ9W`Q- z$yS749(7!pgthr07gzRG$Ci6?`KFdIsBWnx`bH!Wyfrp}v9Vh^5Y&tFF7|!K#S$ zl+Y=!!xCF86TTYysx7AMi>!ZrZ z`PdoKu-NV~;k-cjju63VLFE&M#bV9wW)I|s$78O)> zX%<~=2QVbC4f)PY;aV9_{9S!#B{vO9G>SA?I>ok*&8`dC)nn z9AelFH{($1jV&3*oh2P)l17uJhQ^xFOW19%g)AEiv~l5+Wgvez zM@d{={xMm!flxYk((g};u6o=H@~n4-b|25O*`pON@xEV*up!;iMJ1-i; zb81GNy3;%~DX=(fN}VMh_?$T5267X8kEmLuG6Nnk4|hX{1z9n|L}(9JA-sd5wzrE& z{RxKrBA~y5wL(37>O7kQ)edzy!w#Cug*O}`5qFisl@&3GN`%!BLAb;xLXl5Rv|$vh zXvH7aYE(7U+7-nyEg#w9i_)6^7OetdtE`PcSY7nNwtAt)LbMSVZ)BFZ#)U;QYVm_q zGzRB>kMwxQMA|g*#=8C0%{+~y-p#I;!2tsCaC>xKf6U3a-mynD z%gdiJ0oRz|O%4ppOkOkpOZmCe!4jJoqNI30YRg#m^PkKZraMELJ#eB?1Y4Vs?fwI{ z{Sb$Dkip9Eh9^&Tk)Wpty5~R<@=WLfP^4Z$Q#7G@Qt1`-In_&8U8WQ}n9eSm1sRHB zz(=xo!U#sT1m^qR$3BLf&mU!d7Z{C)Px?7EmHjK_VoC~7xpuCUJB<>DtjfVGdN8Iz zTB9PP8bJ-xsgh3^Autyxf(AB8mNd)YD;cQRA7E98gk3CMD{(?aeD)Byl<8(;nbmg4 z(1fXlWM)-Z+GcWUj(y1CM0!};J38Wwr+qDNdpm{E4%WBA9j+Eyi$vlgH@TQiXaN_h z+~-2q1i+PTbgN7M*y*xBjMm+560xg-IOc-8;vJ%QXVcm7qSuJVbz+~QN{w{t(wieV zED!jB9W)B;vgs{idH<%@uLxGFr6GtkEGdj6Wi7w^6>fh!@n7imQkV$Y&SA4dBY#fj zC19b0etL2i@&t6juWfL9SJ_l}whSoxvFBHg0-&DBB?&4LaEvyh;^paA#499mMIKBf zW(a4iuTdxbMA2b~cFk-Y#&Keptm6@{*SRJ3+ghF>rr$J112;zTQvNqL`*cml`LOad zOhOkM-}KB+hB9-vn9J|#^l+eLwzS>}s_mIPlvfX#8jj{8ew>sz?ui02U zX32STh3G{8D{;~DUG1t6#q*uow*v5Rf&V!|%G%i8_NBDV?Qd_%+u$B|D8x%radp7$E$P49a7 z<02n9$x9A#j(7aIA8$j*4bbnG%Oc_^PdQ#-4s$20oDm_PfXRFAbCL7h05hlg)qZaD zqf1=>;m%IMz#-1_*g`$(Qs)!{faVe*`3{N;U+d8aFW^n>?2S4 zUF)463PfMYX+ZTsT=-qz{sG|o`JDFI0QdP`@g1M|(yV+ zC7=QP-wP_=622b3W(tx{@xqg; z7s4SSq8}hOq8{GhJoKRo{NV~tVhuhbB--5=ZlcI3;tViiD01Q;dg2d&qA6nk+$gR< zDY9b8Nnt96;VQ;r#ku0r8KCB|f(_E5DpD67?BVuZBGV-v10Z8ED&sOTV>3GAGeToD zcH%E$q5(wXHDY5nYU40YU@`7u#MvCo$y_B8VmQ7W&UxdiwA?M~o%vB?2-O}twj(*d zW3;8CbRk?m>f=7TV?8cQ&M|^H3M4)HW2^vVLBiWXA|$&hSWYukw&_n7d${v3gu7|WlIXl4V)iTnGRFJNhEL2mk;8 diff --git a/SheepShaver/doc/BeOS/history.html b/SheepShaver/doc/BeOS/history.html deleted file mode 100644 index 8d016a739..000000000 --- a/SheepShaver/doc/BeOS/history.html +++ /dev/null @@ -1,59 +0,0 @@ - - -Revision History - - - -

SheepShaver Revision History

- -

V2.2 (04-Feb-2002)

-
    -
  • Integrated code from Basilisk II -
  • Source released under GPL -
- -

V2.1 (31-Mar-2001)

-
    -
  • Support for MacOS 8.5 and 8.6 -
  • Support for G3 ROMs -
  • It's possible to select which video modes are to be used by MacOS -
  • SheepShaver will not use up all CPU time when "nothing" is running -
  • More stable networking -
  • 16 and 32 bit window modes -
  • Small bug fixes -
- -

V2.0 (20-Jan-1999)

-
    -
  • "BeOS" icon on the Mac desktop to access files on BeOS volumes from Mac applications. -
  • Handling of removable media (i.e. automatic detection of disk insertion) -
  • More flexible parallel port selection on BeBox -
  • Greatly improved Time Manager (higher accuracy) -
  • Fixed "audio lags" -
  • Option to ignore illegal memory accesses -
  • Adapted for (and requires) BeOS R4 -
  • MacOS 7.5.5/7.6/7.6.1 run better on some systems -
  • Small bug fixes -
- -

V1.1 (13-Jul-1998)

-
    -
  • Support for more machine types (esp. PowerMac 4400) -
  • Corrected time zone handling -
  • Volume list in preferences handles dropped volumes and files -
  • BeBox: 16/24 bit modes have correct colors with a Millennium II -
  • Video/SetEntries didn't set last palette entry -
  • Mac programs trying to use the (non-existant) SCSI Manager shouldn't crash any longer -
- -

V1.0 (18-May-1998)

-
    -
  • Initial release -
- -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/icon.gif b/SheepShaver/doc/BeOS/icon.gif deleted file mode 100644 index 51368b117dcc38bde6f0ac4457387bad5fd31efa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2011 zcmaJ=X;@QN8a`ma0F_2r3>syr9YKRdt|&{30R{<-bXXM(#fag`B9wN_V^q{=A+nS) zsfZV0#voXrBBWwjq{C8V8oAmAiW&hU$f^ipfwK6(o$vCizvetio}BZ2@B6*)d+zn~ z-{b0bh=+J+7SW5zWU^Q+Hk)l@V`Fb`@8sm<>gvkl@%VgxP*6}rM1)W%jEjp)NlB4N zBvPp~BO^mDmlFh`R4U8L%2X;|kNQ7=9l#h_~&oxl?|H}kMQ4~pkNRlE*3MVOyq!2+- z1Vs`QK~OkBVFZP6ioz)prwE+FaSFpJ1W1e`F$ySfjKVMq0fy!P5Ol#YfdGbZ5~$%z zk_1V@1|vyCchP%-AaR1k2okzrHk1jR#BmbCNd!8e6(b3Z#4!@XNCXOKfuIN^z)T$Y z2?Xu5R-gku_zws~OQ6|d;RJyZ&_z3eVX((>0s|blg27P32pl6Yj6lOOM7yU8U=ch4 zKZbAwwrSxs9@K#xMEj$)0v+%H0jK~`P=^Cp7>*;FgLVSLV2@!qTm?m;<#g#>FsjN7 ze!wS$NT))p0RVVKba=FL5C?cr2SUIx42Nkz2YiSYNaq4|IDm!d`=PUdxPcZNf(Yn? zXM-Zqa_SH>j2zfQz+Iu`oah9h6MFgwh`9o2M@W?i-#R zic7x%^t*tVP&4B2RmzsHm}XlzOr@cy==DG&aQ87d8f;)d}O`ax5d5+ zmSaSjy0a+YoMZTxj7;aD_B`&vrR?}a!}qTmgztQW&0Ci<*+gX&99V;ZCKXNIro zUx}_mv&SxUWQBW5obpD4+sd(8U5{6`|Pg#`jX8>{Fac7IeC4C*4yGZGV_lkcxjp&WfAFXJ(c~kUE;ak3$_VG zO3O`lB3+u|d+qx%*Ie!he5O7t)uy`WB!^}0OS8Rcp87`3AwK#+C8EbOUzO|(=sZ$< zWv}I(flH!24lPHf%DZ%zk0z&-Twx1?I?fkvA1p~TKQK3tA9_IktwG}5@*B#eb!$fo z4?Z>ul`e|Ph+WO))@6wFdjTFoewti<>^!DY;RHgAey7hB+_vXsW6Yg$F=foLdePM*x!$6%ppr4(*sW=> zV3}7Xc^#Nf+U-1%nC!VRcwSl>65=u0V2EX{_47OH+kQ&+u4rIq zXPVV7DNcp?_~me&o5Xs;NZ;{&Y3vrmeg=B5VaKNGl{-!es~@_(c^&kt>0+<5@57mH zdFQ&7K6>8tmrqu5IL2rAFEHOm{k6M}omu#@a(DRU z|K8nL8u@mGv~i&ZV=f`p`o%-iv)n{A_3DVnUu~{`c-SFOkFvet>R)x%BED}$NN^im7Uc>;BI}E)Gt^X6-P!)J4+j7_sV6a_ti!lzWIs!y(ZnM@L%sW zH~9IOYFR5>D|F9n#JSOr_F4x%@RL0rzMCgBxqu4!KE$Zr<}ItTKFfV!GIPjr>lT## zUY8v@slDlNz9aidJ>m6g-|CtEAUi<`&-@wN*W#D2WB;*9uwm@@&l#^LL!y2(H5sa7 z)%R;WSZ+|`ltE>Hf ze^XOab8~Yb5a{ge4242Mh;TR@iA18&==k_}EEbE$PrG%0~ z38A=9Oeo??aV5DDTyd@#SAw2&Q9n$(VSHJ-e0AK-9 zh~of@aZVaTD?u~t8RHm*Qncc(_Jyg>*Wd>_VWM_Lvq1s0k~U8(2RYP(9f&|Nnxh-w zfJd63_62bqV3D4W_5yYT779TEdAJ)&(u(V_87+S;6POjP_@o^~DpbPG6=jg3D^Ujn zR=8*v00a~e)f)8V^)N7R+#OY@zX1I$kOi>^a?7LPiB{Y@cRV`ers@2`w|z$NdKVSu zRr)zusO5s2V#@MZSOtSoH9>iRo|bV zekHGGdGe0Azx4dlm1MOi-BxxafA6$sXM2nJla!EA*N;l3hOp zJwvy8{hJo|RP=w*ej~c^P*0bq>w3mV-mT87Gsh24Wj%R!WJ_l3Vn*ceO}?LPDYL&! z6wHsf4h*;58aGugpNsnUcMY3%E?qh}ai_JSyZ6nz*LDwG8@<1olCG0irOo93Pf$`zLPS zun~xEtHSRbi8rRR3R1L0OEq;8>8ab8se(l_z z`a$1~Zx6Ow2QJQeDtDw^+HLaJ8^OlWd(|JC;tNliPj4?af)719mRDxoVl;R%il3{! Kyw<#mUj7$_>qdM4 diff --git a/SheepShaver/doc/BeOS/index.html b/SheepShaver/doc/BeOS/index.html deleted file mode 100644 index 523283335..000000000 --- a/SheepShaver/doc/BeOS/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - -The SheepShaver User's Guide - - - -

SheepShaver V2.2 Installation and User's Guide (BeOS)

- -

Contents

- - - -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/installation.html b/SheepShaver/doc/BeOS/installation.html deleted file mode 100644 index 105d9c8f7..000000000 --- a/SheepShaver/doc/BeOS/installation.html +++ /dev/null @@ -1,25 +0,0 @@ - - -Installation - - - -

Installation

- -You need BeOS/PowerPC R4. R3 or earlier versions will not work. - -
    -
  1. Unpack the SheepShaver package (if you are reading this, you probably have already done this) -
  2. On a BeBox, you need a copy of a PCI PowerMac ROM (4MB) in a file -called "ROM" in the same folder SheepShaver is in (but you can select a different -location in the settings window). SheepShaver can also use the "Mac OS ROM" file -that comes with MacOS 8.5/8.6 (look in the System Folder on your MacOS CD). In -order to legally use SheepShaver, you have to own the ROM the image file was taken from. -
- -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/introduction.html b/SheepShaver/doc/BeOS/introduction.html deleted file mode 100644 index f33567870..000000000 --- a/SheepShaver/doc/BeOS/introduction.html +++ /dev/null @@ -1,45 +0,0 @@ - - -Introduction - - - -

Introduction

- -SheepShaver is a MacOS run-time environment for BeOS that allows you -to run MacOS applications at native speed inside the BeOS multitasking -environment on PowerPC-based BeOS systems. This means that both BeOS -and MacOS applications can run at the same time and data can be exchanged -between them. - -

SheepShaver is neither a MacOS replacement nor an emulator. It runs an -unmodified PowerPC MacOS under control of the BeOS at full speed without -any kind of emulation. So it also uses the MacOS 68k emulator to run 68k -applications. In this way, SheepShaver is comparable to the "Blue Box" of -Apple's Rhapsody operating system. - -

Some of SheepShaver's features:

- -
    -
  • Compatibility: SheepShaver runs MacOS 7.5.2 thru 8.6 with all system - extensions like AppleGuide, AppleScript, QuickTime, QuickTime VR, - QuickDraw 3D, Open Transport, PPP, Language Kits, ColorSync, etc. -
  • Graphics: The MacOS user interface is displayed in a BeOS window or - full-screen (with QuickDraw acceleration) in resolutions up to - 1600x1200 in 24 bit. -
  • Sound: CD-quality stereo sound output -
  • Networking: SheepShaver supports Internet and LAN networking via - Ethernet and PPP with all Open Transport compatible MacOS applications. -
  • Volumes: Any HFS or HFS+ volume can be used with SheepShaver (this - includes Zip/Jaz/SyQuest drives etc.). It also features a built-in - CD-ROM driver and a driver for HD floppy disks. -
  • Data Exchange: You can access BeOS files from the MacOS via a "BeOS" - icon on the Mac desktop and copy and paste text between BeOS and MacOS -
- -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/memory.gif b/SheepShaver/doc/BeOS/memory.gif deleted file mode 100644 index 9867b003e7f6922b967f969903d0154343e986f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5510 zcmV;16?y7MNk%w1VVeO{0mJ|R|NsC0|7QRHGymg8|H}aXuM_C#=-AlU%a{Pj$jHFJ zz__@$u&}V8prDwTn3$LVm}UTwkdTOoh=72AczAebnEz&G0AOHXSXfv41ejEjAQkdcy;k%kYKn3(L&u@9ODr*V65?e%=260B`6DH?E*LJ;x9bK(K5dqJ#?@&VvP!;lwxj zF3MVyEuhDbwZ8o-xaMFUbQ_@mDRagl83GH(EU0-Ib0r5478IgXDeqWI0x*5Do4AZ7 z&Xo+=>||q9X3u%fph^|G5a!K!51egKc&8)CuV5jGB*&(JNjye3KtRfn1JGw#Wx~94 zG-2GT$JDa*;C7}lw=k8-g}6&eaU|b97XWQ`7(x$R zdz+3bF{kc7ew|@P)^z#>iuN{88y?Y^^)hrL)d{5T3#$>vNDg14J zyGPw;kAAwvCQVT5@yCY$LjvaKUmJ~WXWCqo@im)9bY%A4h8rd)4s-O4c1KpnK%kIo zM$v{>iSpc(lNuxjXC78JT{V+Z z=-ftfI7H=@81;q7l1+9QRw|l=IVF~ESV<<8%fRH+mc)7Kre?adBIlVH?MUZFF}|1x zmv8pzk0EykDyX1*`e`UGfDWqYqS#z8!=sQ!D(R$@R%+>^jskGNrkr-_>8GHED(a}D zmTKy$sHUpws-Yh0DnJrs%Id7N)@tjmxaO+suDtf@>#xA78mj}EN?`1<$R?}ovdlK? z?6c5DEA6z@R%`A5wb*8>?Y7)@>+QGR7Ava+mzHbpx#*^=?z-%@>+ZY69x!aN4j5qX zz4+#<@4o!@>+in+2Q2Ww1Q%@Z!3Za;@WKo??C`@2$2+gQ^#*J4#TaL-@x~l?>@lhm zk6ZD_B$sUR$tb6+GOHm=Jo3sg$1L;AG}mlu%k&yx^Ugf??DNmQ;!Ls5pDqy90zfCN z^wLbPEHt@9d+LD$n>yfus8?^Ab=FOH?e*7Shx+u(opMbo*Jg*U_S$UwJa*KbT8%WP zMmvMFGY8;(wFh<2O~ElnA5b^nZ5M9%;k>>r_AylFJ$K-FbGmijS6h7m1sn)|Q{;lD zjrixFhc34NxGuw8GzU~umpSL0?=3m&f&Y!c+@jZRd+3Uv&3f6dM~*h^SucQr2Nc|H z{PAq(E_LIUPhIuoT1Wpo<_j#aIpL5aul@E)E8pqh*dM*A23eEud+&eqef8knx9>jB z-e>Ij`}EhZa{Rw)P`uH_+wcGXCc~evtjCxB0q}qb%$NWZ$iN0BZES+8o&+aI!3tXN zf*8!81~@P#mpp$un8!y1}^bo6qd4tEGN z2=efUK$MvegGj_8l5B`ZOrjDkhQuX0@rk%^J6yBy`>B*#l_{>q!2vRdOXhs;$4j&R}J z=BVJQHKgS;Rl(aE;j-DgRdI7u{G^=Z4mzuQqK%>Ztl29&8BC->Zkp%w9pG-Vzhl<_ z4FeJNWjp&RP~wr4aLy?bK-xUC`i^SNliE&?Syr0b)p^4UX{cuUx}PRfu9KsH1~OXI$QkW! zFg-x?`d7}b)>5yotL#}Hdr!RXt$$-h?D;bLP02pft0)8OWtYjiYZeuHB_(R!G(gQy z<&>9dy&T?J`&xo}fVQUnUS8K~R^D3nmV#?uRCt@d$%S)k4&Ck62j1?_|hf7kc8Wp9x8)tAWOEdM3 z3d4J4>DB(GR-rlrq;IWorxI#fz*RPV=2IVt&xg?%1CON`WpO!IdQ;nOH^t#Q21uuO zj2s&`xPyDC`HV~04+}P!qK$HVp9)#J4fJ=t^)XkMD$#VN3b`huaXo7V(OjwdR&B=E zn|%dlU!gaEX6_};=6tF+pN!9719Yy2C*xk-xnw4unV{9S=&m)|XNNxjVxCWh=8`@7 zYnNVHrgs+UkAbz)X+~bB!3JukjhbVhw%Mr}ZM#xyy2O(vm8&f+YSGR5)u5D@$VT<5 zUT-LLZJNZW(s=7L8k>`1jrARm&20Cfme|dXw)UQ_Y*%?( zzfJD8QG44tWMjG49m#N`8;j~@x4bd!?um&q-t*2ku1ELod$&s808iSv?LE?E2mIhX z8~CpAjWu$f%9y_#vrn-p+sFdb%PL0r`!FhTY$}&=rBXPz8D7nY-VCcT9dUyL`el<# z&YynPIO3dlPo%+jp*Rm{$m_lEf1eGjCGFo#9j;St;uo<%FB>)gW6NcN%G_`@m#fy2 zu5(g}Jl#GY6=@F}Sq^`gr3(f7cS(!!9Up)LU3U7@3kP^l5TSe~X$9fI9?*1bB` z?2+whK4Xq}rqMjXucJKYimYA8_q>p$`Yw)FI#7r=uH)RzJ@k+qc)V$u^rh$7P!GT5 zs1)4DuCF`ngU@`AT^-(bZ@%;|_I!UYfBM)DR`riR?(BPiSKF8T_s8#Mx?}zNLxj!T{}| zi1&hrzSfDpCW3BAf(92lnusrW2!PuIgoB7UikJZZuK0?s2z;nWZ=tw_N7gnJkc+yw zi@7L^v)DAMIEpjpg1?w;fv9||Sd8=+jMk=%|Hq8o=Zxu_bp1sXfW0QUzs^akq2uNPtqq zko%QUte278lQoOiPYYI(<#du3riJlXO(gkwf#-QBiI3SNVC}?AH`$UT7Lji_k)VQm zuSJeIsgu;vQtPNqG=-E9Ns0Yti`|%%`X-S7R*8LBnU&JFm0ZbuUip=!7nWkVc4S$W zGIy3}iEwJUmI2q6Zh4h5DUxvsaBx|d@&=b2gqOyqmlyDtfEk!xz?Wy_mpqV-gh@q) z*#RA31B|IDq~wcthkB-xOb%x;6_=RnH<$7!Oo##1Z3TAkj zxpm(4I(Zjj7FnOYMO^%eWT2N#OF3KrbMsqwvs?n&oSYeip81@i`Iy_Ko$zU%dMBM3 z7FmJCOz7D;KiNA2re80YHUkA*J8F=b}vC>SGz{oH=ld_#~Nq26H9Dq^uc$QaON~`8}u=OAv>V zx{{?ILugTIX9=2&()0sgx@rbOwc*w&_UI!1I_r(blZcxt9_ z+Ki&ImwUQIekquOS(Sn6KS+uLhZ`qLqnRjEa0hDT;nNSbo5sc2ugKH+&pP ze22xH9amdA_o{g%Vl@SY$Mcl~raoQ-)*?fHXv^ zoDu7eX)`z{D^1}upkJ3?yZ5X;HKQ7Pt5iuU3lMBJu&A}lKz=!sLCZsWNv1^`M0%RE zf(o$J$h3Cqv_K2BQ?#`IR9i$=+dz@HwOre^DkPxp{X4Yzo=36!^c8@RX7w^D1UcEI|z)cvqT$AP-%O6r*ac#nr(BrnR~itu(?wzh;d4qfrELNS8?-+ zWrt(BsC&C&pt@mOiBo&5<7klC`m8nURUa~VgWrWqAWmYr);yvJL; zLXf<1!@Hm+ULq!*i@sH(z6h+q5PSm+ELjdrMFJeb);qz= zJ4HR4wD-%obeTj8fWajE!K;gmt$VdqEVKta!&)T6Hhe%hoWuXK z!#r$1KK#S<6U0L7Y&BfOPDI2=oQg-h#7U&YPJBF29L2_X!V;OQR7^xuoW-KE#axVR zAk48}+(2GD#)nhJX3R=WoW?P{#%xT(_?yCS3_xf+$6-^)c1(+5?6`T1sBYZHejLYG z49GqF$Amn@hJ46IEXVsdgM7-y)5)w1Gp_u~Dih1Hj54%b%b}LZQ;W;yX3D(mNxuBccO1;ZtjDR0 ztBqXDYOKqKtIU#2%+73T&>YQ5bIa5$XVZMmKV!|>tbN(s%?bC-;QYzVJkGsb&gKlv z=$y{Oyw2=w%)2|4o%_!FcFa3V&+x3g6^zfoD9-#WOaA=Ne-_XJO>6F4(9e9(2wlkv zz0l#@&<;(`dz`-!y=Men(Hg_e7=0=lz0n{!(Q@q3vwYDa?adHf(j$G+C~eCmz0!u( z(k=~tFdft7r_wb2F&%x=2sP6>-I_ez)8_QkK)ov5NVi6P)JUDwO1;!f-PBI~)KDGO zZY#C_Lk&N?Th%+GT3D@1^1RjEbJbowNnjn;gEZD;&DB(T)>hrsYQ5HJ-PUEs)^Huy zZ_QRxeb<2b&#H9+UMoVY_RD*{01z|S1k=Iz9N2`N*Z^bL^o-c{g4a!bFN|H6kj>P! z;@B6U*qZ&=_A=RSnc17I*ni!?a?MtPZ2*}KC!p=wYnj?#GTIbe+97w^uKg8~wc4<) zjkOIDw@oXUZ2&b8+7ENvot@j(=-R^VFugr1za8Ak%`n7m0IZFc$o6wV-t|2&=dCLL z^j$Ct;0y|2FCGvu1)ebXZQRnR-v-kF&d>n+a^MH9F#Vk>|4lF+FyIbO;08|N?JeC3 z?u-mhFb)pkCEhO+j^N?#+uDs#-0j>LKH&G_3;?VTs>P;{Kehe~>N{u*PIRG z0KVZ~J^?iDSx(toelS6901A)+IbP&o?%`rC+g9h~1~cb5?&Sp@=qZlm1(V?K zZRQ1Y;!oFw=lkU6050J6k^u#-<{qHwY;FLa?&ct#=udty4t@;(8?NSe zp6P~u=#q}!V{YmD&EFr6-{>0W30Kr3vmP*ruH}jz?Eb>*4;SlYUh2kv z?6n@^%J}2Wt}n=bGs=$IxIXRtGVE|(?Ao3$)m|zW{_Xq1?QtpX_;Ue|rj*)|jdJr3vh4g>Sfy7m6pm95m04eik$@JW5y*PiYLW9!}Q*a~0R1Ru(Q z-Pa%#@t&;J1|QXW&E#|KFCpYlwE@+==LEwt}4Kl3zS z^EQ9;k`hWKyz@LC3GepuH8U*WGW0}W^hSU5NT2jdzw}Js^vja*P#^URQa|-nU-edB I^&tQNJBtH3EC2ui diff --git a/SheepShaver/doc/BeOS/quickstart.html b/SheepShaver/doc/BeOS/quickstart.html deleted file mode 100644 index 62f9be15c..000000000 --- a/SheepShaver/doc/BeOS/quickstart.html +++ /dev/null @@ -1,38 +0,0 @@ - - -Quick Start - - - -

Quick Start

- -The following is a step-by-step guide that shows you how to get SheepShaver -up and running in the quickest possible way. We assume that you are running -on a PowerMac that already has MacOS installed on a partition of your hard drive -and that you have booted into BeOS. - -

-

    -
  1. Double-click the SheepShaver icon. The "SheepShaver Settings" window will appear. -
  2. Click on "Start". SheepShaver will try to detect on which partition MacOS is installed and should then start booting MacOS. -
  3. If this is the first time you start SheepShaver you will be asked if you want your -network configuration to be modified to enable Ethernet networking under SheepShaver. -If you want to use Ethernet with SheepShaver you should press "OK" (this will change the -file /boot/home/config/settings/network; a backup of the the original file will -be stored in network.orig). -
  4. To quit SheepShaver, select "Shutdown" from the Finder's "Special" menu. -
- -

One word of caution:

- -Volumes which are used by SheepShaver must not also be mounted under BeOS -while SheepShaver is running. You will lose data and corrupt the -volume if you do this! Don't press the "Mount all disks now" button in the -BeOS "Disk Mount Settings" window while SheepShaver is running! - -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/serial.gif b/SheepShaver/doc/BeOS/serial.gif deleted file mode 100644 index b491d769dea310cfd695607bf91ca7b1749fd6cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4844 zcmV41ejEjAQkdcy;k%kSIn3(Lpp@9ODr*V65?e%=260B`6DH?E*LJ;x9bK(K5dqJ#?@&VvP!;lwxj zF3MVyEuhDbwZ8o-xaMFUbQhriDRYJ)83GB%B&c~Ab0vlh5)`6TDeqWI0x*5Do4AZ7 z&Xo+=>||q9X3u%fph^|G5a!K!4V+z2c&8)CuV5jGB*&(JNjyd`I6%q}1JGw#Wx~94 zG-2GT$JDaT;C7}lw=k8-g}6&eaU|b97XWQ`7{Ux( zdz+3bF{kc7ew|@P)^z#>iuN{88y?Y^^)hrL)d{5T3#$>vNDg14J zyGPw;kAAwvCQVT5@yCY$LjvaKUmJ~WXWCqo@im)9bY%A4h8rd)4s-O4c1KpnIG~Vg zM$v{>iSpc(lNuxjXC78JT{V+Z z=-ftfI7H=@81;q7l1+9QRw|l=IVF~ESV<<8%fRH+mc)7Kre?adBIlVH?MUZFF}|1x zmv8pzk0EykDyX1*`e`UGfDWqYqS#C@!=sQ!D(R$@R%+>^jskGNrkr-_>8GHED(a}D zmTKy$sHUpws-Yh0DnJip%Id7N)@tjmxaO+suDtf@>#xA78Y=^uK49#z$R?}ovdlK? z?6c5DEA6z@R%`A5wb*8>?Y7)@>+QGR7AxxmmzHbpx#*^=?z-%@>+ZY69x!aN3>aYV zz4+#<@4o!@>+in+2Q2Ww1Q%@Z!3Za;@WKo??C`@2$2+gQ^#*J4#TaL-@x~l?>@lhm zk6ZD_B$sUR$tb6+GOHm=Jo3sg$1L;AG}mlu%k&yx^Ugf??DNmQ;!Ls5pDGZQ0zfCN z^wLbPEHt@9dzt|Qn=+7rs8?^Ab=FOH?e*7Shx+u(opMbo*Jg*U_S$UwJa*KbT8%WP zMmvMFGY8;(bq00M9l>r_AylFJ$K-FbGmijS6h8R1Q-Z@Q{;lD zjrixFhc34NxGuw8GzL^tmpSL0?=3m&f&Wdx+@jZRd+3Uv&3f6dM~*h^St~$61`*tD z{PAq(E_LIUPhIuoT1Wpo<_ajVIpL5aul@E)E8pqh*dM*A1zD5td+&eqef8knx9>jB z-e>Ij`}EhZa{RwqP`uH_+wcGXCc~evtjCxB0q}qb%$NWZ$iN0BZES+8o&+aI!3tXN zf*8!81~@P#mpp$un8!y1}^bo6qd4tEGN z2=efUK$MvegGj_8l5B`ZOrjDkhQuX0@rk%^J6yBy`>B*#l_{>q!2vRdOXhs;$4j&R}J z=BVJQHKgS;Rl(aE;j-DgRdI7u{G^=Z4mzuQqK%>Ztl29&8BC->Zkp%w9pG-Vzhl<_ zjRFz%Wjp&RP~wr4aLy?bK-xUC`i^SNliE&?Syr0b)p^4UX{cuUx}PRfu9J&^1u|OH$QkW! zFg-x?`d7}b)>5yotL#}Hdr!RXt$$-h?D;bLP02pft0)8OWtYjiYZeuHB_(R!EI`dq z<&>9dy&T?J`&xo#fVQUnUS8K~R^D3nmV#?uRCt@d$%S)k4&Ck62j1?_|hf7kc8Wp9x8)tAWOEdM3 z3d4J4>DB(GR-rlrq;IWorxI#fz*RPV=2IVt&xg?%1CON`WpO!IdQ;nOH^t#Q21uuO zj2s&`xPyDC`HV~04+}P!qK$HVp9)#J4fJ=t^)XkMD$#VN3b`huaXo7V(OjwdR&B=E zn|%dlU!gaEX6_};=6tF+pN!9719Yy2C*xk-xnw4unV{9S=&m)|XNNxjVxCWh=8`@7 zYnNVHrgs+UkAbz)X+|EX8GX1;ckI(PGxgd=9X3@1&D9#4D61`Pyji!p)RUZaC12GZ zIHc>n@K)8&;U0sy#KE0yfUA4pC)4=Glcw-=Gu(X`@0iF({(?-drh?3b)k%l z>|_htE3n%gz;m~5S_gk(wXdCLK)<)tM-_JkOV7I+mTN)fyL6D5?z^siyxt-|fzEe+ zr-na#s-gb!x5vD5knJmh6Z~Di>z(qz0=sBce*n7A7kUW&Jm_yO`ck$%>ZUKci-Bz8 zr!G12*{t&TDu1)fXW660*K+H-`MuEhUeTlv`r_M{a*j3q`u@(o;)9QJovYmX;1B=r zOJB*0o8SBBPk+M2&-){5uU;!8Vf^Kfvc%WF+ok4t0yu#G1XzFucz_33fBg3`{`YYg zr*8|Wexvhl+DCp7c!9gpfI^3X9B3;VxP9DHLkHJ^c1C{=SbhXYFa}40^S6E#*nS}Q zaQnxC9rJ+}7=rJIG2cgnHE4nxxINvcgEPp38e@Yn*l;;`F*`_vMd*Vd7)&;YbM6## zQCM`r5`?Ukg{-oKOekkgc!M-|bVzr43&waCgN1NMD_q!x7Gs10S9JH(Q#FM*Q`I|M zr(#}rg_qYij+0r(pi)Fthl4eQY#1zVSZ!38cZTIS_$7ItB{fmlR|dp1Zd67Jrks8T@964AU)R74H zkxYk>5h;>iM3P1GYc@cSC~0jfnRYy|T~R?<%~*_(C|x+|OfQK`1<8z^$dYzMN&(f7 zy*P^6M2YU$lP&j?E-5%dsVPM1Wsap}K1Esod{}nBs5gJeWqo*+Ub$OLsWdTJeKR?g z++|H#BaGICcd`XtxrK>@2WCn+mZ7$f|3@kYca~b%V!+j0j;K*$`CzXFi!`-d-DsDH z=agu+mped{&yza5!%SotJ*r;W0Sw5v0 zjn8M52QX!w$#xUyaX)C5k9m@_=|p8oH>jnXyQxIIxl=z7oY6L%#wl^gnVkK$oXjb2 z&iS0{7M;>bZq!+w-gceX36qSuoh+xF-pOp>8J@;Ap5%E(=6RlDl%DFDlHJ*!(D|P5 zIi2!3pVnEQ_L-gdnV;PGnYYQG%f_Dn018C{I-tC{p9Wf<2%4bixu6WXo(}q;?&+UT zD4}9hpcWcL7@DC!w4ofjLmv8}4iusy%0MJqq6l=NC<;I-x}yHmqAprLFdC!pGov)x zJ~n!z+moX@>T40&qeR4`K#Fa(>301%q)8;CNGdu?x}?Weq`-HiPO70lI;A68rB-U9 zSem6Nx}{voqF(x?FB+y|Dx+jtrZsw|Xo{n1x~4nYrf%w^6bgoM3Z`=^rFHs0O`4}o zv!{H@aZt*B-hh(V#s(Ndn`joBuq{Sp|p&F~kld87bf2^9TeY&f>3aGP6 zfu)+MzsjV(TCA^jtjJ26!D^cox~#0EtkC*&uL_*g`g78Ht$UWO+A1@++O1w#t>B7l z;ySL;TCV2WZs?k>q_(c?N^kD^u09#B^4hEPTCc$RDbI$ln8vOA>M`H?uecJh0_%bP zTCh!cuLvut&1$5ky0Fwrs(A^qBzLeBYls$mv7o518tbhY+p)^{u^>B4B0I7JTe2o= zupFDRy1KF~dzTUmnlI~nG5eo03$qOyr4M_vwC1ur+k-y)vl~OOLQ8!?TeRU?v(JjO zwTQAzODaT*v{75MQ!BLpRr|A7%d=T~vs*i}UHh_M%d%mcvSVwqWjnHG3$kh3v1_Zb zZF{kAOR;eav2(kyb&IffTd;X6uzUNjeao+Zi?0y5kc3;fhI_b(o4AU*xQyGlj{CTf z8@ZA@xdiBxPrEa!b-B7EtVXH1gG8&ITV|Xax(@`pqzg);d%A98x~jXm&f2;*lew_# zF|s?m9Fw_}o4W}qu&Oly0QtKeG=jF;y9$tk#tSej$gjkEyv)ll$&0VcYcIMxz4!9G z&pExiTPx8!0nN+2-20EhJCNVoy(xHb+iL)D^1arZoZOqfv~s>-AzA7hzWLa`U?IQn z%eod;yar&uWV892=0P|a&1yTre3h#7<1a zMoh&?T*JG`!~)~QP>ja?GQ~)2zC4UjK3oF^)5ZAW3w^ z#itU(K>Wr3mka@Re94=9!VkQ}pUlNjoB$QD$D{npZQRJO%T{p=!UQwO2C&DMT*So8 z#)>?{W30mIXvP7f#+8i7tX#|u?8c7l%UT@BlPtvcQUOKG${FCzu519}49kBk%i4S} zPJ9es%*wdj&B?6H*4)db0?E#d!}~(R%p8vQTrlHnyrz6JZwyVpjL$B-%zzBc2K_Gq zT`H)&(Eg&&2@TOX%*Y8m(Dppb6s<23jm`?a(Hw2j6@1P0T+krRFCFd4>3q`o($HLl z(Q*7U2#wA%JjaO_kz8-TfO_t&qO`B+6&VxZ7^hPuF>1n z1M}2z<4U~1d({|p)S8OBNuAWZJJ7a!YG57K8&kVvjWK3@)=V_kYJG-m-PTw5)^PoG zyX4b$eb;!M*LuCzF%U|?_Sb+N*rPy!b4@eD0xpQ1*owW_jNRCd{n(Hl*^<31U0vCh Sec70u*_yrCoISlE0029JP30i~ diff --git a/SheepShaver/doc/BeOS/settings.html b/SheepShaver/doc/BeOS/settings.html deleted file mode 100644 index 7c05c2a91..000000000 --- a/SheepShaver/doc/BeOS/settings.html +++ /dev/null @@ -1,127 +0,0 @@ - - -Setting up SheepShaver - - - -

Setting up SheepShaver

- -In the "SheepShaver Settings" window that pops up when you double-click on -the SheepShaver icon, you can configure certain features of SheepShaver. -When you click on "Start", the current settings are saved to disk and will be -available next time you start SheepShaver. - -

The settings are divided into four groups: Volumes, Graphics/Sound, Serial/Network and Memory/Misc. - -

Volumes

- - - -

The main part of the volumes pane is a list that contains all volumes to be mounted -by SheepShaver. If this list is empty, SheepShaver will try to detect and mount all HFS partitions -it can find. CD-ROM drives are always automatically detected and used. - -

SheepShaver can use HFS partitions, whole HFS formatted drives, and it can also -emulate hard disks in single BeOS files ("hardfiles"). - -

To add a Mac volume to the list, mount it on the BeOS side, click on "Add...", go to the "Disks" -level in the topmost popup menu of the file panel, click once on the volume you want and -click on "Add". A line beginning with "/dev/disk/" should then appear in the volume list. -After adding volumes to the list, you should unmount them on the BeOS side again.To remove -a Mac volume, select it in the list and click on "Remove". - -

You can create a new, empty hardfile by clicking on "Create...". Enter the file -name and the size of the hardfile and click on "Create". The hardfile will be created (this may -take some seconds) and added to the volume list. The so-created hardfile will have to be -formatted under MacOS before you can store something in it. If you start up SheepShaver, -the Finder will display a message about an "unreadable" volume being found and give you the -option to format it. - -

Double-clicking on an entry in the volume list will add or remove a "*" in front of the -device name. Volumes marked with a "*" are read-only for the MacOS under SheepShaver. - -

SheepShaver will show a "BeOS" disk icon on the Mac desktop that allows access to BeOS -files from Mac applications. In "BeOS Root" you specify which BeOS directory will -be at the root of this virtual "BeOS" disk. You can enter a path name here or drag and drop a -Tracker folder onto it. The default setting of "/boot" means that the "BeOS" icon in the MacOS -Finder will correspond to your BeOS boot volume. If you want to access files on other BeOS -volumes, you should enter "/" here. The "BeOS" disk will then contain folders for each BeOS -volume (among other things). The MacOS will create files and folders like "Desktop", "Trash", -"OpenFolderListDF" etc. in the directory you specify as "BeOS Root". If they annoy you, you -can delete them. - -

To boot from CD-ROM, set the "Boot From" setting to "CD-ROM". -The "Disable CD-ROM Driver" box is used to disable SheepShaver's built-in CD-ROM driver. -This is currently of not much use and you should leave the box unselected. - -

Graphics/Sound

- - - -

WIth "Window Refresh Rate" you can set the refresh rate of the MacOS window. -Higher rates mean faster screen updates and less "sluggish" behaviour, but also require more CPU time. - -

The "QuickDraw Acceleration" box should always be enabled. It allows for faster graphics in -full-screen modes. But if your machine uses the "IXMicro" BeOS video driver, you have to disable the -QuickDraw acceleration or full-screen modes won't work (this is because of BeOS bug #981112-032247). - -

The main part of the window is occupied by a list of checkboxes that allows you to select -which graphics modes are available for displaying the MacOS desktop. You can, for -example, disable the modes that your monitor or graphics card can't display, or disable the -window modes when you want to run some Mac programs in full-screen mode that would otherwise -erroneously switch to a window mode. The actual mode to be used is selected in the "Monitors" -control panel under MacOS. - -

The "Disable Sound Output" box allows you to disable all sound output by SheepShaver. -This is useful if the sound takes too much CPU time on your machine or to get rid of warning -messages if SheepShaver can't use your audio hardware. - -

Serial/Network

- - - -

You can select to which ports the MacOS modem and printer ports are redirected. -This doesn't make much sense on a PowerMac, but on a BeBox you can assign the modem -and printer ports to any of the four serial ports (or com3/com4) or even parallel ports of -the BeBox (useful for printing if you have Mac drivers for parallel printers, like the PowerPrint -package from www.gdt.com). - -

If you don't want SheepShaver's Ethernet support to be enabled for some reason, you -can use the "Disable Ethernet" checkbox to disable it (this will also get rid of the annoying -"no network hardware" messages if your Mac is not equipped with Ethernet). - -

Memory/Misc

- - - -

With "MacOS RAM Size" you select how much RAM will be available to the MacOS -(and all MacOS applications running under it). SheepShaver uses the BeOS virtual memory system, -so you can select more RAM than you physically have in your machine. The MacOS virtual memory -system is not available under SheepShaver (i.e. if you have 32MB of RAM in your computer and -select 64MB to be used for MacOS in the SheepShaver settings, MacOS will behave as if it's running on -a computer that has 64MB of RAM but no virtual memory). - -

The "Ignore Illegal Memory Accesses" option is there to make some broken Mac -programs work that access addresses where there is no RAM or ROM. With this option unchecked, -SheepShaver will in this case display an error message and quit. When the option is activated, -SheepShaver will try to continue as if the illegal access never happened (writes are ignored, reads -return 0). This may or may not make the program work (when a program performs an illegal access, -it is most likely that something else went wrong). When a Mac program behaves strangely or hangs, -you can quit SheepShaver, uncheck this option and retry. If you get an "illegal access" message, -you will know that something is broken. - -

If the "Don't Use CPU When Idle" option is enabled, SheepShaver will try to reduce -CPU usage to a minimum when the MacOS is doing "nothing" but waiting for user input. This doesn't -work with all programs and it may confuse the timing of some games but in general you should -leave it enabled. - -

"ROM File" specifies the path name of the Mac ROM file to be used. If it is left -blank, SheepShaver expects the ROM file to be called "ROM" and be in the same directory as -the SheepShaver application. - -


-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/troubleshooting.html b/SheepShaver/doc/BeOS/troubleshooting.html deleted file mode 100644 index b46aa5855..000000000 --- a/SheepShaver/doc/BeOS/troubleshooting.html +++ /dev/null @@ -1,79 +0,0 @@ - - -Troubleshooting - - - -

Troubleshooting

- -

SheepShaver doesn't boot

- -SheepShaver should boot all MacOS versions >=7.5.2, except MacOS X. However, -your mileage may vary. If it doesn't boot, try again with extensions disabled -(by pressing the shift key) and then remove some of these extensions: -"MacOS Licensing Extension", Speed Doubler, 68k FPU extensions and MacsBug. - -

The colors are wrong in 16 or 32 bit graphics modes

- -If you're running SheepShaver on a BeBox, the only graphics modes that have -the right colors are the 8 bit modes (this is actually a hardware problem -and has to do with frame buffers being little-endian on the BeBox), unless -you are using a Matrox Milennium I/II. -

You should also be aware that not all graphics cards support 16 bit modes -under BeOS (especially S3 cards don't). Check the BeOS "Screen" preferences -application to see if your card does. - -

SheepShaver appears to be very slow

- -
    -
  • Don't use the window modes, the fullscreen modes are much faster. -
  • If you nevertheless want (or have) to use a window mode, you should set the -color depth in MacOS to the same as the BeOS workspace you are running SheepShaver on -(e.g. if you are on a 16-bit workspace, set the color depth in MacOS to "Thousands"). -Also, set the window refresh rate to a low value (high values like 30Hz will make SheepShaver -(and BeOS) slower, not faster!). -
- -

Full-screen mode doesn't work

- -If your machine uses the "IXMicro" BeOS video driver (TwinTurbo cards), you -will have to disable the "QuickDraw Acceleration" in the "Video" pane of the -SheepShaver settings. - -

Ethernet doesn't work

- -
    -
  • Is the Ethernet set up under BeOS? Ethernet will not work in SheepShaver if you didn't set it up in the BeOS "Network" preferences. -
  • If you're using TCP/IP on the MacOS side, you have to set up different IP addresses for the BeOS and for the MacOS. -
  • Try disabling AppleTalk in the BeOS Network preferences (there might be conflicts between BeOS AppleTalk and SheepShaver networking). -
- -

SheepShaver crashes, but yesterday it worked

- -Try the "Zap PRAM File" item in the main menu of the SheepShaver preferences editor. -When you are using a ROM file and switching to a different ROM version, you have -to zap the PRAM file or SheepShaver might behave very weird. - -

Known incompatibilities

- -
    -
  • MacOS programs or drivers which access Mac hardware directly are not supported by SheepShaver. -
  • Speed Doubler, RAM Doubler, 68k FPU emulators and similar programs don't run under SheepShaver. -
  • MacsBug is not compatible with SheepShaver. -
  • If you want to run RealPC on a BeBox, you have to disable one CPU in the "Pulse" application or it will crash. -
- -

Known bugs

- -
    -
  • The QuickTime 2.5 Cinepak codec crashes the emulator. -
  • Programs that use InputSprockets crash the emulator when in window mode. -
  • The mouse cursor hotspot in window mode is not correct. -
- -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/using.html b/SheepShaver/doc/BeOS/using.html deleted file mode 100644 index 8f9395bcf..000000000 --- a/SheepShaver/doc/BeOS/using.html +++ /dev/null @@ -1,76 +0,0 @@ - - -Using SheepShaver - - - -

Using SheepShaver

- -

Changing the display mode

- -SheepShaver can display the MacOS user interface in a BeOS window or full-screen -(much faster) in several resolutions and color depths. You select the display mode -as usual under MacOS in the "Monitors" control panel (under System 7.x, click on "Options"). -The "75Hz" modes are full-screen modes, the "60Hz" modes are window modes -(this doesn't mean that the video refresh rate is 75 or 60Hz in the respective modes; -the rate displayed has no meaning; it's simply there to distinguish full screen modes -from window modes). - -

Window mode

- -The SheepShaver window has a menu at the bottom that allows you to change the -graphics refresh rate and to mount floppy disks (see below). The window refresh is -disabled as long as the "Scroll Lock" key is pressed (the graphics output is then frozen). - -

Full-screen mode

- -The full-screen mode uses a whole BeOS workspace for displaying the MacOS user -interface. You can switch workspaces with Command-F1/F2/F3/etc. Please note that -the MacOS (and all MacOS applications) will be suspended when you switch to a different -workspace. It will only be resumed when you go back to the SheepShaver workspace. - -

Networking

- -SheepShaver only supports Ethernet networking (and PPP via the serial -ports). If there are multiple Ethernet cards installed, only the first -card will be used. The Ethernet support is implemented at the data-link -level. This implies that the "Mac" and the "Be" side must have two different -network addresses. - -

Using floppy disks

- -Floppy disks are not automatically detected when they are inserted. They have to be -mounted explicitly. After inserting a floppy disk, select the "Mount Floppy" item in the -"SheepShaver" menu (when running in window mode), or press Ctrl-F1 (when running in -full-screen mode). BeBox users should note that floppy disks also have to be unmounted -under MacOS before ejecting them from the drive. - -

Accessing BeOS files

- -SheepShaver will display a "BeOS" disk icon on the Mac desktop that allows you -to access any BeOS files/folders which are in the directory specified as "BeOS Root" -in the "Volumes" pane of the SheepShaver settings. You can open and save files on the -"BeOS" disk from Mac applications, copy, move or rename files from the Finder etc. -Putting files/folder to the trash may however not always work. SheepShaver translates -some BeOS file types to MacOS types and vice versa, so e.g. JPEG and PDF files will -show up the correct icons in the Finder. To store Mac resources and other additional -data, SheepShaver uses the following BeOS file attributes: - -
    -
  • MACOS:RFORK contains the complete Mac resource fork of the file -
  • MACOS:HFS_FLAGS contains Finder flags -
  • MACOS:CREATOR contains the MacOS creator application ID -
- -

Copying text via the clipboard

- -SheepShaver tries to keep the BeOS and MacOS clipboards synchronized. That means, -when you copy a piece of text under BeOS, you can paste it into a MacOS application -and vice versa. - -
-
-SheepShaver User's Guide -
- - diff --git a/SheepShaver/doc/BeOS/volumes.gif b/SheepShaver/doc/BeOS/volumes.gif deleted file mode 100644 index 857dd0a21e5144e9ab9a4de2309c827b8c3193ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7456 zcmcJ~1y>Uc!+_yY0)mK03y7eAq;wF(|xF*-&HjM3elgV9Kb z`_B6#zUv3v=iCa4U&O>sGjKFE7Pn{QUg*`1nvN z0EI$zb#*m2H^brZ($do0+}zav0i;?0LPJCS{QNvTJgls&EGz&fCMLSNx@u}_Kp;?7 zR#r?*Oi&QO!NI}I%uGv5OHNJ>_RWF^~wE2D<%fQN=`{lOOJi&8DVmyFS}NPxJ37m&>w9|p zkj9O;gG0kZU1Q@DL>CQj$w0V{z17~_RQFVUayzAu(M?0lA=Fwc+tC+ z5mC^7W6|O~Gtk6UYZu6DiRPRw;-<4RH`BJB3p-vPq(V?&X2K|zp=zFG?Bkt&ro``1 zrGDzl79W*mhcxi#A)ZB_+TBFVw_DMaf@~We<>LKnGm60m3ye$f^w*m187^i25kzS% z`BcjG5-R)R9jvMVIn;3p0$$Gs>E+u*ImaZ-fEil;AP$DR*=puJ+Z9Gq5UaeJEjBLG zw^v6fM4P7&)|Uog@4@hu!UypxhD)&O?Dn*M3;hpgL*t&eJ17Twy~4icFY4bk?|~NH z%cbpjUu)!eWEVg8eHXaH@NH9i7Mo{oX=oJ}yeQAEs!QUG3RPmU*fV9VJhEIit8)^` z0wr!=tw&21vy*#Ml0g)W(8{^-E*9z`;5Z7yq$HOAf-RYibXJ6u{1mlASQC$FTMFZ; zNAR;F%@?$&Kh1&jSz~O|Q%Kb*pX{%K;+y|NXNkE552o8)(di1b;!Ch+N6#yAWF5%v z%w})j?w8sx3bF3ziP`W_nq3isVL@W6E#LKJ>xhNX~cc}Rfx^s5ixYd-%+XSL%~{s=LUbr{-d$Gm;ka@3f0LCNnK2;DezoQf77wEouYhg zaye@NIl7!%{jO3s+bKe>gJ)7wd9`TE$0O2hcK`JgKH`gP0333X4q3IkKDu7>BfP(w zYCl)uUJE9yy4j5MmiAa~UyKr|wm<|nN)nm)iV`QO+INdvu&Rlpqf+ee_LpUNZ^T_K zWjy!N{k|2VTj)dB3Wu+3{hd!FVr~8nrJXPVyPtCM1gxFQ-VSTaka(R2e(A|=I_ys) z3pfqp7)~S7ME#*IwsXvf<&ated*~NWgT;pP$RMa5rn}P+S<-y+5MVD0{aGkbIiDgz zOe|FVEKDsjpRxql$4T$+LFtl5-9#ip>wFerl9*1@14If?*hN|>7tq@UBZXVfqUNnx z8PGt5TvKeEh1+leQ`ozH={x=y=tBYX8ZAnWelqemcd|^78|N2^!8kIE9t&exJ?G6} zd}q(wYM}u!5KC8rEuQ%_8!@+`JP%$*JrgIy{Ofe(c|xT3&NT2Arpy|dy zH=q#-d7E16?5U({^gO9oh*3c4TB&rRR%bwYQ6T20veB0*hY?r(5Beb$R;?${uJqi- zVq$It7z7S}iLR#h82wrH5@-8jX0Mc{g4p*YV`+=2Zgl|WK^>jZct5)fz_k4|{~NHx zu!}M4SAqHt<+Ro6A2^1Ln*WY=#aThanaf4%&4s`lOAPzx3+?7-E;?9RmEQFi*ya1>RBt_#wOZsoMt><=o-OmF)}V9RArLF7_i}-Wc$17N;5-F zH7CxBKsLML3QFyJy^y&~`zqhegYt*Sq#45~zG}8e<6XZ+nO?6L`=f*v zi^LjUeAiZ8tXW%E=SS$QH#?tp5}6;xF~9fn+wUBjjP$FTs1I^*8fU}47*~IWwwnGuoYNK*foXvc zS;o?JyZ+U~(<+C-GWYR1ewTHPBX%~VTyYaJh0U-K1IL*AWisyThP<$2_XE`xikFM< zKS#%2gk-CNFWFd+Mo!i@^jGhXo4Q~;^KMhF>qMQ`P0yI-gCrT|NMf3%b{|i}n~v6A zJ{PM=Mx8}_KWs5SZ$T-5oTF(-w!qUjah0g^WW>YHhmh};>d^{GBrqKQv6fND=--rI z8-N$A)FYQG+&?zj&_LDJ$rO7o0PXs|T1+brE%`+%wZZ0lKChbSQS3#P_v3*Hd&+b_ z=rT<~YVC7-;Y7>_QI`64Vh5T}&?s_9i_-LwV(C5kMfCO4%pZ7E^O6-eqgO;XS@?c5 z4;wFIf=I|^4r5D_rV2Xz20peQvVWB9YUprcy=f**F2u?$8>KRcAZntR=THTK%)y2<$Z?M;Vd z<1gs(5aU08_FsTdD6q@B7vdMM;Q0g&7|?P1Pee*r$7K}af_1(A^XjVe{L(#Jz>D7t{~x5D6X z#Ss$)iv^fk1!#o^I>iNO=m!7bfH(pnb~l0UH~7h-K_tK+GN6@CNRWuA-ngazJ0JuX z7|KHQ`w{JZN#*@}&pi_8C&m%BNP}Y}<{Kv#u-oLtQyReF5%w4DoxA4^91nzegnJUX zdFci{*9DP6EX)G~cKUyjq-$fY3Wpd{ZJ^JB7$(4>DwE#4k&z zkQJn-Gy?7CizJFv3H=pT5*ZreTjUYG+>D=464DRxgq9lrYW6IucP|trDAx5-g-7q} z`jhB>Xa0^bdH5o_xJIc#0h?4{sA2675j08#L>ixNgdyl!WPmSZ@CM>akX^f)kL;p zkc=)*&KA$apfHW#H1`~EMt4glR3I}WEhQ@~lW;C&7@Q>)5K;n8YHx{~UC1Ka%v9IO zJax@fEX`c?%#LMA+Gxpm(U6rJmVHW0xlZi1DegMC;J8bdb9ejV@2%^lVzxgKcV|lu z{$LJ9G3O90dYqO+u$U|7l>09&7hBtqo3x)x?M3?d6M!vCxh9S{PfVbp&+m=RdqtnM z1I}Yf&kw-Kqvy=456kDIFDUBDe;1zqPBCrzeSw4*(OXPDWqN@mePO_O!Gd_k$JX>u z>4pBXh2uX9l)?&t<%JrU=R%kQ{)M~_;(X24BGazIFMEX!X_+4ei_FRij26QeJ&V|% z7Md>>v#1xz4`x`?=ho~MyN454rYD+6qC*zkiE&+W6<^CMI-eHx zV=CJ8U{=XUn^(m;}7Ucj?yY?7Auw|DrU<|n(hi)Br10}3&ySU^Er)snUtBSC$*dDBY^r{L-uQJsuz2}6}V5*-Cl@PsxKSjXtVWrQMN^iuA zU+Cw~)0NFjl-)h8p*ueB*RanDUb;hr9OubXoyz4j8>n)YUSu+|}(vqLfH=0G%8+h0Fer=i= zNHPqI@kncOKr}IhH~JoA3E9*JXB34k)srvQmE6_6K4^#;%8Yo`z_-|x;+?_0AD`}B zNW9e2CElb9Pl&W>^m$cLxRjoD(0KE-2`1TEdC(dMYw&`#hHy1CM6_JfHV1lFws^zq z5cTb^(%rclJ-FI_!w}KlZABU3wp=aMUt7LKG>;FZ+vulHAHZf|^~o9SDPav`ip@1k z%~6~k`HCGshT6~vZTql}Ev5S2wANk(Lf^dg{2-+o+?glYupZHV4@<4K>CoUp++-Nx zMYc8Bbdu?}VK)$6&fuR=>=x?e)Z{!fm=w5$YdY`g9)zN)vIw%Y8-_eWw?F-=&ZYfd;&!b*56?`aXaI1k&{<^1VR| zM<3GSy}rFqntLYFJguLqtz}le-;4oeoY`++KoH=A3Q$J*MWP~y1$-i_%)L89wNZd^ zRC0wtxGgHBZGbmnAZd6YmsB9e03P?yg-{yE%N%6d8Yo{LWbGNOVi+n=t|>a~PH02b z91ddPnL}-v{D|eDT&W@6`)a<(!LH1~PM_hH%;CXh)Stt;-bf^p8-<4Rzm4Ues~8+! z?wjrhuqBMtGT=ZS`kZiZMuz#vq*^8_{&@MINFB*mBS+3FMmCp6e~{w5T^}JQ$6Xs9 zT6z#zco;>u@$Vb7A8_|yF`yP0#!r1lPBO>V83wUFeYcS#xR2vhP+#gTGD5$Jv*Cf4 zD*~h|6UXZ#?-+4s6edr7094S4cPdDNqjo}QJFyCqqE_HnC)3Fr(_f{L{7~c}!}Rya2`nAs z3~*)e&9m_{?r|U^4WTSlePq)9acb+ZZ=qtwK5JT%an74(j^SwLa=AZW(p-fHNu@H$ zy)qRB1xQ5ADpwACj~vso8?}t$Co^1-QJE8t>a#qW@@k*g<(W~;Lis-%=&>1WB3=05 zGtGH4Nxm{;khS1vIQPTHV|RFlQw7)H5V{cQ-!jtIEWKFQzCg)1Lp#!!b2LHyd1mN{ ztcwR}%-Ao)Gm966`f0c_`Y@jpxiV|GSm?9Z$nE-jWX0cSWm{#j9=iJBXr-QXRdh*b zt8z84V&%MYVcKvF%&;QJ&~zQOrfa+UZ>0~ww9Zkmwl=h8d-y3P3TVIl3416#EJ6Z* z#CLtgO<-fN(dfKE`w!o-ZH;`nSDj&#MP^f+bn~t6CI@JfEqjxDbyHfZ&zGS`fVYS6 z--e*?mL%RRQPh@{y`ThWN}6dqnQcXgd;5zF=s%_=g^umn^DX(&ZM6<=P}R1&(N4d> zj){q;hvJ4y*LVeMQao(3a=c0vHz>0Tq~Xx8^&hWDt8>Ck=^P0TGj z+9w^jt0k~&BKSo^Bmuny!Ys?|&)O5j*<)6!2>u+eQgj?nyfa%*>?|oV-Ja2tNI=h# z?bG-j#a10HM4uiTo#;EB{D@x6=>XquW2%m2blg-0k)~s0N7;armSZh={Q;m0=i>NO z8*p}_wA&ZI@1hMU&QvCBN2bP#qwU66aE+qSJF#Iq7=*N%GFM^ma0^2{z zJ6r_#T>zAKoT_ZKnZADSIHz!sV;;W9RlAh>b*YKH)F3;?LddR+9nfaKu5@^>sOmpx z#9T@IxT5^VZ)m$~-}%$}^)<49$6__lO;yMdD;reD~x*W+$vU#Wg5u-#UuZl!>BHapJtv&EchEb1H1Le0Svc(>!`;BGgU zuGbHZyLTR+&$f6^bJbq-oTQJtia(j5W`}nH*#|EEh zwV;Kx#lPx{Tg-EOqK#NxA*Q%~Wr`O#%p7#=LVtV&eq-PAlr7GSkQ?#PZoGLhwwITR z59+LO66bg3D6S*&Xtpz`D%!;-Bqn+G{KZQu8oH#^;(TUUd=)(pAISmfSv);1zuaee z1w|!7Y%Ft8HV0cAr^*jHVM5_MxRjwe#M2vUt{(I4U8Qdn+DgtPCM_c?=aC7lQx=|= zcR*j?)PiX5M0~979~j~fj0y(3MVX911vhul`v*rS3u~9xw*?8)Fm=o|*C)9^!WV4c zN*zr;hwP41;mi*%evY8wx3Hy-8x{JFD;!KI9$&~3{h4i-b#s)c+5Vj=GEwokFgB4Y z&ZCtkW=A>aqknMuLhqJDrh*iXTC3~(fNZ(EFG*Ml%RQCYEP)R*m}wL>1@*bfMj>Iu zZ$7U^KlwUy4g5y1L5m?wzB0WGQlQO4e@azVp_fssyd}RASM%fDRTy&s_iMwzvF1t^ zx+8KPcjB!XA00kQYs%`~2a=nxbz#fV&)7C(vmIo{bt4I-`#H&RVAcC!y|`BpH_M5e;WT>7n4b`>hbc{Y;y2Rp{X=6kYh`5L=WHNp?ch_?OSGk1qX^Ub%4k02@ z7~JmE&CPr6jTw7*ZNs87A>t-9(pyK*RyX~4IGJT`?i);Ueopl(gint|;*YcHUKc_> z{;PDbn0eWIX@ZoBAW$Xg(KLAsP5F3o8)J{t8;9Qjfp5P1;4kCCEU-!wax)Q$vw|=o zID~XRo8-C#5XS?jqDoIz4^`wN;<9k%+5oUL5~|s z^^KV{DHU-A<^8Rzn}_58cH+6_dVF|`LuW4bg?*66CpChF?}?Zo`e&Z^hl@Ae<3ut5 z_g)7#jl365C4JcTGg_w$?7}E_Q{U`mT<8Qdxw9ANG{KRD!ypbqBE9o?xY{xh3GM`^`9cnb0k~>_vwEp=(VwqjzcrIjlBo6HaVd2V=#^{4A%47Ve;{uTsdtKL zR>q$Q1}kT{#t|pzqXhHlRDOb{m;;5_K9I?(*x4s!5UR7O`-U|Hltr4cA=ogeecojL zI?Xpr=F7_-qhIAtvm7Hzq}~v;LXQ%19`XA{&u)uziFvXJ2&`l$gw%p~DSvO6?S1CS zQws%sGa@V6lcy2?&*XbzfzPy+f}HhN_h6yI_xrnw>ggIuRf$DBZu?56^qOg-iN$=v z$qSC@npww*CDNDss`CEy-}1=ZN}zA|)oaL!pK>RaskmV@^XRq8KuP6V4H&JObgfGJ lB$(kPMyH!zyCyoR!rZ)EZX#W~p(?4;&h0>7iy9vw`G5Dj1)~4} diff --git a/SheepShaver/src/BeOS/CreatePCIDrivers/Ethernet.cpp b/SheepShaver/src/BeOS/CreatePCIDrivers/Ethernet.cpp deleted file mode 100644 index c6c0fbf47..000000000 --- a/SheepShaver/src/BeOS/CreatePCIDrivers/Ethernet.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Ethernet.cpp - SheepShaver ethernet PCI driver stub - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include -#include "xlowmem.h" -#include "ether_defs.h" - - -/* - * Driver Description structure - */ - -struct DriverDescription { - uint32 driverDescSignature; - uint32 driverDescVersion; - char nameInfoStr[32]; - uint32 version; - uint32 driverRuntime; - char driverName[32]; - uint32 driverDescReserved[8]; - uint32 nServices; - uint32 serviceCategory; - uint32 serviceType; - uint32 serviceVersion; -}; - -#pragma export on -DriverDescription TheDriverDescription = { - 'mtej', - 0, - "\pSheepShaver Ethernet", - 0x01008000, // V1.0.0final - 4, // kDriverIsUnderExpertControl - "\penet", - 0, 0, 0, 0, 0, 0, 0, 0, - 1, - 'otan', - 0x000a0b01, // Ethernet, Framing: Ethernet/EthernetIPX/802.2, IsDLPI - 0x01000000, // V1.0.0 -}; -#pragma export off - - -/* - * install_info and related structures - */ - -static int ether_open(queue_t *rdq, void *dev, int flag, int sflag, void *creds); -static int ether_close(queue_t *rdq, int flag, void *creds); -static int ether_wput(queue_t *q, msgb *mp); -static int ether_wsrv(queue_t *q); -static int ether_rput(queue_t *q, msgb *mp); -static int ether_rsrv(queue_t *q); - -struct ot_module_info { - uint16 mi_idnum; - char *mi_idname; - int32 mi_minpsz; // Minimum packet size - int32 mi_maxpsz; // Maximum packet size - uint32 mi_hiwat; // Queue hi-water mark - uint32 mi_lowat; // Queue lo-water mark -}; - -static ot_module_info module_information = { - kEnetModuleID, - "SheepShaver Ethernet", - 0, - kEnetTSDU, - 6000, - 5000 -}; - -typedef int (*putp_t)(queue_t *, msgb *); -typedef int (*srvp_t)(queue_t *); -typedef int (*openp_t)(queue_t *, void *, int, int, void *); -typedef int (*closep_t)(queue_t *, int, void *); - -struct qinit { - putp_t qi_putp; - srvp_t qi_srvp; - openp_t qi_qopen; - closep_t qi_qclose; - void *qi_qadmin; - struct ot_module_info *qi_minfo; - void *qi_mstat; -}; - -static qinit read_side = { - NULL, - ether_rsrv, - ether_open, - ether_close, - NULL, - &module_information, - NULL -}; - -static qinit write_side = { - ether_wput, - NULL, - ether_open, - ether_close, - NULL, - &module_information, - NULL -}; - -struct streamtab { - struct qinit *st_rdinit; - struct qinit *st_wrinit; - struct qinit *st_muxrinit; - struct qinit *st_muxwinit; -}; - -static streamtab the_streamtab = { - &read_side, - &write_side, - NULL, - NULL -}; - -struct install_info { - struct streamtab *install_str; - uint32 install_flags; - uint32 install_sqlvl; - char *install_buddy; - void *ref_load; - uint32 ref_count; -}; - -enum { - kOTModIsDriver = 0x00000001, - kOTModUpperIsDLPI = 0x00002000, - SQLVL_MODULE = 3, -}; - -static install_info the_install_info = { - &the_streamtab, - kOTModIsDriver /*| kOTModUpperIsDLPI */, - SQLVL_MODULE, - NULL, - NULL, - 0 -}; - - -// Prototypes for exported functions -extern "C" { -#pragma export on -extern uint32 ValidateHardware(void *theID); -extern install_info* GetOTInstallInfo(); -extern uint8 InitStreamModule(void *theID); -extern void TerminateStreamModule(void); -#pragma export off -} - - -/* - * Validate that our hardware is available (always available) - */ - -uint32 ValidateHardware(void *theID) -{ - return 0; -} - - -/* - * Return pointer to install_info structure - */ - -install_info *GetOTInstallInfo(void) -{ - return &the_install_info; -} - - -/* - * Init module - */ - -asm uint8 InitStreamModule(register void *theID) -{ - lwz r2,XLM_TOC - lwz r0,XLM_ETHER_INIT - mtctr r0 - bctr -} - - -/* - * Terminate module - */ - -asm void TerminateStreamModule(void) -{ - lwz r2,XLM_TOC - lwz r0,XLM_ETHER_TERM - mtctr r0 - bctr -} - - -/* - * DLPI functions - */ - -static asm int ether_open(register queue_t *rdq, register void *dev, register int flag, register int sflag, register void *creds) -{ - lwz r2,XLM_TOC - lwz r0,XLM_ETHER_OPEN - mtctr r0 - bctr -} - -static asm int ether_close(register queue_t *rdq, register int flag, register void *creds) -{ - lwz r2,XLM_TOC - lwz r0,XLM_ETHER_CLOSE - mtctr r0 - bctr -} - -static asm int ether_wput(register queue_t *q, register msgb *mp) -{ - lwz r2,XLM_TOC - lwz r0,XLM_ETHER_WPUT - mtctr r0 - bctr -} - -static asm int ether_rsrv(register queue_t *q) -{ - lwz r2,XLM_TOC - lwz r0,XLM_ETHER_RSRV - mtctr r0 - bctr -} diff --git a/SheepShaver/src/BeOS/CreatePCIDrivers/Makefile b/SheepShaver/src/BeOS/CreatePCIDrivers/Makefile deleted file mode 100644 index f9f12eee4..000000000 --- a/SheepShaver/src/BeOS/CreatePCIDrivers/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -all: ../../EthernetDriverStub.i ../../VideoDriverStub.i - -clean: - -rm *.o hexconv Ethernet Video - -../../EthernetDriverStub.i: Ethernet hexconv - hexconv $< $@ - -../../VideoDriverStub.i: Video hexconv - hexconv $< $@ - -hexconv: hexconv.cpp - mwcc -o hexconv hexconv.cpp - -Ethernet.o: Ethernet.cpp - mwcc -I.. -I../../include -o $@ -c $< - -Video.o: Video.cpp - mwcc -I.. -I../../include -o $@ -c $< - -Ethernet: Ethernet.o - mwldppc -xms -export pragma -nostdentry -nostdlib -o $@ $< - -Video: Video.o - mwldppc -xms -export pragma -nostdentry -nostdlib -o $@ $< diff --git a/SheepShaver/src/BeOS/CreatePCIDrivers/Video.cpp b/SheepShaver/src/BeOS/CreatePCIDrivers/Video.cpp deleted file mode 100644 index 1e1c9b244..000000000 --- a/SheepShaver/src/BeOS/CreatePCIDrivers/Video.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Video.cpp - SheepShaver video PCI driver stub - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "xlowmem.h" - - -/* - * Driver Description structure - */ - -struct DriverDescription { - uint32 driverDescSignature; - uint32 driverDescVersion; - char nameInfoStr[32]; - uint32 version; - uint32 driverRuntime; - char driverName[32]; - uint32 driverDescReserved[8]; - uint32 nServices; - uint32 serviceCategory; - uint32 serviceType; - uint32 serviceVersion; -}; - -#pragma export on -struct DriverDescription TheDriverDescription = { - 'mtej', - 0, - "\pvideo", - 0x01008000, // V1.0.0final - 6, // kDriverIsUnderExpertControl, kDriverIsOpenedUponLoad - "\pDisplay_Video_Apple_Sheep", - 0, 0, 0, 0, 0, 0, 0, 0, - 1, - 'ndrv', - 'vido', - 0x01000000, // V1.0.0 -}; -#pragma export off - - -// Prototypes for exported functions -extern "C" { -#pragma export on -extern int16 DoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind); -#pragma export off -} - - -/* - * Do driver IO - */ - -asm int16 DoDriverIO(void *spaceID, void *commandID, void *commandContents, uint32 commandCode, uint32 commandKind) -{ - lwz r2,XLM_TOC - lwz r0,XLM_VIDEO_DOIO - mtctr r0 - bctr -} diff --git a/SheepShaver/src/BeOS/CreatePCIDrivers/hexconv.cpp b/SheepShaver/src/BeOS/CreatePCIDrivers/hexconv.cpp deleted file mode 100644 index 59a0a3e09..000000000 --- a/SheepShaver/src/BeOS/CreatePCIDrivers/hexconv.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include - -int main(int argc, char **argv) -{ - if (argc != 3) { - printf("Usage: %s \n", argv[0]); - return 0; - } - - FILE *fin = fopen(argv[1], "rb"); - if (fin == NULL) { - printf("Can't open '%s' for reading\n", argv[1]); - return 0; - } - - FILE *fout = fopen(argv[2], "w"); - if (fout == NULL) { - printf("Can't open '%s' for writing\n", argv[2]); - return 0; - } - - unsigned char buf[16]; - while (!feof(fin)) { - fprintf(fout, "\t"); - int actual = fread(buf, 1, 16, fin); - for (int i=0; i@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= ../main.cpp main_beos.cpp ../prefs.cpp ../prefs_items.cpp prefs_beos.cpp \ - prefs_editor_beos.cpp sys_beos.cpp ../rom_patches.cpp ../rsrc_patches.cpp \ - ../emul_op.cpp ../name_registry.cpp ../macos_util.cpp ../timer.cpp \ - timer_beos.cpp ../xpram.cpp xpram_beos.cpp ../adb.cpp clip_beos.cpp \ - ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp scsi_beos.cpp \ - ../video.cpp video_beos.cpp ../audio.cpp audio_beos.cpp ../ether.cpp \ - ether_beos.cpp ../serial.cpp serial_beos.cpp ../extfs.cpp extfs_beos.cpp \ - about_window_beos.cpp ../user_strings.cpp user_strings_beos.cpp ../thunks.cpp - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= SheepShaver.rsrc - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= be tracker game media translation textencoding device GL - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = -prefix BeHeaders - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - diff --git a/SheepShaver/src/BeOS/NetPeek/Makefile b/SheepShaver/src/BeOS/NetPeek/Makefile deleted file mode 100644 index 233c7e5fd..000000000 --- a/SheepShaver/src/BeOS/NetPeek/Makefile +++ /dev/null @@ -1,110 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= NetPeek - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= APP - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= NetPeek.cpp - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = ../ ../../include ../NetAddOn - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - diff --git a/SheepShaver/src/BeOS/NetPeek/NetPeek.cpp b/SheepShaver/src/BeOS/NetPeek/NetPeek.cpp deleted file mode 100644 index ccf5629a9..000000000 --- a/SheepShaver/src/BeOS/NetPeek/NetPeek.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * NetPeek.cpp - Utility program for monitoring SheepNet add-on - */ - -#include "sysdeps.h" -#include "sheep_net.h" - -#include - -static area_id buffer_area; // Packet buffer area -static net_buffer *net_buffer_ptr; // Pointer to packet buffer - -int main(void) -{ - area_id handler_buffer; - if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) { - printf("Can't find packet buffer\n"); - return 10; - } - if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) { - printf("Can't clone packet buffer\n"); - return 10; - } - - uint8 *p = net_buffer_ptr->ether_addr; - printf("Ethernet address : %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5]); - printf("read_sem : %d\n", net_buffer_ptr->read_sem); - printf("read_ofs : %d\n", net_buffer_ptr->read_ofs); - printf("read_packet_size : %d\n", net_buffer_ptr->read_packet_size); - printf("read_packet_count : %d\n", net_buffer_ptr->read_packet_count); - printf("write_sem : %d\n", net_buffer_ptr->write_sem); - printf("write_ofs : %d\n", net_buffer_ptr->write_ofs); - printf("write_packet_size : %d\n", net_buffer_ptr->write_packet_size); - printf("write_packet_count: %d\n", net_buffer_ptr->write_packet_count); - - printf("\nRead packets:\n"); - for (int i=0; iread[i]; - printf("cmd : %08lx\n", p->cmd); - printf("length: %d\n", p->length); - } - printf("\nWrite packets:\n"); - for (int i=0; iwrite[i]; - printf("cmd : %08lx\n", p->cmd); - printf("length: %d\n", p->length); - } - return 0; -} diff --git a/SheepShaver/src/BeOS/SaveROM/Makefile b/SheepShaver/src/BeOS/SaveROM/Makefile deleted file mode 100644 index cba232e1a..000000000 --- a/SheepShaver/src/BeOS/SaveROM/Makefile +++ /dev/null @@ -1,110 +0,0 @@ -## BeOS Generic Makefile v2.1 ## - -## Fill in this file to specify the project being created, and the referenced -## makefile-engine will do all of the hard work for you. This handles both -## Intel and PowerPC builds of the BeOS. - -## Application Specific Settings --------------------------------------------- - -# specify the name of the binary -NAME= SaveROM - -# specify the type of binary -# APP: Application -# SHARED: Shared library or add-on -# STATIC: Static library archive -# DRIVER: Kernel Driver -TYPE= APP - -# add support for new Pe and Eddie features -# to fill in generic makefile - -#%{ -# @src->@ - -# specify the source files to use -# full paths or paths relative to the makefile can be included -# all files, regardless of directory, will have their object -# files created in the common object directory. -# Note that this means this makefile will not work correctly -# if two source files with the same name (source.c or source.cpp) -# are included from different directories. Also note that spaces -# in folder names do not work well with this makefile. -SRCS= SaveROM.cpp - -# specify the resource files to use -# full path or a relative path to the resource file can be used. -RSRCS= SaveROM.rsrc - -# @<-src@ -#%} - -# end support for Pe and Eddie - -# specify additional libraries to link against -# there are two acceptable forms of library specifications -# - if your library follows the naming pattern of: -# libXXX.so or libXXX.a you can simply specify XXX -# library: libbe.so entry: be -# -# - if your library does not follow the standard library -# naming scheme you need to specify the path to the library -# and it's name -# library: my_lib.a entry: my_lib.a or path/my_lib.a -LIBS= be - -# specify additional paths to directories following the standard -# libXXX.so or libXXX.a naming scheme. You can specify full paths -# or paths relative to the makefile. The paths included may not -# be recursive, so include all of the paths where libraries can -# be found. Directories where source files are found are -# automatically included. -LIBPATHS= - -# additional paths to look for system headers -# thes use the form: #include
-# source file directories are NOT auto-included here -SYSTEM_INCLUDE_PATHS = - -# additional paths to look for local headers -# thes use the form: #include "header" -# source file directories are automatically included -LOCAL_INCLUDE_PATHS = ../ ../../include ../NetAddOn - -# specify the level of optimization that you desire -# NONE, SOME, FULL -OPTIMIZE= FULL - -# specify any preprocessor symbols to be defined. The symbols will not -# have their values set automatically; you must supply the value (if any) -# to use. For example, setting DEFINES to "DEBUG=1" will cause the -# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" -# would pass "-DDEBUG" on the compiler's command line. -DEFINES= - -# specify special warning levels -# if unspecified default warnings will be used -# NONE = supress all warnings -# ALL = enable all warnings -WARNINGS = - -# specify whether image symbols will be created -# so that stack crawls in the debugger are meaningful -# if TRUE symbols will be created -SYMBOLS = - -# specify debug settings -# if TRUE will allow application to be run from a source-level -# debugger. Note that this will disable all optimzation. -DEBUGGER = - -# specify additional compiler flags for all files -COMPILER_FLAGS = - -# specify additional linker flags -LINKER_FLAGS = - - -## include the makefile-engine -include /boot/develop/etc/makefile-engine - diff --git a/SheepShaver/src/BeOS/SaveROM/README b/SheepShaver/src/BeOS/SaveROM/README deleted file mode 100644 index 37214b340..000000000 --- a/SheepShaver/src/BeOS/SaveROM/README +++ /dev/null @@ -1,8 +0,0 @@ -"SaveROM" is a program that allows you to save the ROM of -a PowerMac running under BeOS to a file. - -1. Copy "sheep_driver" to ~/config/add-ons/kernel/drivers. -2. Double-click the "SaveROM" icon. - -This will create a file called "ROM" which should be 4MB -in size. diff --git a/SheepShaver/src/BeOS/SaveROM/SaveROM.cpp b/SheepShaver/src/BeOS/SaveROM/SaveROM.cpp deleted file mode 100644 index 5796ad5d2..000000000 --- a/SheepShaver/src/BeOS/SaveROM/SaveROM.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * SaveROM - Save Mac ROM to file - * - * Copyright (C) 1998-2004 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include - - -// Constants -const char APP_SIGNATURE[] = "application/x-vnd.cebix-SaveROM"; -const char ROM_FILE_NAME[] = "ROM"; - -// Global variables -static uint8 buf[0x400000]; - -// Application object -class SaveROM : public BApplication { -public: - SaveROM() : BApplication(APP_SIGNATURE) - { - // Find application directory and cwd to it - app_info the_info; - GetAppInfo(&the_info); - BEntry the_file(&the_info.ref); - BEntry the_dir; - the_file.GetParent(&the_dir); - BPath the_path; - the_dir.GetPath(&the_path); - chdir(the_path.Path()); - } - virtual void ReadyToRun(void); -}; - - -/* - * Create application object and start it - */ - -int main(int argc, char **argv) -{ - SaveROM *the_app = new SaveROM(); - the_app->Run(); - delete the_app; - return 0; -} - - -/* - * Display error alert - */ - -static void ErrorAlert(const char *text) -{ - BAlert *alert = new BAlert("SaveROM Error", text, "Quit", NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); - alert->Go(); -} - - -/* - * Display OK alert - */ - -static void InfoAlert(const char *text) -{ - BAlert *alert = new BAlert("SaveROM Message", text, "Quit", NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - alert->Go(); -} - - -/* - * Main program - */ - -void SaveROM::ReadyToRun(void) -{ - int fd = open("/dev/sheep", 0); - if (fd < 0) { - ErrorAlert("Cannot open '/dev/sheep'."); - goto done; - } - - if (read(fd, buf, 0x400000) != 0x400000) { - ErrorAlert("Cannot read ROM."); - close(fd); - goto done; - } - - FILE *f = fopen(ROM_FILE_NAME, "wb"); - if (f == NULL) { - ErrorAlert("Cannot open ROM file."); - close(fd); - goto done; - } - - if (fwrite(buf, 1, 0x400000, f) != 0x400000) { - ErrorAlert("Cannot write ROM."); - fclose(f); - close(fd); - goto done; - } - - InfoAlert("ROM saved."); - - fclose(f); - close(fd); -done: - PostMessage(B_QUIT_REQUESTED); -} diff --git a/SheepShaver/src/BeOS/SaveROM/SaveROM.rsrc b/SheepShaver/src/BeOS/SaveROM/SaveROM.rsrc deleted file mode 100644 index a61919ba80a170f7ce863bf1ad107b503bfc093d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4323 zcmeHJzfV(96h6f&rP24E(N+frH8D6QW?ns-6xt+7^FW7WT>UY0}-HVCQy(3rt zn>hVvJNZ83w3D0s5Rv~eBL7oF{%2gJO0i(alx@S-quaErI*MKyc5>5*x50OwMdZJT z$bS`)|E7U|PWonzY{R#%tGi>0;l%5r}tv*2g^iobY&t+cS@Q$4o6e5-HKUno~HUTNK*Di-)c^gjl+ zkMf_H%YE6tEL-~SJyXW`f_E12x1ilD#UTT}sLKuO)+AO1Y`M z86@CTx;2BvkqsELc^4%vVNeW*M!99uSC^+GL@q89kCT8I z#b8wWA|O!VTNdtCqe34Ms|TOy@H}t>kE8IE579&+KRkie$2>#M^^u}CP#Ey0b94FO z;zW=q9LY*6)_5~(XmWBCI{cdRDPZ)XSqM9`-#4?%nOTr}u>bP2 z!|3_Xr}Zy>JZXP}lZ7{<)35&eE|9=ca$>@jrPD)QZDjqh2rcIqF!>jk!NLe_rS(z|5;$w|?bZI$ZLZFFPmG z_?Opj)7(yTJMDpK5BxtpAn(!-i{h)SX=r{E@D*CREsDH{ueYga8LH`Kv)2_Ip9|1* zAu?N{H#BTpWrE4Lp<9534DHHPdfv~VZ4RHPqdmShVbQR1GxcceMx&wmfuTJyGZ$@N zx8Vb+m&g(269g{z@e;u+A*0g&rSbs}#LoL6B~=u~%s|B#aRomPf*>YK#VWp59Hhwa zB4Wb%;L@C+%%PHeo5V8}IlLCH<(n%o;bs1vyY zvc4tkYA+$&!np9y>zxO7wUauD>!39je}|6<=^rQ_%+rp69iDS+`~{anAoY<32vT}W zuDLem)H1kvhy-gXJ4m>+v&=DQg(p4|j~!(|=S&P&l0g4NDD*8YFfqi}Xck_g?wloaMkdy>tbcIubgmNmjvgZtc<(~xJCZOBj z-3(U_Ukq1AgJ+Sfe4L#3Ux|iCgTwvdvuHS4*}ir2+m8!2Wlu9uWT4x*`-rM^WDN`7 zZES|OySKx~>rXm&Hy@QZF*8QankiTh-)D6@-H>sl_phK~Vm -#include -#include -#include - -#include "about_window.h" -#include "video.h" -#include "version.h" -#include "user_strings.h" - - -// About window dimensions -static const BRect about_frame = BRect(0, 0, 383, 99); - -// Special colors -const rgb_color fill_color = {216, 216, 216, 0}; - -// SheepShaver icon -static const uint8 sheep_icon[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xda, 0x15, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xff, 0x00, 0x00, 0x00, 0x16, 0xda, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, - 0x00, 0x1d, 0xda, 0x1e, 0x1e, 0x1e, 0xda, 0x16, 0x00, 0x00, 0x16, 0xda, 0x16, 0xda, 0x08, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x0b, 0xff, 0xff, 0x11, 0x00, 0xda, - 0x1d, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0x16, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff, - 0xff, 0x0b, 0x00, 0x00, 0x16, 0x16, 0x00, 0x12, 0xfd, 0x1d, 0x0b, 0x00, 0x00, 0x1d, 0xfd, 0x1d, - 0xfd, 0x1e, 0xda, 0x1e, 0xda, 0x1e, 0xda, 0x3f, 0xda, 0x3f, 0xda, 0x15, 0x00, 0xff, 0xff, 0xff, - 0x16, 0x00, 0x17, 0x16, 0x00, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x16, 0x0f, 0x0b, 0x1d, - 0x1e, 0xfd, 0x1e, 0xda, 0x1e, 0xda, 0x3f, 0xda, 0x3f, 0xda, 0x1d, 0x5a, 0x15, 0xff, 0xff, 0xff, - 0x05, 0x17, 0x16, 0x00, 0x12, 0x1d, 0x00, 0x1d, 0xfd, 0x00, 0xfd, 0x00, 0x00, 0x16, 0x0b, 0x00, - 0x00, 0x0e, 0x1d, 0x3f, 0xda, 0x3f, 0xda, 0x1d, 0xda, 0x1b, 0x5a, 0x1b, 0x0f, 0x1d, 0xff, 0xff, - 0xff, 0x05, 0x00, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x00, 0x0f, 0x14, 0x14, - 0x16, 0x00, 0x15, 0xfd, 0x1d, 0xda, 0x1b, 0xda, 0x1b, 0x5a, 0x1b, 0x5a, 0x0f, 0x14, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x12, 0x00, 0x16, 0x00, 0x0f, - 0x00, 0x1b, 0xfd, 0x1e, 0xfd, 0x1b, 0xda, 0x1b, 0x5a, 0x1b, 0x5a, 0x1b, 0x5a, 0x14, 0xff, 0xff, - 0xff, 0x00, 0x1d, 0xfd, 0x1d, 0xfd, 0x1d, 0xfd, 0x1a, 0xfd, 0x12, 0x00, 0x16, 0x1b, 0x16, 0x0e, - 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0x5a, 0x18, 0x00, 0x00, 0x5a, 0x1b, 0x00, 0xff, 0xff, - 0xff, 0x00, 0xfd, 0x14, 0xfd, 0x14, 0xfd, 0x1d, 0xfd, 0x12, 0x00, 0x16, 0xfd, 0x1b, 0xfd, 0x1b, - 0xfd, 0x1b, 0xfd, 0x1e, 0xfd, 0x1b, 0x5a, 0x18, 0x5a, 0x00, 0x00, 0x1b, 0x9b, 0x00, 0xff, 0xff, - 0xff, 0x00, 0x0f, 0xfd, 0x1d, 0xfd, 0x0f, 0xfd, 0x12, 0x00, 0x16, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, - 0x1b, 0xfd, 0x18, 0xfd, 0x1b, 0xf9, 0x18, 0x5a, 0x00, 0x12, 0x00, 0x9b, 0x1b, 0x00, 0xff, 0xff, - 0xff, 0x00, 0xfd, 0x0a, 0x0a, 0x0a, 0xfd, 0x10, 0x00, 0x1b, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x18, - 0xfd, 0x15, 0xfa, 0x15, 0xf9, 0x18, 0x15, 0x00, 0x12, 0x9b, 0x00, 0x1b, 0x9b, 0x00, 0x15, 0x15, - 0xff, 0xff, 0x00, 0xfd, 0x1d, 0xfd, 0x1d, 0x00, 0x16, 0x00, 0x1b, 0xfd, 0x1b, 0xfd, 0x15, 0xfd, - 0x15, 0xfa, 0x15, 0xf9, 0x15, 0x16, 0x00, 0x0f, 0x9b, 0x12, 0x00, 0x9b, 0x1b, 0x00, 0x15, 0x15, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x1d, 0x00, 0xfa, 0x1e, 0x00, 0x1e, 0xfa, 0x15, - 0xfa, 0x15, 0x16, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x12, 0x15, 0x15, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, 0xf9, 0x00, 0x3f, 0xfa, 0x00, 0xfa, 0x1b, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x12, 0x15, 0x15, 0x15, 0x15, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf9, 0x1d, 0x00, 0xf9, 0x1b, 0x00, 0x1b, 0xf9, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1d, 0xf9, 0x00, 0x3f, 0xf9, 0x00, 0xf9, 0x1b, 0x00, - 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x16, 0x1d, 0x00, 0xf9, 0x1b, 0x00, 0x1b, 0xf9, 0x00, - 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x00, 0x16, 0xf9, 0x00, 0x1b, 0x16, 0x00, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00, 0x12, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, - 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0x15, 0x00, 0x0a, 0x19, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x12, 0x00, 0x00, 0x00, 0x16, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x19, 0x1c, 0x18, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0x00, 0x18, 0x11, 0x00, 0x15, 0x00, 0x1c, 0x18, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0x00, 0x0b, 0x0b, - 0x00, 0x00, 0x0f, 0xff, 0x12, 0x00, 0x18, 0x19, 0x00, 0x15, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0x00, 0x14, 0x1e, 0xfd, 0x01, 0xfd, 0x14, - 0xfa, 0xf9, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x19, 0x1c, 0x00, 0x18, 0x1c, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0xfd, 0x1e, 0xf9, 0x1e, 0xfa, 0x1e, 0xf9, - 0x14, 0xfa, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x18, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0x1e, 0xf9, 0x14, 0xfa, 0x1e, 0xf9, 0x1e, - 0xfd, 0x1e, 0x00, 0x15, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x00, 0x00, 0x18, 0x00, 0x1c, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0x00, 0xfd, 0x1e, 0xfd, 0x14, 0xfd, 0x1e, 0xfd, - 0x1e, 0x01, 0x00, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x1c, 0x00, 0x15, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x14, 0xfa, 0x01, 0xf9, 0x1e, 0xf9, 0x14, - 0x14, 0x00, 0x0f, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x00, 0x00, 0x15, 0x15, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; - - -// View class -class AboutViewT : public BView { -public: - AboutViewT(BRect r) : BView(r, "", B_FOLLOW_NONE, B_WILL_DRAW) {} - - virtual void Draw(BRect update) - { - char str[256]; - sprintf(str, GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - - SetFont(be_bold_font); - SetDrawingMode(B_OP_OVER); - MovePenTo(20, 20); - DrawString(str); - SetFont(be_plain_font); - MovePenTo(20, 40); - DrawString(GetString(STR_ABOUT_TEXT2)); - MovePenTo(20, 60); - DrawString(B_UTF8_COPYRIGHT "1997-2008 Christian Bauer and Marc Hellwig"); - } - - virtual void MouseDown(BPoint point) - { - Window()->PostMessage(B_QUIT_REQUESTED); - } -}; - - -// 3D view class -class AboutView3D : public BGLView { -public: - AboutView3D(BRect r) : BGLView(r, "", B_FOLLOW_NONE, 0, BGL_RGB | BGL_DOUBLE) - { - rot_x = rot_y = 0; - - if (!VideoSnapshot(64, 64, texture)) { - uint8 *p = texture; - const uint8 *q = sheep_icon; - const color_map *cm = system_colors(); - for (int i=0; i<32*32; i++) { - uint8 red = cm->color_list[*q].red; - uint8 green = cm->color_list[*q].green; - uint8 blue = cm->color_list[*q++].blue; - p[0] = p[3] = p[64*3] = p[65*3] = red; - p[1] = p[4] = p[64*3+1] = p[65*3+1] = green; - p[2] = p[5] = p[64*3+2] = p[65*3+2] = blue; - p += 6; - if ((i & 31) == 31) - p += 64*3; - } - } - } - - virtual void AttachedToWindow(void) - { - BGLView::AttachedToWindow(); - LockGL(); - - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - - glShadeModel(GL_SMOOTH); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(30, 1, 0.5, 20); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - GLfloat light_color[4] = {1, 1, 1, 1}; - GLfloat light_dir[4] = {1, 2, 1.5, 1}; - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color); - glLightfv(GL_LIGHT0, GL_POSITION, light_dir); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHTING); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexImage2D(GL_TEXTURE_2D, 0, 4, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, texture); - glEnable(GL_TEXTURE_2D); - - UnlockGL(); - - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "OpenGL Animation", B_NORMAL_PRIORITY, this); - resume_thread(tick_thread); - } - - virtual void DetachedFromWindow(void) - { - status_t l; - tick_thread_active = false; - wait_for_thread(tick_thread, &l); - - BGLView::DetachedFromWindow(); - } - - virtual void Draw(BRect update) - { - LockGL(); - glClear(GL_COLOR_BUFFER_BIT); - glBegin(GL_QUADS); - glNormal3d(0, 0, 1); - glTexCoord2f(0, 0); - glVertex3d(-1, 1, 0); - glTexCoord2f(1, 0); - glVertex3d(1, 1, 0); - glTexCoord2f(1, 1); - glVertex3d(1, -1, 0); - glTexCoord2f(0, 1); - glVertex3d(-1, -1, 0); - glEnd(); - SwapBuffers(); - UnlockGL(); - } - - static status_t tick_func(void *arg) - { - AboutView3D *obj = (AboutView3D *)arg; - while (obj->tick_thread_active) { - obj->rot_x += 2; - obj->rot_y += 2; - obj->LockGL(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0, 0, -5); - glRotatef(obj->rot_x, 1, 0, 0); - glRotatef(obj->rot_y, 0, 1, 0); - obj->UnlockGL(); - if (obj->LockLooperWithTimeout(20000) == B_OK) { - obj->Draw(obj->Bounds()); - obj->UnlockLooper(); - } - snooze(16667); - } - return 0; - } - -private: - thread_id tick_thread; - bool tick_thread_active; - - float rot_x, rot_y; - uint8 texture[64*64*3]; -}; - - -// Window class -class AboutWindowT : public BWindow { -public: - AboutWindowT() : BWindow(about_frame, NULL, B_MODAL_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK) - { - Lock(); - MoveTo(100, 100); - BRect r = Bounds(); - r.right = 100; - AboutView3D *view_3d = new AboutView3D(r); - AddChild(view_3d); - r = Bounds(); - r.left = 100; - AboutViewT *view = new AboutViewT(r); - AddChild(view); - view->SetHighColor(0, 0, 0); - view->SetViewColor(fill_color); - view->MakeFocus(); - Unlock(); - Show(); - } -}; - - -/* - * Open "About" window - */ - -void OpenAboutWindow(void) -{ - new AboutWindowT; -} diff --git a/SheepShaver/src/BeOS/audio_beos.cpp b/SheepShaver/src/BeOS/audio_beos.cpp deleted file mode 120000 index ce433abbb..000000000 --- a/SheepShaver/src/BeOS/audio_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/audio_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/BeOS/clip_beos.cpp b/SheepShaver/src/BeOS/clip_beos.cpp deleted file mode 100644 index 953ed8040..000000000 --- a/SheepShaver/src/BeOS/clip_beos.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - * clip_beos.cpp - Clipboard handling, BeOS implementation - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "clip.h" -#include "main.h" -#include "cpu_emulation.h" -#include "emul_op.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static bool we_put_this_data = false; // Flag for PutScrap(): the data was put by GetScrap(), don't bounce it back to the Be side -static BTranslatorRoster *roster; -static float input_cap = 0; -static translator_info input_info; -static float output_cap = 0; -static translator_id output_trans = 0; - - -/* - * Clipboard manager thread (for calling clipboard functions; this is not safe - * under R4 when running on the MacOS stack in kernel space) - */ - -// Message constants -const uint32 MSG_QUIT_CLIP_MANAGER = 'quit'; -const uint32 MSG_PUT_TEXT = 'ptxt'; - -static thread_id cm_thread = -1; -static sem_id cm_done_sem = -1; - -// Argument passing -static void *cm_scrap; -static int32 cm_length; - -static status_t clip_manager(void *arg) -{ - for (;;) { - - // Receive message - thread_id sender; - uint32 code = receive_data(&sender, NULL, 0); - D(bug("Clipboard manager received %08lx\n", code)); - switch (code) { - case MSG_QUIT_CLIP_MANAGER: - return 0; - - case MSG_PUT_TEXT: - if (be_clipboard->Lock()) { - be_clipboard->Clear(); - BMessage *clipper = be_clipboard->Data(); - - // Convert text from Mac charset to UTF-8 - int32 dest_length = cm_length * 3; - int32 state = 0; - char *inbuf = new char[cm_length]; - memcpy(inbuf, cm_scrap, cm_length); // Copy to user space - char *outbuf = new char[dest_length]; - if (convert_to_utf8(B_MAC_ROMAN_CONVERSION, inbuf, &cm_length, outbuf, &dest_length, &state) == B_OK) { - for (int i=0; iAddData("text/plain", B_MIME_TYPE, outbuf, dest_length); - be_clipboard->Commit(); - } else { - D(bug(" text conversion failed\n")); - } - delete[] outbuf; - delete[] inbuf; - be_clipboard->Unlock(); - } - break; - } - - // Acknowledge - release_sem(cm_done_sem); - } -} - - -/* - * Initialize clipboard - */ - -void ClipInit(void) -{ - // check if there is a translator that can handle the pict datatype - roster = BTranslatorRoster::Default(); - int32 num_translators, i,j; - translator_id *translators; - const char *translator_name, *trans_info; - int32 translator_version; - const translation_format *t_formats; - long t_num; - - roster->GetAllTranslators(&translators, &num_translators); - for (i=0;iGetTranslatorInfo(translators[i], &translator_name, - &trans_info, &translator_version); - D(bug("found translator %s: %s (%.2f)\n", translator_name, trans_info, - translator_version/100.)); - // does this translator support the pict datatype ? - roster->GetInputFormats(translators[i], &t_formats,&t_num); - //printf(" supports %d input formats \n",t_num); - for (j=0;jinput_cap) { - input_info.type = t_formats[j].type; - input_info.group = t_formats[j].group; - input_info.quality = t_formats[j].quality; - input_info.capability = t_formats[j].capability; - strcpy(input_info.MIME,t_formats[j].MIME); - strcpy(input_info.name,t_formats[j].name); - input_info.translator=translators[i]; - input_cap = t_formats[j].capability; - } - D(bug("matching input translator found:type:%c%c%c%c group:%c%c%c%c quality:%f capability:%f MIME:%s name:%s\n", - t_formats[j].type>>24,t_formats[j].type>>16,t_formats[j].type>>8,t_formats[j].type, - t_formats[j].group>>24,t_formats[j].group>>16,t_formats[j].group>>8,t_formats[j].group, - t_formats[j].quality, - t_formats[j].capability,t_formats[j].MIME, - t_formats[j].name)); - } - - } - roster->GetOutputFormats(translators[i], &t_formats,&t_num); - //printf("and %d output formats \n",t_num); - for (j=0;joutput_cap) { - output_trans = translators[i]; - output_cap = t_formats[j].capability; - } - D(bug("matching output translator found:type:%c%c%c%c group:%c%c%c%c quality:%f capability:%f MIME:%s name:%s\n", - t_formats[j].type>>24,t_formats[j].type>>16,t_formats[j].type>>8,t_formats[j].type, - t_formats[j].group>>24,t_formats[j].group>>16,t_formats[j].group>>8,t_formats[j].group, - t_formats[j].quality, - t_formats[j].capability,t_formats[j].MIME, - t_formats[j].name)); - } - } - } - delete [] translators; // clean up our droppings - - // Start clipboard manager thread - cm_done_sem = create_sem(0, "Clipboard Manager Done"); - cm_thread = spawn_thread(clip_manager, "Clipboard Manager", B_NORMAL_PRIORITY, NULL); - resume_thread(cm_thread); -} - - -/* - * Deinitialize clipboard - */ - -void ClipExit(void) -{ - // Stop clipboard manager - if (cm_thread > 0) { - status_t l; - send_data(cm_thread, MSG_QUIT_CLIP_MANAGER, NULL, 0); - while (wait_for_thread(cm_thread, &l) == B_INTERRUPTED) ; - } - - // Delete semaphores - delete_sem(cm_done_sem); -} - - -/* - * Mac application wrote to clipboard - */ - -void PutScrap(uint32 type, void *scrap, int32 length) -{ - D(bug("PutScrap type %08lx, data %p, length %ld\n", type, scrap, length)); - if (we_put_this_data) { - we_put_this_data = false; - return; - } - if (length <= 0) - return; - - switch (type) { - case 'TEXT': - D(bug(" clipping TEXT\n")); - cm_scrap = scrap; - cm_length = length; - while (send_data(cm_thread, MSG_PUT_TEXT, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(cm_done_sem) == B_INTERRUPTED) ; - break; - - case 'PICT': - D(bug(" clipping PICT\n")); - //!! this has to be converted to use the Clipboard Manager -#if 0 - if (be_clipboard->Lock()) { - be_clipboard->Clear(); - BMessage *clipper = be_clipboard->Data(); - // Waaaah! This crashes! - if (input_cap > 0) { // if there is an converter for PICT datatype convert data to bitmap. - BMemoryIO *in_buffer = new BMemoryIO(scrap, length); - BMallocIO *out_buffer = new BMallocIO(); - status_t result=roster->Translate(in_buffer,&input_info,NULL,out_buffer,B_TRANSLATOR_BITMAP); - clipper->AddData("image/x-be-bitmap", B_MIME_TYPE, out_buffer->Buffer(), out_buffer->BufferLength()); - D(bug("conversion result:%08x buffer_size:%d\n",result,out_buffer->BufferLength())); - delete in_buffer; - delete out_buffer; - } - clipper->AddData("image/pict", B_MIME_TYPE, scrap, length); - be_clipboard->Commit(); - be_clipboard->Unlock(); - } -#endif - break; - } -} - -/* - * Mac application zeroes clipboard - */ - -void ZeroScrap() -{ - -} - -/* - * Mac application reads clipboard - */ - -void GetScrap(void **handle, uint32 type, int32 offset) -{ - M68kRegisters r; - D(bug("GetScrap handle %p, type %08lx, offset %ld\n", handle, type, offset)); - return; //!! GetScrap is currently broken (should use Clipboard Manager) - //!! replace with clipboard notification in BeOS R4.1 - - switch (type) { - case 'TEXT': - D(bug(" clipping TEXT\n")); - if (be_clipboard->Lock()) { - BMessage *clipper = be_clipboard->Data(); - char *clip; - ssize_t length; - - // Check if we already copied this data - if (clipper->HasData("application/x-SheepShaver-cookie", B_MIME_TYPE)) - return; - bigtime_t cookie = system_time(); - clipper->AddData("application/x-SheepShaver-cookie", B_MIME_TYPE, &cookie, sizeof(bigtime_t)); - - // No, is there text in it? - if (clipper->FindData("text/plain", B_MIME_TYPE, &clip, &length) == B_OK) { - D(bug(" text/plain found\n")); - - // Convert text from UTF-8 to Mac charset - int32 src_length = length; - int32 dest_length = length; - int32 state = 0; - char *outbuf = new char[dest_length]; - if (convert_from_utf8(B_MAC_ROMAN_CONVERSION, clip, &src_length, outbuf, &dest_length, &state) == B_OK) { - for (int i=0; iCommit(); - be_clipboard->Unlock(); - } - break; - - case 'PICT': - D(bug(" clipping PICT\n")); - if (be_clipboard->Lock()) { - BMessage *clipper = be_clipboard->Data(); - char *clip; - ssize_t length; - - // Check if we already copied this data - if (clipper->HasData("application/x-SheepShaver-cookie", B_MIME_TYPE)) - return; - bigtime_t cookie = system_time(); - clipper->AddData("application/x-SheepShaver-cookie", B_MIME_TYPE, &cookie, sizeof(bigtime_t)); - - static uint16 proc2[] = { - 0x598f, // subq.l #4,sp - 0xa9fc, // ZeroScrap() - 0x2f3c, 0, 0, // move.l #length,-(sp) - 0x2f3c, 'PI', 'CT', // move.l #'PICT',-(sp) - 0x2f3c, 0, 0, // move.l #buf,-(sp) - 0xa9fe, // PutScrap() - 0x588f, // addq.l #4,sp - M68K_RTS - }; - - // No, is there a pict ? - if (clipper->FindData("image/pict", B_MIME_TYPE, &clip, &length) == B_OK ) { - D(bug(" image/pict found\n")); - - // Add pict to Mac clipboard - *(int32 *)(proc2 + 3) = length; - *(char **)(proc2 + 9) = clip; - we_put_this_data = true; - Execute68k((uint32)proc2, &r); -#if 0 - // No, is there a bitmap ? - } else if (clipper->FindData("image/x-be-bitmap", B_MIME_TYPE, &clip, &length) == B_OK || output_cap > 0) { - D(bug(" image/x-be-bitmap found\nstarting conversion to PICT\n")); - - BMemoryIO *in_buffer = new BMemoryIO(clip, length); - BMallocIO *out_buffer = new BMallocIO(); - status_t result=roster->Translate(output_trans,in_buffer,NULL,out_buffer,'PICT'); - D(bug("result of conversion:%08x buffer_size:%d\n",result,out_buffer->BufferLength())); - - // Add pict to Mac clipboard - *(int32 *)(proc2 + 3) = out_buffer->BufferLength(); - *(char **)(proc2 + 9) = (char *)out_buffer->Buffer(); - we_put_this_data = true; - Execute68k(proc2, &r); - - delete in_buffer; - delete out_buffer; -#endif - } - be_clipboard->Commit(); - be_clipboard->Unlock(); - } - break; - } -} diff --git a/SheepShaver/src/BeOS/ether_beos.cpp b/SheepShaver/src/BeOS/ether_beos.cpp deleted file mode 100644 index 740f9638d..000000000 --- a/SheepShaver/src/BeOS/ether_beos.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* - * ether_beos.cpp - SheepShaver Ethernet Device Driver (DLPI), BeOS specific stuff - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "ether.h" -#include "ether_defs.h" -#include "prefs.h" -#include "xlowmem.h" -#include "main.h" -#include "user_strings.h" -#include "sheep_net.h" - -#define DEBUG 0 -#include "debug.h" - -#define STATISTICS 0 -#define MONITOR 0 - - -// Global variables -static thread_id read_thread; // Packet receiver thread -static bool ether_thread_active = true; // Flag for quitting the receiver thread - -static area_id buffer_area; // Packet buffer area -static net_buffer *net_buffer_ptr; // Pointer to packet buffer -static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing -static uint32 rd_pos; // Current read position in packet buffer -static uint32 wr_pos; // Current write position in packet buffer - -static bool net_open = false; // Flag: initialization succeeded, network device open - - -// Prototypes -static status_t AO_receive_thread(void *data); - - -/* - * Initialize ethernet - */ - -void EtherInit(void) -{ - // Do nothing if the user disabled the network - if (PrefsFindBool("nonet")) - return; - - // find net-server team -i_wanna_try_that_again: - bool found_add_on = false; - team_info t_info; - int32 t_cookie = 0; - image_info i_info; - int32 i_cookie = 0; - while (get_next_team_info(&t_cookie, &t_info) == B_NO_ERROR) { - if (strstr(t_info.args,"net_server")!=NULL) { - // check if sheep_net add-on is loaded - while (get_next_image_info(t_info.team,&i_cookie,&i_info) == B_NO_ERROR) { - if (strstr(i_info.name,"sheep_net")!=NULL) { - found_add_on = true; - break; - } - } - } - if (found_add_on) break; - } - if (!found_add_on) { - - // Search for sheep_net in network config file - char str[1024]; - bool sheep_net_found = false; - FILE *fin = fopen("/boot/home/config/settings/network", "r"); - while (!feof(fin)) { - fgets(str, 1024, fin); - if (strstr(str, "PROTOCOLS")) - if (strstr(str, "sheep_net")) - sheep_net_found = true; - } - fclose(fin); - - // It was found, so something else must be wrong - if (sheep_net_found) { - WarningAlert(GetString(STR_NO_NET_ADDON_WARN)); - return; - } - - // Not found, inform the user - if (!ChoiceAlert(GetString(STR_NET_CONFIG_MODIFY_WARN), GetString(STR_OK_BUTTON), GetString(STR_CANCEL_BUTTON))) - return; - - // Change the network config file and restart the network - fin = fopen("/boot/home/config/settings/network", "r"); - FILE *fout = fopen("/boot/home/config/settings/network.2", "w"); - bool global_found = false; - bool modified = false; - while (!feof(fin)) { - str[0] = 0; - fgets(str, 1024, fin); - if (!global_found && strstr(str, "GLOBAL:")) { - global_found = true; - } else if (global_found && !modified && strstr(str, "PROTOCOLS")) { - str[strlen(str)-1] = 0; - strcat(str, " sheep_net\n"); - modified = true; - } else if (global_found && !modified && strlen(str) > 2 && str[strlen(str) - 2] == ':') { - fputs("\tPROTOCOLS = sheep_net\n", fout); - modified = true; - } - fputs(str, fout); - } - if (!modified) - fputs("\tPROTOCOLS = sheep_net\n", fout); - fclose(fout); - fclose(fin); - remove("/boot/home/config/settings/network.orig"); - rename("/boot/home/config/settings/network", "/boot/home/config/settings/network.orig"); - rename("/boot/home/config/settings/network.2", "/boot/home/config/settings/network"); - - app_info ai; - if (be_roster->GetAppInfo("application/x-vnd.Be-NETS", &ai) == B_OK) { - BMessenger msg(NULL, ai.team); - if (msg.IsValid()) { - while (be_roster->IsRunning("application/x-vnd.Be-NETS")) { - msg.SendMessage(B_QUIT_REQUESTED); - snooze(500000); - } - } - } - BPath path; - find_directory(B_BEOS_BOOT_DIRECTORY, &path); - path.Append("Netscript"); - char *argv[3] = {"/bin/sh", (char *)path.Path(), NULL}; - thread_id net_server = load_image(2, argv, environ); - resume_thread(net_server); - status_t l; - wait_for_thread(net_server, &l); - goto i_wanna_try_that_again; - } - - // Set up communications with add-on - area_id handler_buffer; - if ((handler_buffer = find_area("packet buffer")) < B_NO_ERROR) { - WarningAlert(GetString(STR_NET_ADDON_INIT_FAILED)); - return; - } - if ((buffer_area = clone_area("local packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, handler_buffer)) < B_NO_ERROR) { - D(bug("EtherInit: couldn't clone packet area\n")); - WarningAlert(GetString(STR_NET_ADDON_CLONE_FAILED)); - return; - } - if ((read_sem = create_sem(0, "ether read")) < B_NO_ERROR) { - printf("FATAL: can't create Ethernet semaphore\n"); - return; - } - net_buffer_ptr->read_sem = read_sem; - write_sem = net_buffer_ptr->write_sem; - read_thread = spawn_thread(AO_receive_thread, "ether read", B_URGENT_DISPLAY_PRIORITY, NULL); - resume_thread(read_thread); - for (int i=0; iwrite[i].cmd = IN_USE | (ACTIVATE_SHEEP_NET << 8); - rd_pos = wr_pos = 0; - release_sem(write_sem); - - // Everything OK - net_open = true; -} - - -/* - * Exit ethernet - */ - -void EtherExit(void) -{ - if (net_open) { - - // Close communications with add-on - for (int i=0; iwrite[i].cmd = IN_USE | (DEACTIVATE_SHEEP_NET << 8); - release_sem(write_sem); - - // Quit receiver thread - ether_thread_active = false; - status_t result; - release_sem(read_sem); - while (wait_for_thread(read_thread, &result) == B_INTERRUPTED) ; - - delete_sem(read_sem); - delete_area(buffer_area); - } - -#if STATISTICS - // Show statistics - printf("%ld messages put on write queue\n", num_wput); - printf("%ld error acks\n", num_error_acks); - printf("%ld packets transmitted (%ld raw, %ld normal)\n", num_tx_packets, num_tx_raw_packets, num_tx_normal_packets); - printf("%ld tx packets dropped because buffer full\n", num_tx_buffer_full); - printf("%ld packets received\n", num_rx_packets); - printf("%ld packets passed upstream (%ld Fast Path, %ld normal)\n", num_rx_fastpath + num_unitdata_ind, num_rx_fastpath, num_unitdata_ind); - printf("EtherIRQ called %ld times\n", num_ether_irq); - printf("%ld rx packets dropped due to low memory\n", num_rx_no_mem); - printf("%ld rx packets dropped because no stream found\n", num_rx_dropped); - printf("%ld rx packets dropped because stream not ready\n", num_rx_stream_not_ready); - printf("%ld rx packets dropped because no memory for unitdata_ind\n", num_rx_no_unitdata_mem); -#endif -} - - -/* - * Ask add-on for ethernet hardware address - */ - -void AO_get_ethernet_address(uint32 arg) -{ - uint8 *addr = Mac2HostAddr(arg); - if (net_open) { - OTCopy48BitAddress(net_buffer_ptr->ether_addr, addr); - } else { - addr[0] = 0x12; - addr[1] = 0x34; - addr[2] = 0x56; - addr[3] = 0x78; - addr[4] = 0x9a; - addr[5] = 0xbc; - } - D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5])); -} - - -/* - * Tell add-on to enable multicast address - */ - -void AO_enable_multicast(uint32 addr) -{ - D(bug("AO_enable_multicast\n")); - if (net_open) { - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: couldn't enable multicast address\n")); - } else { - Mac2host_memcpy(p->data, addr, 6); - p->length = 6; - p->cmd = IN_USE | (ADD_MULTICAST << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - } -} - - -/* - * Tell add-on to disable multicast address - */ - -void AO_disable_multicast(uint32 addr) -{ - D(bug("AO_disable_multicast\n")); - if (net_open) { - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: couldn't enable multicast address\n")); - } else { - Mac2host_memcpy(p->data, addr, 6); - p->length = 6; - p->cmd = IN_USE | (REMOVE_MULTICAST << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - D(bug("WARNING: couldn't disable multicast address\n")); - } -} - - -/* - * Tell add-on to transmit one packet - */ - -void AO_transmit_packet(uint32 mp_arg) -{ - D(bug("AO_transmit_packet\n")); - if (net_open) { - net_packet *p = &net_buffer_ptr->write[wr_pos]; - if (p->cmd & IN_USE) { - D(bug("WARNING: couldn't transmit packet (buffer full)\n")); - num_tx_buffer_full++; - } else { - D(bug(" write packet pos %d\n", i)); - num_tx_packets++; - - // Copy packet to buffer - uint8 *start; - uint8 *bp = start = p->data; - mblk_t *mp = Mac2HostAddr(mp_arg); - while (mp) { - uint32 size = mp->b_wptr - mp->b_rptr; - memcpy(bp, mp->b_rptr, size); - bp += size; - mp = mp->b_cont; - } - -#if MONITOR - bug("Sending Ethernet packet:\n"); - for (int i=0; i<(uint32)(bp - start); i++) { - bug("%02lx ", start[i]); - } - bug("\n"); -#endif - - // Notify add-on - p->length = (uint32)(bp - start); - p->cmd = IN_USE | (SHEEP_PACKET << 8); - wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT; - release_sem(write_sem); - } - } -} - - -/* - * Packet reception thread - */ - -static status_t AO_receive_thread(void *data) -{ - while (ether_thread_active) { - if (net_buffer_ptr->read[rd_pos].cmd & IN_USE) { - if (ether_driver_opened) { - D(bug(" packet received, triggering Ethernet interrupt\n")); - SetInterruptFlag(INTFLAG_ETHER); - TriggerInterrupt(); - } - } - acquire_sem_etc(read_sem, 1, B_TIMEOUT, 25000); - } - return 0; -} - - -/* - * Ethernet interrupt - */ - -void EtherIRQ(void) -{ - D(bug("EtherIRQ\n")); - num_ether_irq++; - OTEnterInterrupt(); - - // Send received packets to OpenTransport - net_packet *p = &net_buffer_ptr->read[rd_pos]; - while (p->cmd & IN_USE) { - if ((p->cmd >> 8) == SHEEP_PACKET) { - num_rx_packets++; - D(bug(" read packet pos %d\n", i)); - uint32 size = p->length; - -#if MONITOR - bug("Receiving Ethernet packet:\n"); - for (int i=0; idata[i]); - } - bug("\n"); -#endif - - // Wrap packet in message block - //!! maybe use esballoc() - mblk_t *mp; - if ((mp = allocb(size, 0)) != NULL) { - D(bug(" packet data at %p\n", (void *)mp->b_rptr)); - memcpy(mp->b_rptr, p->data, size); - mp->b_wptr += size; - ether_packet_received(mp); - } else { - D(bug("WARNING: Cannot allocate mblk for received packet\n")); - num_rx_no_mem++; - } - } - p->cmd = 0; // Free packet - rd_pos = (rd_pos + 1) % READ_PACKET_COUNT; - p = &net_buffer_ptr->read[rd_pos]; - } - OTLeaveInterrupt(); -} diff --git a/SheepShaver/src/BeOS/extfs_beos.cpp b/SheepShaver/src/BeOS/extfs_beos.cpp deleted file mode 120000 index e7cec3dcd..000000000 --- a/SheepShaver/src/BeOS/extfs_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/extfs_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/BeOS/main_beos.cpp b/SheepShaver/src/BeOS/main_beos.cpp deleted file mode 100644 index 551cd5180..000000000 --- a/SheepShaver/src/BeOS/main_beos.cpp +++ /dev/null @@ -1,2015 +0,0 @@ -/* - * main_beos.cpp - Emulation core, BeOS implementation - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * - * SheepShaver uses three run-time environments, reflected by the value of XLM_RUN_MODE. - * The two modes which are also present in the original MacOS, are: - * MODE_68K - 68k emulator is active - * MODE_NATIVE - 68k emulator is inactive - * In the original MacOS, these two modes have different memory mappings and exception - * tables. Under SheepShaver, the only difference is the handling of interrupts (see below). - * SheepShaver extends the 68k emulator with special opcodes (EMUL_OP) to perform faster - * mode switches when patching 68k routines with PowerPC code and adds a third run mode: - * MODE_EMUL_OP - 68k emulator active, but native register usage - * - * Switches between MODE_68K and MODE_NATIVE are only done with the Mixed Mode Manager - * (via nanokernel patches). The switch from MODE_68K to MODE_EMUL_OP occurs when executin - * one of the EMUL_OP 68k opcodes. When the opcode routine is done, it returns to MODE_68K. - * - * The Execute68k() routine allows EMUL_OP routines to execute 68k subroutines. It switches - * from MODE_EMUL_OP back to MODE_68K, so it must not be used by native routines (executing - * in MODE_NATIVE) nor by any other thread than the emul_thread (because the 68k emulator - * is not reentrant). When the 68k subroutine returns, it switches back to MODE_EMUL_OP. - * It is OK for a 68k routine called with Execute68k() to contain an EMUL_OP opcode. - * - * The handling of interrupts depends on the current run mode: - * MODE_68K - The USR1 signal handler sets one bit in the processor's CR. The 68k emulator - * will then execute the 68k interrupt routine when fetching the next instruction. - * MODE_NATIVE - The USR1 signal handler switches back to the original stack (signals run - * on a separate signal stack) and enters the External Interrupt routine in the - * nanokernel. - * MODE_EMUL_OP - The USR1 signal handler directly executes the 68k interrupt routine - * with Execute68k(). Before doing this, it must first check the current 68k interrupt - * level which is stored in XLM_68K_R25. This variable is set to the current level - * when entering EMUL_OP mode. Execute68k() also uses it to restore the level so that - * Execute68k()'d routines will run at the same interrupt level as the EMUL_OP routine - * it was called from. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "main.h" -#include "version.h" -#include "prefs.h" -#include "prefs_editor.h" -#include "cpu_emulation.h" -#include "emul_op.h" -#include "xlowmem.h" -#include "xpram.h" -#include "timer.h" -#include "adb.h" -#include "video.h" -#include "sys.h" -#include "macos_util.h" -#include "rom_patches.h" -#include "user_strings.h" - -#include "sheep_driver.h" - -#define DEBUG 0 -#include "debug.h" - -// Enable Execute68k() safety checks? -#define SAFE_EXEC_68K 0 - -// Save FP regs in Execute68k()? -#define SAVE_FP_EXEC_68K 0 - -// Interrupts in EMUL_OP mode? -#define INTERRUPTS_IN_EMUL_OP_MODE 1 - -// Interrupts in native mode? -#define INTERRUPTS_IN_NATIVE_MODE 1 - - -// Constants -const char APP_SIGNATURE[] = "application/x-vnd.cebix-SheepShaver"; -const char ROM_FILE_NAME[] = "ROM"; -const char ROM_FILE_NAME2[] = "Mac OS ROM"; -const char KERNEL_AREA_NAME[] = "Macintosh Kernel Data"; -const char KERNEL_AREA2_NAME[] = "Macintosh Kernel Data 2"; -const char RAM_AREA_NAME[] = "Macintosh RAM"; -const char ROM_AREA_NAME[] = "Macintosh ROM"; -const char DR_CACHE_AREA_NAME[] = "Macintosh DR Cache"; -const char DR_EMULATOR_AREA_NAME[] = "Macintosh DR Emulator"; -const char SHEEP_AREA_NAME[] = "SheepShaver Virtual Stack"; - -const uintptr ROM_BASE = 0x40800000; // Base address of ROM - -const uint32 SIG_STACK_SIZE = 8192; // Size of signal stack - -const uint32 MSG_START = 'strt'; // Emulator start message - - -// Application object -class SheepShaver : public BApplication { -public: - SheepShaver() : BApplication(APP_SIGNATURE) - { - // Find application directory and cwd to it - app_info the_info; - GetAppInfo(&the_info); - BEntry the_file(&the_info.ref); - BEntry the_dir; - the_file.GetParent(&the_dir); - BPath the_path; - the_dir.GetPath(&the_path); - chdir(the_path.Path()); - - // Initialize other variables - sheep_fd = -1; - emulator_data = NULL; - kernel_area = kernel_area2 = rom_area = ram_area = dr_cache_area = dr_emulator_area = -1; - emul_thread = nvram_thread = tick_thread = -1; - ReadyForSignals = false; - AllowQuitting = true; - NVRAMThreadActive = true; - TickThreadActive = true; - memset(last_xpram, 0, XPRAM_SIZE); - } - virtual void ReadyToRun(void); - virtual void MessageReceived(BMessage *msg); - void StartEmulator(void); - virtual bool QuitRequested(void); - virtual void Quit(void); - - thread_id emul_thread; // Emulator thread - thread_id nvram_thread; // NVRAM watchdog thread - thread_id tick_thread; // 60Hz thread - - KernelData *kernel_data; // Pointer to Kernel Data - EmulatorData *emulator_data; - - bool ReadyForSignals; // Flag: emul_thread ready to receive signals - bool AllowQuitting; // Flag: Alt-Q quitting allowed - bool NVRAMThreadActive; // nvram_thread will exit when this is false - bool TickThreadActive; // tick_thread will exit when this is false - - uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes - -private: - static status_t emul_func(void *arg); - static status_t nvram_func(void *arg); - static status_t tick_func(void *arg); - static void sigusr1_invoc(int sig, void *arg, vregs *r); - void sigusr1_handler(vregs *r); - static void sigsegv_invoc(int sig, void *arg, vregs *r); - static void sigill_invoc(int sig, void *arg, vregs *r); - void jump_to_rom(uint32 entry); - - void init_rom(void); - void load_rom(void); - - int sheep_fd; // FD of sheep driver - - area_id kernel_area; // Kernel Data area ID - area_id kernel_area2; // Alternate Kernel Data area ID - area_id rom_area; // ROM area ID - area_id ram_area; // RAM area ID - area_id dr_cache_area; // DR Cache area ID - area_id dr_emulator_area; // DR Emulator area ID - - struct sigaction sigusr1_action; // Interrupt signal (of emulator thread) - struct sigaction sigsegv_action; // Data access exception signal (of emulator thread) - struct sigaction sigill_action; // Illegal instruction exception signal (of emulator thread) - - // Exceptions - class area_error {}; - class file_open_error {}; - class file_read_error {}; - class rom_size_error {}; -}; - - -// Global variables -SheepShaver *the_app; // Pointer to application object -#if !EMULATED_PPC -void *TOC; // TOC pointer -#endif -uint32 RAMBase; // Base address of Mac RAM -uint32 RAMSize; // Size of Mac RAM -uint32 ROMBase; // Base address of Mac ROM -uint32 KernelDataAddr; // Address of Kernel Data -uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM -uint32 DRCacheAddr; // Address of DR Cache -uint32 DREmulatorAddr; // Address of DR Emulator -uint32 PVR; // Theoretical PVR -int64 CPUClockSpeed; // Processor clock speed (Hz) -int64 BusClockSpeed; // Bus clock speed (Hz) -int64 TimebaseSpeed; // Timebase clock speed (Hz) -system_info SysInfo; // System information -uint8 *RAMBaseHost; // Base address of Mac RAM (host address space) -uint8 *ROMBaseHost; // Base address of Mac ROM (host address space) - -static void *sig_stack = NULL; // Stack for signal handlers -static void *extra_stack = NULL; // Stack for SIGSEGV inside interrupt handler -uint32 SheepMem::page_size; // Size of a native page -uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros -uintptr SheepMem::base; // Address of SheepShaver data -uintptr SheepMem::proc; // Bottom address of SheepShave procedures -uintptr SheepMem::data; // Top of SheepShaver data (stack like storage) -static area_id SheepMemArea; // SheepShaver data area ID - - -// Prototypes -static void sigsegv_handler(vregs *r); -static void sigill_handler(vregs *r); - - -/* - * Create application object and start it - */ - -int main(int argc, char **argv) -{ - tzset(); - the_app = new SheepShaver(); - the_app->Run(); - delete the_app; - return 0; -} - - -/* - * Run application - */ - -#if !EMULATED_PPC -static asm void *get_toc(void) -{ - mr r3,r2 - blr -} -#endif - -void SheepShaver::ReadyToRun(void) -{ - // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - -#if !EMULATED_PPC - // Get TOC pointer - TOC = get_toc(); -#endif - - // Get system info - get_system_info(&SysInfo); - switch (SysInfo.cpu_type) { - case B_CPU_PPC_601: - PVR = 0x00010000; - break; - case B_CPU_PPC_603: - PVR = 0x00030000; - break; - case B_CPU_PPC_603e: - PVR = 0x00060000; - break; - case B_CPU_PPC_604: - PVR = 0x00040000; - break; - case B_CPU_PPC_604e: - PVR = 0x00090000; - break; - case B_CPU_PPC_750: - PVR = 0x00080000; - break; - default: - PVR = 0x00040000; - break; - } - CPUClockSpeed = SysInfo.cpu_clock_speed; - BusClockSpeed = SysInfo.bus_clock_speed; - TimebaseSpeed = BusClockSpeed / 4; - - // Delete old areas - area_id old_kernel_area = find_area(KERNEL_AREA_NAME); - if (old_kernel_area > 0) - delete_area(old_kernel_area); - area_id old_kernel2_area = find_area(KERNEL_AREA2_NAME); - if (old_kernel2_area > 0) - delete_area(old_kernel2_area); - area_id old_ram_area = find_area(RAM_AREA_NAME); - if (old_ram_area > 0) - delete_area(old_ram_area); - area_id old_rom_area = find_area(ROM_AREA_NAME); - if (old_rom_area > 0) - delete_area(old_rom_area); - area_id old_dr_cache_area = find_area(DR_CACHE_AREA_NAME); - if (old_dr_cache_area > 0) - delete_area(old_dr_cache_area); - area_id old_dr_emulator_area = find_area(DR_EMULATOR_AREA_NAME); - if (old_dr_emulator_area > 0) - delete_area(old_dr_emulator_area); - - // Read preferences - int argc = 0; - char **argv = NULL; - PrefsInit(NULL, argc, argv); - - // Init system routines - SysInit(); - - // Test amount of RAM available for areas - if (SysInfo.max_pages * B_PAGE_SIZE < 16 * 1024 * 1024) { - ErrorAlert(GetString(STR_NOT_ENOUGH_MEMORY_ERR)); - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Show preferences editor (or start emulator directly) - if (!PrefsFindBool("nogui")) - PrefsEditor(MSG_START); - else - PostMessage(MSG_START); -} - - -/* - * Message received - */ - -void SheepShaver::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case MSG_START: - StartEmulator(); - break; - default: - BApplication::MessageReceived(msg); - } -} - - -/* - * Start emulator - */ - -void SheepShaver::StartEmulator(void) -{ - char str[256]; - - // Open sheep driver and remap low memory - sheep_fd = open("/dev/sheep", 0); - if (sheep_fd < 0) { - sprintf(str, GetString(STR_NO_SHEEP_DRIVER_ERR), strerror(sheep_fd), sheep_fd); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - status_t res = ioctl(sheep_fd, SHEEP_UP); - if (res < 0) { - sprintf(str, GetString(STR_SHEEP_UP_ERR), strerror(res), res); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Create areas for Kernel Data - kernel_data = (KernelData *)KERNEL_DATA_BASE; - kernel_area = create_area(KERNEL_AREA_NAME, &kernel_data, B_EXACT_ADDRESS, KERNEL_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (kernel_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(kernel_area), kernel_area); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - emulator_data = &kernel_data->ed; - KernelDataAddr = (uint32)kernel_data; - D(bug("Kernel Data area %ld at %p, Emulator Data at %p\n", kernel_area, kernel_data, emulator_data)); - - void *kernel_data2 = (void *)KERNEL_DATA2_BASE; - kernel_area2 = clone_area(KERNEL_AREA2_NAME, &kernel_data2, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, kernel_area); - if (kernel_area2 < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(kernel_area2), kernel_area2); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - D(bug("Kernel Data 2 area %ld at %p\n", kernel_area2, kernel_data2)); - - // Create area for SheepShaver data - if (!SheepMem::Init()) { - sprintf(str, GetString(STR_NO_SHEEP_MEM_AREA_ERR), strerror(SheepMemArea), SheepMemArea); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Create area for Mac RAM - RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 8*1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 8*1024*1024; - } - - RAMBase = 0x10000000; - ram_area = create_area(RAM_AREA_NAME, (void **)&RAMBase, B_BASE_ADDRESS, RAMSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (ram_area < 0) { - sprintf(str, GetString(STR_NO_RAM_AREA_ERR), strerror(ram_area), ram_area); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - RAMBaseHost = (uint8 *)RAMBase; - D(bug("RAM area %ld at %p\n", ram_area, RAMBaseHost)); - - // Create area and load Mac ROM - try { - init_rom(); - } catch (area_error) { - ErrorAlert(GetString(STR_NO_ROM_AREA_ERR)); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (file_open_error) { - ErrorAlert(GetString(STR_NO_ROM_FILE_ERR)); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (file_read_error) { - ErrorAlert(GetString(STR_ROM_FILE_READ_ERR)); - PostMessage(B_QUIT_REQUESTED); - return; - } catch (rom_size_error) { - ErrorAlert(GetString(STR_ROM_SIZE_ERR)); - PostMessage(B_QUIT_REQUESTED); - return; - } - - // Create area for DR Cache - DRCacheAddr = DR_CACHE_BASE; - dr_cache_area = create_area(DR_CACHE_AREA_NAME, (void **)&DRCacheAddr, B_EXACT_ADDRESS, DR_CACHE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (dr_cache_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(dr_cache_area), dr_cache_area); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - D(bug("DR Cache area %ld at %p\n", dr_cache_area, DRCacheAddr)); - - // Create area for DR Emulator - DREmulatorAddr = DR_EMULATOR_BASE; - dr_emulator_area = create_area(DR_EMULATOR_AREA_NAME, (void **)&DREmulatorAddr, B_EXACT_ADDRESS, DR_EMULATOR_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (dr_emulator_area < 0) { - sprintf(str, GetString(STR_NO_KERNEL_DATA_ERR), strerror(dr_emulator_area), dr_emulator_area); - ErrorAlert(str); - PostMessage(B_QUIT_REQUESTED); - return; - } - D(bug("DR Emulator area %ld at %p\n", dr_emulator_area, DREmulatorAddr)); - - // Initialize everything - if (!InitAll(NULL)) { - PostMessage(B_QUIT_REQUESTED); - return; - } - D(bug("Initialization complete\n")); - - // Clear caches (as we loaded and patched code) and write protect ROM -#if !EMULATED_PPC - clear_caches(ROMBaseHost, ROM_AREA_SIZE, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE); -#endif - set_area_protection(rom_area, B_READ_AREA); - - // Initialize extra low memory - D(bug("Initializing extra Low Memory...\n")); - WriteMacInt32(XLM_SHEEP_OBJ, (uint32)this); // Pointer to SheepShaver object - D(bug("Extra Low Memory initialized\n")); - - // Disallow quitting with Alt-Q from now on - AllowQuitting = false; - - // Start 60Hz interrupt - tick_thread = spawn_thread(tick_func, "60Hz", B_URGENT_DISPLAY_PRIORITY, this); - resume_thread(tick_thread); - - // Start NVRAM watchdog thread - memcpy(last_xpram, XPRAM, XPRAM_SIZE); - nvram_thread = spawn_thread(nvram_func, "NVRAM Watchdog", B_LOW_PRIORITY, this); - resume_thread(nvram_thread); - - // Start emulator thread - emul_thread = spawn_thread(emul_func, "MacOS", B_NORMAL_PRIORITY, this); - resume_thread(emul_thread); -} - - -/* - * Quit requested - */ - -bool SheepShaver::QuitRequested(void) -{ - if (AllowQuitting) - return BApplication::QuitRequested(); - else - return false; -} - -void SheepShaver::Quit(void) -{ - status_t l; - - // Stop 60Hz interrupt - if (tick_thread > 0) { - TickThreadActive = false; - wait_for_thread(tick_thread, &l); - } - - // Stop NVRAM watchdog - if (nvram_thread > 0) { - status_t l; - NVRAMThreadActive = false; - suspend_thread(nvram_thread); // Wake thread up from snooze() - snooze(1000); - resume_thread(nvram_thread); - while (wait_for_thread(nvram_thread, &l) == B_INTERRUPTED) ; - } - - // Wait for emulator thread to finish - if (emul_thread > 0) - wait_for_thread(emul_thread, &l); - - // Deinitialize everything - ExitAll(); - - // Delete SheepShaver globals - SheepMem::Exit(); - - // Delete DR Emulator area - if (dr_emulator_area >= 0) - delete_area(dr_emulator_area); - - // Delete DR Cache area - if (dr_cache_area >= 0) - delete_area(dr_cache_area); - - // Delete ROM area - if (rom_area >= 0) - delete_area(rom_area); - - // Delete RAM area - if (ram_area >= 0) - delete_area(ram_area); - - // Delete Kernel Data area2 - if (kernel_area2 >= 0) - delete_area(kernel_area2); - if (kernel_area >= 0) - delete_area(kernel_area); - - // Unmap low memory and close sheep driver - if (sheep_fd >= 0) { - ioctl(sheep_fd, SHEEP_DOWN); - close(sheep_fd); - } - - // Exit system routines - SysExit(); - - // Exit preferences - PrefsExit(); - - BApplication::Quit(); -} - - -/* - * Create area for ROM (sets rom_area) and load ROM file - * - * area_error : Cannot create area - * file_open_error: Cannot open ROM file - * file_read_error: Cannot read ROM file - */ - -void SheepShaver::init_rom(void) -{ - // Size of a native page - page_size = B_PAGE_SIZE; - - // Create area for ROM - ROMBase = ROM_BASE; - rom_area = create_area(ROM_AREA_NAME, (void **)&ROMBase, B_EXACT_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (rom_area < 0) - throw area_error(); - ROMBaseHost = (uint8 *)ROMBase; - D(bug("ROM area %ld at %p\n", rom_area, rom_addr)); - - // Load ROM - load_rom(); -} - - -/* - * Load ROM file - * - * file_open_error: Cannot open ROM file (nor use built-in ROM) - * file_read_error: Cannot read ROM file - */ - -void SheepShaver::load_rom(void) -{ - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - - // Try to open ROM file - BFile file(rom_path && *rom_path ? rom_path : ROM_FILE_NAME, B_READ_ONLY); - if (file.InitCheck() != B_NO_ERROR) { - - // Failed, then ask memory_mess driver for ROM - uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work - ssize_t actual = read(sheep_fd, (void *)rom, ROM_SIZE); - if (actual == ROM_SIZE) { - memcpy(ROMBaseHost, rom, ROM_SIZE); - delete[] rom; - return; - } else - throw file_open_error(); - } - - printf(GetString(STR_READING_ROM_FILE)); - - // Get file size - off_t rom_size = 0; - file.GetSize(&rom_size); - - uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work - ssize_t actual = file.Read((void *)rom, ROM_SIZE); - - // Decode Mac ROM - if (!DecodeROM(rom, actual)) { - if (rom_size != 4*1024*1024) - throw rom_size_error(); - else - throw file_read_error(); - } - delete[] rom; -} - - -/* - * Emulator thread function - */ - -status_t SheepShaver::emul_func(void *arg) -{ - SheepShaver *obj = (SheepShaver *)arg; - - // Install interrupt signal handler - sigemptyset(&obj->sigusr1_action.sa_mask); - obj->sigusr1_action.sa_handler = (__signal_func_ptr)(obj->sigusr1_invoc); - obj->sigusr1_action.sa_flags = 0; - obj->sigusr1_action.sa_userdata = arg; - sigaction(SIGUSR1, &obj->sigusr1_action, NULL); - - // Install data access signal handler - sigemptyset(&obj->sigsegv_action.sa_mask); - obj->sigsegv_action.sa_handler = (__signal_func_ptr)(obj->sigsegv_invoc); - obj->sigsegv_action.sa_flags = 0; - obj->sigsegv_action.sa_userdata = arg; - sigaction(SIGSEGV, &obj->sigsegv_action, NULL); - -#if !EMULATED_PPC - // Install illegal instruction signal handler - sigemptyset(&obj->sigill_action.sa_mask); - obj->sigill_action.sa_handler = (__signal_func_ptr)(obj->sigill_invoc); - obj->sigill_action.sa_flags = 0; - obj->sigill_action.sa_userdata = arg; - sigaction(SIGILL, &obj->sigill_action, NULL); -#endif - - // Exceptions will send signals - disable_debugger(true); - - // Install signal stack - sig_stack = malloc(SIG_STACK_SIZE); - extra_stack = malloc(SIG_STACK_SIZE); - set_signal_stack(sig_stack, SIG_STACK_SIZE); - - // We're now ready to receive signals - obj->ReadyForSignals = true; - - // Jump to ROM boot routine - D(bug("Jumping to ROM\n")); - obj->jump_to_rom(ROMBase + 0x310000); - D(bug("Returned from ROM\n")); - - // We're no longer ready to receive signals - obj->ReadyForSignals = false; - obj->AllowQuitting = true; - - // Quit program - be_app->PostMessage(B_QUIT_REQUESTED); - return 0; -} - - -/* - * Jump into Mac ROM, start 680x0 emulator - * (also contains other EMUL_RETURN and EMUL_OP routines) - */ - -#if EMULATED_PPC -extern void emul_ppc(uint32 start); -extern void init_emul_ppc(void); -void SheepShaver::jump_to_rom(uint32 entry) -{ - init_emul_ppc(); - emul_ppc(entry); -} -#else -asm void SheepShaver::jump_to_rom(register uint32 entry) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - mfcr r0 - stw r0,4(r1) - stwu r1,-(56+19*4+18*8)(r1) - - // Save PowerPC registers - stmw r13,56(r1) - stfd f14,56+19*4+0*8(r1) - stfd f15,56+19*4+1*8(r1) - stfd f16,56+19*4+2*8(r1) - stfd f17,56+19*4+3*8(r1) - stfd f18,56+19*4+4*8(r1) - stfd f19,56+19*4+5*8(r1) - stfd f20,56+19*4+6*8(r1) - stfd f21,56+19*4+7*8(r1) - stfd f22,56+19*4+8*8(r1) - stfd f23,56+19*4+9*8(r1) - stfd f24,56+19*4+10*8(r1) - stfd f25,56+19*4+11*8(r1) - stfd f26,56+19*4+12*8(r1) - stfd f27,56+19*4+13*8(r1) - stfd f28,56+19*4+14*8(r1) - stfd f29,56+19*4+15*8(r1) - stfd f30,56+19*4+16*8(r1) - stfd f31,56+19*4+17*8(r1) - - // Move entry address to ctr, get pointer to Emulator Data - mtctr r4 - lwz r4,SheepShaver.emulator_data(r3) - - // Skip over EMUL_RETURN routine and get its address - bl @1 - - - /* - * EMUL_RETURN: Returned from emulator - */ - - // Restore PowerPC registers - lwz r1,XLM_EMUL_RETURN_STACK - lwz r2,XLM_TOC - lmw r13,56(r1) - lfd f14,56+19*4+0*8(r1) - lfd f15,56+19*4+1*8(r1) - lfd f16,56+19*4+2*8(r1) - lfd f17,56+19*4+3*8(r1) - lfd f18,56+19*4+4*8(r1) - lfd f19,56+19*4+5*8(r1) - lfd f20,56+19*4+6*8(r1) - lfd f21,56+19*4+7*8(r1) - lfd f22,56+19*4+8*8(r1) - lfd f23,56+19*4+9*8(r1) - lfd f24,56+19*4+10*8(r1) - lfd f25,56+19*4+11*8(r1) - lfd f26,56+19*4+12*8(r1) - lfd f27,56+19*4+13*8(r1) - lfd f28,56+19*4+14*8(r1) - lfd f29,56+19*4+15*8(r1) - lfd f30,56+19*4+16*8(r1) - lfd f31,56+19*4+17*8(r1) - - // Exiting from 68k emulator - li r0,1 - stw r0,XLM_IRQ_NEST - li r0,MODE_NATIVE - stw r0,XLM_RUN_MODE - - // Return to caller of jump_to_rom() - lwz r0,56+19*4+18*8+8(r1) - mtlr r0 - lwz r0,56+19*4+18*8+4(r1) - mtcrf 0xff,r0 - addi r1,r1,56+19*4+18*8 - blr - - - // Save address of EMUL_RETURN routine for 68k emulator patch -@1 mflr r0 - stw r0,XLM_EMUL_RETURN_PROC - - // Skip over EXEC_RETURN routine and get its address - bl @2 - - - /* - * EXEC_RETURN: Returned from 68k routine executed with Execute68k() - */ - - // Save r25 (contains current 68k interrupt level) - stw r25,XLM_68K_R25 - - // Reentering EMUL_OP mode - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Save 68k registers - lwz r4,56+19*4+18*8+12(r1) - stw r8,M68kRegisters.d[0](r4) - stw r9,M68kRegisters.d[1](r4) - stw r10,M68kRegisters.d[2](r4) - stw r11,M68kRegisters.d[3](r4) - stw r12,M68kRegisters.d[4](r4) - stw r13,M68kRegisters.d[5](r4) - stw r14,M68kRegisters.d[6](r4) - stw r15,M68kRegisters.d[7](r4) - stw r16,M68kRegisters.a[0](r4) - stw r17,M68kRegisters.a[1](r4) - stw r18,M68kRegisters.a[2](r4) - stw r19,M68kRegisters.a[3](r4) - stw r20,M68kRegisters.a[4](r4) - stw r21,M68kRegisters.a[5](r4) - stw r22,M68kRegisters.a[6](r4) - - // Restore PowerPC registers - lmw r13,56(r1) -#if SAVE_FP_EXEC_68K - lfd f14,56+19*4+0*8(r1) - lfd f15,56+19*4+1*8(r1) - lfd f16,56+19*4+2*8(r1) - lfd f17,56+19*4+3*8(r1) - lfd f18,56+19*4+4*8(r1) - lfd f19,56+19*4+5*8(r1) - lfd f20,56+19*4+6*8(r1) - lfd f21,56+19*4+7*8(r1) - lfd f22,56+19*4+8*8(r1) - lfd f23,56+19*4+9*8(r1) - lfd f24,56+19*4+10*8(r1) - lfd f25,56+19*4+11*8(r1) - lfd f26,56+19*4+12*8(r1) - lfd f27,56+19*4+13*8(r1) - lfd f28,56+19*4+14*8(r1) - lfd f29,56+19*4+15*8(r1) - lfd f30,56+19*4+16*8(r1) - lfd f31,56+19*4+17*8(r1) -#endif - - // Return to caller - lwz r0,56+19*4+18*8+8(r1) - mtlr r0 - addi r1,r1,56+19*4+18*8 - blr - - - // Stave address of EXEC_RETURN routine for 68k emulator patch -@2 mflr r0 - stw r0,XLM_EXEC_RETURN_PROC - - // Skip over EMUL_BREAK/EMUL_OP routine and get its address - bl @3 - - - /* - * EMUL_BREAK/EMUL_OP: Execute native routine, selector in r5 (my own private mode switch) - * - * 68k registers are stored in a M68kRegisters struct on the stack - * which the native routine may read and modify - */ - - // Save r25 (contains current 68k interrupt level) - stw r25,XLM_68K_R25 - - // Entering EMUL_OP mode within 68k emulator - li r0,MODE_EMUL_OP - stw r0,XLM_RUN_MODE - - // Create PowerPC stack frame, reserve space for M68kRegisters - mr r3,r1 - subi r1,r1,56 // Fake "caller" frame - rlwinm r1,r1,0,0,29 // Align stack - - mfcr r0 - rlwinm r0,r0,0,11,8 - stw r0,4(r1) - mfxer r0 - stw r0,16(r1) - stw r2,12(r1) - stwu r1,-(56+16*4+15*8)(r1) - lwz r2,XLM_TOC - - // Save 68k registers - stw r8,56+M68kRegisters.d[0](r1) - stw r9,56+M68kRegisters.d[1](r1) - stw r10,56+M68kRegisters.d[2](r1) - stw r11,56+M68kRegisters.d[3](r1) - stw r12,56+M68kRegisters.d[4](r1) - stw r13,56+M68kRegisters.d[5](r1) - stw r14,56+M68kRegisters.d[6](r1) - stw r15,56+M68kRegisters.d[7](r1) - stw r16,56+M68kRegisters.a[0](r1) - stw r17,56+M68kRegisters.a[1](r1) - stw r18,56+M68kRegisters.a[2](r1) - stw r19,56+M68kRegisters.a[3](r1) - stw r20,56+M68kRegisters.a[4](r1) - stw r21,56+M68kRegisters.a[5](r1) - stw r22,56+M68kRegisters.a[6](r1) - stw r3,56+M68kRegisters.a[7](r1) - stfd f0,56+16*4+0*8(r1) - stfd f1,56+16*4+1*8(r1) - stfd f2,56+16*4+2*8(r1) - stfd f3,56+16*4+3*8(r1) - stfd f4,56+16*4+4*8(r1) - stfd f5,56+16*4+5*8(r1) - stfd f6,56+16*4+6*8(r1) - stfd f7,56+16*4+7*8(r1) - mffs f0 - stfd f8,56+16*4+8*8(r1) - stfd f9,56+16*4+9*8(r1) - stfd f10,56+16*4+10*8(r1) - stfd f11,56+16*4+11*8(r1) - stfd f12,56+16*4+12*8(r1) - stfd f13,56+16*4+13*8(r1) - stfd f0,56+16*4+14*8(r1) - - // Execute native routine - addi r3,r1,56 - mr r4,r24 - bl EmulOp - - // Restore 68k registers - lwz r8,56+M68kRegisters.d[0](r1) - lwz r9,56+M68kRegisters.d[1](r1) - lwz r10,56+M68kRegisters.d[2](r1) - lwz r11,56+M68kRegisters.d[3](r1) - lwz r12,56+M68kRegisters.d[4](r1) - lwz r13,56+M68kRegisters.d[5](r1) - lwz r14,56+M68kRegisters.d[6](r1) - lwz r15,56+M68kRegisters.d[7](r1) - lwz r16,56+M68kRegisters.a[0](r1) - lwz r17,56+M68kRegisters.a[1](r1) - lwz r18,56+M68kRegisters.a[2](r1) - lwz r19,56+M68kRegisters.a[3](r1) - lwz r20,56+M68kRegisters.a[4](r1) - lwz r21,56+M68kRegisters.a[5](r1) - lwz r22,56+M68kRegisters.a[6](r1) - lwz r3,56+M68kRegisters.a[7](r1) - lfd f13,56+16*4+14*8(r1) - lfd f0,56+16*4+0*8(r1) - lfd f1,56+16*4+1*8(r1) - lfd f2,56+16*4+2*8(r1) - lfd f3,56+16*4+3*8(r1) - lfd f4,56+16*4+4*8(r1) - lfd f5,56+16*4+5*8(r1) - lfd f6,56+16*4+6*8(r1) - lfd f7,56+16*4+7*8(r1) - mtfsf 0xff,f13 - lfd f8,56+16*4+8*8(r1) - lfd f9,56+16*4+9*8(r1) - lfd f10,56+16*4+10*8(r1) - lfd f11,56+16*4+11*8(r1) - lfd f12,56+16*4+12*8(r1) - lfd f13,56+16*4+13*8(r1) - - // Delete PowerPC stack frame - lwz r2,56+16*4+15*8+12(r1) - lwz r0,56+16*4+15*8+16(r1) - mtxer r0 - lwz r0,56+16*4+15*8+4(r1) - mtcrf 0xff,r0 - mr r1,r3 - - // Reeintering 68k emulator - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Set r0 to 0 for 68k emulator - li r0,0 - - // Execute next 68k opcode - rlwimi r29,r27,3,13,28 - lhau r27,2(r24) - mtlr r29 - blr - - - // Save address of EMUL_BREAK/EMUL_OP routine for 68k emulator patch -@3 mflr r0 - stw r0,XLM_EMUL_OP_PROC - - // Save stack pointer for EMUL_RETURN - stw r1,XLM_EMUL_RETURN_STACK - - // Preset registers for ROM boot routine - lis r3,0x40b0 // Pointer to ROM boot structure - ori r3,r3,0xd000 - - // 68k emulator is now active - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Jump to ROM - bctr -} -#endif - - -#if !EMULATED_PPC -/* - * Execute 68k subroutine (must be ended with RTS) - * This must only be called by the emul_thread when in EMUL_OP mode - * r->a[7] is unused, the routine runs on the caller's stack - */ - -#if SAFE_EXEC_68K -void execute_68k(uint32 pc, M68kRegisters *r); - -void Execute68k(uint32 pc, M68kRegisters *r) -{ - if (*(uint32 *)XLM_RUN_MODE != MODE_EMUL_OP) - printf("FATAL: Execute68k() not called from EMUL_OP mode\n"); - if (find_thread(NULL) != the_app->emul_thread) - printf("FATAL: Execute68k() not called from emul_thread\n"); - execute_68k(pc, r); -} - -asm void execute_68k(register uint32 pc, register M68kRegisters *r) -#else -asm void Execute68k(register uint32 pc, register M68kRegisters *r) -#endif -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stw r4,12(r1) - stwu r1,-(56+19*4+18*8)(r1) - - // Save PowerPC registers - stmw r13,56(r1) -#if SAVE_FP_EXEC_68K - stfd f14,56+19*4+0*8(r1) - stfd f15,56+19*4+1*8(r1) - stfd f16,56+19*4+2*8(r1) - stfd f17,56+19*4+3*8(r1) - stfd f18,56+19*4+4*8(r1) - stfd f19,56+19*4+5*8(r1) - stfd f20,56+19*4+6*8(r1) - stfd f21,56+19*4+7*8(r1) - stfd f22,56+19*4+8*8(r1) - stfd f23,56+19*4+9*8(r1) - stfd f24,56+19*4+10*8(r1) - stfd f25,56+19*4+11*8(r1) - stfd f26,56+19*4+12*8(r1) - stfd f27,56+19*4+13*8(r1) - stfd f28,56+19*4+14*8(r1) - stfd f29,56+19*4+15*8(r1) - stfd f30,56+19*4+16*8(r1) - stfd f31,56+19*4+17*8(r1) -#endif - - // Set up registers for 68k emulator - lwz r31,XLM_KERNEL_DATA // Pointer to Kernel Data - addi r31,r31,0x1000 - li r0,0 - mtcrf 0xff,r0 - creqv 11,11,11 // Supervisor mode - lwz r8,M68kRegisters.d[0](r4) - lwz r9,M68kRegisters.d[1](r4) - lwz r10,M68kRegisters.d[2](r4) - lwz r11,M68kRegisters.d[3](r4) - lwz r12,M68kRegisters.d[4](r4) - lwz r13,M68kRegisters.d[5](r4) - lwz r14,M68kRegisters.d[6](r4) - lwz r15,M68kRegisters.d[7](r4) - lwz r16,M68kRegisters.a[0](r4) - lwz r17,M68kRegisters.a[1](r4) - lwz r18,M68kRegisters.a[2](r4) - lwz r19,M68kRegisters.a[3](r4) - lwz r20,M68kRegisters.a[4](r4) - lwz r21,M68kRegisters.a[5](r4) - lwz r22,M68kRegisters.a[6](r4) - li r23,0 - mr r24,r3 - lwz r25,XLM_68K_R25 // MSB of SR - li r26,0 - li r28,0 // VBR - lwz r29,0x74(r31) // Pointer to opcode table - lwz r30,0x78(r31) // Address of emulator - - // Push return address (points to EXEC_RETURN opcode) on stack - li r0,XLM_EXEC_RETURN_OPCODE - stwu r0,-4(r1) - - // Reentering 68k emulator - li r0,MODE_68K - stw r0,XLM_RUN_MODE - - // Set r0 to 0 for 68k emulator - li r0,0 - - // Execute 68k opcode - lha r27,0(r24) - rlwimi r29,r27,3,13,28 - lhau r27,2(r24) - mtlr r29 - blr -} - - -/* - * Execute 68k A-Trap from EMUL_OP routine - * r->a[7] is unused, the routine runs on the caller's stack - */ - -void Execute68kTrap(uint16 trap, M68kRegisters *r) -{ - uint16 proc[2] = {trap, M68K_RTS}; - Execute68k((uint32)proc, r); -} - - -/* - * Quit emulator (must only be called from main thread) - */ - -asm void QuitEmulator(void) -{ - lwz r0,XLM_EMUL_RETURN_PROC - mtlr r0 - blr -} -#endif - - -/* - * Dump 68k registers - */ - -void Dump68kRegs(M68kRegisters *r) -{ - // Display 68k registers - for (int i=0; i<8; i++) { - printf("d%d: %08lx", i, r->d[i]); - if (i == 3 || i == 7) - printf("\n"); - else - printf(", "); - } - for (int i=0; i<8; i++) { - printf("a%d: %08lx", i, r->a[i]); - if (i == 3 || i == 7) - printf("\n"); - else - printf(", "); - } -} - - -/* - * Make code executable - */ - -void MakeExecutable(int dummy, uint32 start, uint32 length) -{ - if ((start >= ROMBase) && (start < (ROMBase + ROM_SIZE))) - return; - clear_caches((void *)start, length, B_INVALIDATE_ICACHE | B_FLUSH_DCACHE); -} - - -/* - * NVRAM watchdog thread (saves NVRAM every minute) - */ - -status_t SheepShaver::nvram_func(void *arg) -{ - SheepShaver *obj = (SheepShaver *)arg; - - while (obj->NVRAMThreadActive) { - snooze(60*1000000); - if (memcmp(obj->last_xpram, XPRAM, XPRAM_SIZE)) { - memcpy(obj->last_xpram, XPRAM, XPRAM_SIZE); - SaveXPRAM(); - } - } - return 0; -} - - -/* - * 60Hz thread (really 60.15Hz) - */ - -status_t SheepShaver::tick_func(void *arg) -{ - SheepShaver *obj = (SheepShaver *)arg; - int tick_counter = 0; - bigtime_t current = system_time(); - - while (obj->TickThreadActive) { - - // Wait - current += 16625; - snooze_until(current, B_SYSTEM_TIMEBASE); - - // Pseudo Mac 1Hz interrupt, update local time - if (++tick_counter > 60) { - tick_counter = 0; - WriteMacInt32(0x20c, TimerDateTime()); - } - - // 60Hz interrupt - if (ReadMacInt32(XLM_IRQ_NEST) == 0) { - SetInterruptFlag(INTFLAG_VIA); - TriggerInterrupt(); - } - } - return 0; -} - - -/* - * Trigger signal USR1 from another thread - */ - -void TriggerInterrupt(void) -{ - idle_resume(); -#if 0 - WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1); -#else - if (the_app->emul_thread > 0 && the_app->ReadyForSignals) - send_signal(the_app->emul_thread, SIGUSR1); -#endif -} - - -/* - * Mutexes - */ - -struct B2_mutex { - int dummy; //!! -}; - -B2_mutex *B2_create_mutex(void) -{ - return new B2_mutex; -} - -void B2_lock_mutex(B2_mutex *mutex) -{ -} - -void B2_unlock_mutex(B2_mutex *mutex) -{ -} - -void B2_delete_mutex(B2_mutex *mutex) -{ - delete mutex; -} - - -/* - * Set/clear interrupt flags (must be done atomically!) - */ - -volatile uint32 InterruptFlags = 0; - -void SetInterruptFlag(uint32 flag) -{ - atomic_or((int32 *)&InterruptFlags, flag); -} - -void ClearInterruptFlag(uint32 flag) -{ - atomic_and((int32 *)&InterruptFlags, ~flag); -} - - -/* - * Disable interrupts - */ - -void DisableInterrupt(void) -{ - atomic_add((int32 *)XLM_IRQ_NEST, 1); -} - - -/* - * Enable interrupts - */ - -void EnableInterrupt(void) -{ - atomic_add((int32 *)XLM_IRQ_NEST, -1); -} - - -/* - * USR1 handler - */ - -void SheepShaver::sigusr1_invoc(int sig, void *arg, vregs *r) -{ - ((SheepShaver *)arg)->sigusr1_handler(r); -} - -#if !EMULATED_PPC -static asm void ppc_interrupt(register uint32 entry) -{ - fralloc - - // Get address of return routine - bl @1 - - // Return routine - frfree - blr - -@1 - // Prepare registers for nanokernel interrupt routine - mtctr r1 - lwz r1,XLM_KERNEL_DATA - stw r6,0x018(r1) - mfctr r6 - stw r6,0x004(r1) - lwz r6,0x65c(r1) - stw r7,0x13c(r6) - stw r8,0x144(r6) - stw r9,0x14c(r6) - stw r10,0x154(r6) - stw r11,0x15c(r6) - stw r12,0x164(r6) - stw r13,0x16c(r6) - - mflr r10 - mfcr r13 - lwz r7,0x660(r1) - mflr r12 - rlwimi. r7,r7,8,0,0 - li r11,0 - ori r11,r11,0xf072 // MSR (SRR1) - mtcrf 0x70,r11 - li r8,0 - - // Enter nanokernel - mtlr r3 - blr -} -#endif - -void SheepShaver::sigusr1_handler(vregs *r) -{ - // Do nothing if interrupts are disabled - if ((*(int32 *)XLM_IRQ_NEST) > 0) - return; - - // Interrupt action depends on current run mode - switch (*(uint32 *)XLM_RUN_MODE) { - case MODE_68K: - // 68k emulator active, trigger 68k interrupt level 1 - *(uint16 *)(kernel_data->v[0x67c >> 2]) = 1; - r->cr |= kernel_data->v[0x674 >> 2]; - break; - -#if INTERRUPTS_IN_NATIVE_MODE - case MODE_NATIVE: - // 68k emulator inactive, in nanokernel? - if (r->r1 != KernelDataAddr) { - // No, prepare for 68k interrupt level 1 - *(uint16 *)(kernel_data->v[0x67c >> 2]) = 1; - *(uint32 *)(kernel_data->v[0x658 >> 2] + 0xdc) |= kernel_data->v[0x674 >> 2]; - - // Execute nanokernel interrupt routine (this will activate the 68k emulator) - atomic_add((int32 *)XLM_IRQ_NEST, 1); - if (ROMType == ROMTYPE_NEWWORLD) - ppc_interrupt(ROMBase + 0x312b1c); - else - ppc_interrupt(ROMBase + 0x312a3c); - } - break; -#endif - -#if INTERRUPTS_IN_EMUL_OP_MODE - case MODE_EMUL_OP: - // 68k emulator active, within EMUL_OP routine, execute 68k interrupt routine directly when interrupt level is 0 - if ((*(uint32 *)XLM_68K_R25 & 7) == 0) { - - // Set extra stack for SIGSEGV handler - set_signal_stack(extra_stack, SIG_STACK_SIZE); -#if 1 - // Execute full 68k interrupt routine - M68kRegisters r; - uint32 old_r25 = *(uint32 *)XLM_68K_R25; // Save interrupt level - *(uint32 *)XLM_68K_R25 = 0x21; // Execute with interrupt level 1 - static const uint16 proc[] = { - 0x3f3c, 0x0000, // move.w #$0000,-(sp) (fake format word) - 0x487a, 0x000a, // pea @1(pc) (return address) - 0x40e7, // move sr,-(sp) (saved SR) - 0x2078, 0x0064, // move.l $64,a0 - 0x4ed0, // jmp (a0) - M68K_RTS // @1 - }; - Execute68k((uint32)proc, &r); - *(uint32 *)XLM_68K_R25 = old_r25; // Restore interrupt level -#else - // Only update cursor - if (HasMacStarted()) { - if (InterruptFlags & INTFLAG_VIA) { - ClearInterruptFlag(INTFLAG_VIA); - ADBInterrupt(); - ExecuteNative(NATIVE_VIDEO_VBL); - } - } -#endif - // Reset normal signal stack - set_signal_stack(sig_stack, SIG_STACK_SIZE); - } - break; -#endif - } -} - - -/* - * SIGSEGV handler - */ - -static uint32 segv_r[32]; - -#if !EMULATED_PPC -asm void SheepShaver::sigsegv_invoc(register int sig, register void *arg, register vregs *r) -{ - mflr r0 - stw r0,8(r1) - stwu r1,-56(r1) - - lwz r3,segv_r(r2) - stmw r13,13*4(r3) - - mr r3,r5 - bl sigsegv_handler - - lwz r3,segv_r(r2) - lmw r13,13*4(r3) - - lwz r0,56+8(r1) - mtlr r0 - addi r1,r1,56 - blr -} -#endif - -static void sigsegv_handler(vregs *r) -{ - char str[256]; - - // Fetch volatile registers - segv_r[0] = r->r0; - segv_r[1] = r->r1; - segv_r[2] = r->r2; - segv_r[3] = r->r3; - segv_r[4] = r->r4; - segv_r[5] = r->r5; - segv_r[6] = r->r6; - segv_r[7] = r->r7; - segv_r[8] = r->r8; - segv_r[9] = r->r9; - segv_r[10] = r->r10; - segv_r[11] = r->r11; - segv_r[12] = r->r12; - - // Get opcode and divide into fields - uint32 opcode = *(uint32 *)r->pc; - uint32 primop = opcode >> 26; - uint32 exop = (opcode >> 1) & 0x3ff; - uint32 ra = (opcode >> 16) & 0x1f; - uint32 rb = (opcode >> 11) & 0x1f; - uint32 rd = (opcode >> 21) & 0x1f; - uint32 imm = opcode & 0xffff; - - // Fault in Mac ROM or RAM? - bool mac_fault = (r->pc >= ROMBase) && (r->pc < (ROMBase + ROM_AREA_SIZE)) || (r->pc >= RAMBase) && (r->pc < (RAMBase + RAMSize)); - if (mac_fault) { - - // "VM settings" during MacOS 8 installation - if (r->pc == ROMBase + 0x488160 && segv_r[20] == 0xf8000000) { - r->pc += 4; - segv_r[8] = 0; - goto rti; - - // MacOS 8.5 installation - } else if (r->pc == ROMBase + 0x488140 && segv_r[16] == 0xf8000000) { - r->pc += 4; - segv_r[8] = 0; - goto rti; - - // MacOS 8 serial drivers on startup - } else if (r->pc == ROMBase + 0x48e080 && (segv_r[8] == 0xf3012002 || segv_r[8] == 0xf3012000)) { - r->pc += 4; - segv_r[8] = 0; - goto rti; - - // MacOS 8.1 serial drivers on startup - } else if (r->pc == ROMBase + 0x48c5e0 && (segv_r[20] == 0xf3012002 || segv_r[20] == 0xf3012000)) { - r->pc += 4; - goto rti; - } else if (r->pc == ROMBase + 0x4a10a0 && (segv_r[20] == 0xf3012002 || segv_r[20] == 0xf3012000)) { - r->pc += 4; - goto rti; - } - } - - // Analyze opcode - enum { - TYPE_UNKNOWN, - TYPE_LOAD, - TYPE_STORE - } transfer_type = TYPE_UNKNOWN; - enum { - SIZE_UNKNOWN, - SIZE_BYTE, - SIZE_HALFWORD, - SIZE_WORD - } transfer_size = SIZE_UNKNOWN; - enum { - MODE_UNKNOWN, - MODE_NORM, - MODE_U, - MODE_X, - MODE_UX - } addr_mode = MODE_UNKNOWN; - switch (primop) { - case 31: - switch (exop) { - case 23: // lwzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 55: // lwzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 87: // lbzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 119: // lbzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 151: // stwx - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; - case 183: // stwux - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; - case 215: // stbx - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; - case 247: // stbux - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; - case 279: // lhzx - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 311: // lhzux - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - case 343: // lhax - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 375: // lhaux - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - case 407: // sthx - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_X; break; - case 439: // sthux - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; - } - break; - - case 32: // lwz - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 33: // lwzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 34: // lbz - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 35: // lbzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 36: // stw - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; - case 37: // stwu - transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; - case 38: // stb - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; - case 39: // stbu - transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; - case 40: // lhz - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 41: // lhzu - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - case 42: // lha - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 43: // lhau - transfer_type = TYPE_LOAD; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - case 44: // sth - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; - case 45: // sthu - transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; - } - - // Calculate effective address - uint32 addr = 0; - switch (addr_mode) { - case MODE_X: - case MODE_UX: - if (ra == 0) - addr = segv_r[rb]; - else - addr = segv_r[ra] + segv_r[rb]; - break; - case MODE_NORM: - case MODE_U: - if (ra == 0) - addr = (int32)(int16)imm; - else - addr = segv_r[ra] + (int32)(int16)imm; - break; - default: - break; - } - - // Ignore ROM writes - if (transfer_type == TYPE_STORE && addr >= ROMBase && addr < ROMBase + ROM_SIZE) { - D(bug("WARNING: %s write access to ROM at %p, pc %p\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc)); - if (addr_mode == MODE_U || addr_mode == MODE_UX) - segv_r[ra] = addr; - r->pc += 4; - goto rti; - } - - // Fault in Mac ROM or RAM? - if (mac_fault) { - - // Ignore illegal memory accesses? - if (PrefsFindBool("ignoresegv")) { - if (addr_mode == MODE_U || addr_mode == MODE_UX) - segv_r[ra] = addr; - if (transfer_type == TYPE_LOAD) - segv_r[rd] = 0; - r->pc += 4; - goto rti; - } - - // In GUI mode, show error alert - if (!PrefsFindBool("nogui")) { - if (transfer_type == TYPE_LOAD || transfer_type == TYPE_STORE) - sprintf(str, GetString(STR_MEM_ACCESS_ERR), transfer_size == SIZE_BYTE ? "byte" : transfer_size == SIZE_HALFWORD ? "halfword" : "word", transfer_type == TYPE_LOAD ? GetString(STR_MEM_ACCESS_READ) : GetString(STR_MEM_ACCESS_WRITE), addr, r->pc, segv_r[24], segv_r[1]); - else - sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->pc, segv_r[24], segv_r[1], opcode); - ErrorAlert(str); - QuitEmulator(); - return; - } - } - - // For all other errors, jump into debugger - sprintf(str, "SIGSEGV\n" - " pc %08lx lr %08lx ctr %08lx msr %08lx\n" - " xer %08lx cr %08lx fpscr %08lx\n" - " r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n" - " r4 %08lx r5 %08lx r6 %08lx r7 %08lx\n" - " r8 %08lx r9 %08lx r10 %08lx r11 %08lx\n" - " r12 %08lx r13 %08lx r14 %08lx r15 %08lx\n" - " r16 %08lx r17 %08lx r18 %08lx r19 %08lx\n" - " r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" - " r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" - " r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", - r->pc, r->lr, r->ctr, r->msr, - r->xer, r->cr, r->fpscr, - r->r0, r->r1, r->r2, r->r3, - r->r4, r->r5, r->r6, r->r7, - r->r8, r->r9, r->r10, r->r11, - r->r12, segv_r[13], segv_r[14], segv_r[15], - segv_r[16], segv_r[17], segv_r[18], segv_r[19], - segv_r[20], segv_r[21], segv_r[22], segv_r[23], - segv_r[24], segv_r[25], segv_r[26], segv_r[27], - segv_r[28], segv_r[29], segv_r[30], segv_r[31]); - VideoQuitFullScreen(); - disable_debugger(false); - debugger(str); - exit(1); - return; - -rti: - // Restore volatile registers - r->r0 = segv_r[0]; - r->r1 = segv_r[1]; - r->r2 = segv_r[2]; - r->r3 = segv_r[3]; - r->r4 = segv_r[4]; - r->r5 = segv_r[5]; - r->r6 = segv_r[6]; - r->r7 = segv_r[7]; - r->r8 = segv_r[8]; - r->r9 = segv_r[9]; - r->r10 = segv_r[10]; - r->r11 = segv_r[11]; - r->r12 = segv_r[12]; -} - - -/* - * SIGILL handler - */ - -#if !EMULATED_PPC -asm void SheepShaver::sigill_invoc(register int sig, register void *arg, register vregs *r) -{ - mflr r0 - stw r0,8(r1) - stwu r1,-56(r1) - - lwz r3,segv_r(r2) - stmw r13,13*4(r3) - - mr r3,r5 - bl sigill_handler - - lwz r3,segv_r(r2) - lmw r13,13*4(r3) - - lwz r0,56+8(r1) - mtlr r0 - addi r1,r1,56 - blr -} -#endif - -static void sigill_handler(vregs *r) -{ - char str[256]; - - // Fetch volatile registers - segv_r[0] = r->r0; - segv_r[1] = r->r1; - segv_r[2] = r->r2; - segv_r[3] = r->r3; - segv_r[4] = r->r4; - segv_r[5] = r->r5; - segv_r[6] = r->r6; - segv_r[7] = r->r7; - segv_r[8] = r->r8; - segv_r[9] = r->r9; - segv_r[10] = r->r10; - segv_r[11] = r->r11; - segv_r[12] = r->r12; - - // Get opcode and divide into fields - uint32 opcode = *(uint32 *)r->pc; - uint32 primop = opcode >> 26; - uint32 exop = (opcode >> 1) & 0x3ff; - uint32 ra = (opcode >> 16) & 0x1f; - uint32 rb = (opcode >> 11) & 0x1f; - uint32 rd = (opcode >> 21) & 0x1f; - uint32 imm = opcode & 0xffff; - - // Fault in Mac ROM or RAM? - bool mac_fault = (r->pc >= ROMBase) && (r->pc < (ROMBase + ROM_AREA_SIZE)) || (r->pc >= RAMBase) && (r->pc < (RAMBase + RAMSize)); - if (mac_fault) { - - switch (primop) { - case 9: // POWER instructions - case 22: -power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->pc, segv_r[1], opcode); - ErrorAlert(str); - QuitEmulator(); - return; - - case 31: - switch (exop) { - case 83: // mfmsr - segv_r[rd] = 0xf072; - r->pc += 4; - goto rti; - - case 210: // mtsr - case 242: // mtsrin - case 306: // tlbie - r->pc += 4; - goto rti; - - case 339: { // mfspr - int spr = ra | (rb << 5); - switch (spr) { - case 0: // MQ - case 22: // DEC - case 952: // MMCR0 - case 953: // PMC1 - case 954: // PMC2 - case 955: // SIA - case 956: // MMCR1 - case 957: // PMC3 - case 958: // PMC4 - case 959: // SDA - r->pc += 4; - goto rti; - case 25: // SDR1 - segv_r[rd] = 0xdead001f; - r->pc += 4; - goto rti; - case 287: // PVR - segv_r[rd] = PVR; - r->pc += 4; - goto rti; - } - break; - } - - case 467: { // mtspr - int spr = ra | (rb << 5); - switch (spr) { - case 0: // MQ - case 22: // DEC - case 275: // SPRG3 - case 528: // IBAT0U - case 529: // IBAT0L - case 530: // IBAT1U - case 531: // IBAT1L - case 532: // IBAT2U - case 533: // IBAT2L - case 534: // IBAT3U - case 535: // IBAT3L - case 536: // DBAT0U - case 537: // DBAT0L - case 538: // DBAT1U - case 539: // DBAT1L - case 540: // DBAT2U - case 541: // DBAT2L - case 542: // DBAT3U - case 543: // DBAT3L - case 952: // MMCR0 - case 953: // PMC1 - case 954: // PMC2 - case 955: // SIA - case 956: // MMCR1 - case 957: // PMC3 - case 958: // PMC4 - case 959: // SDA - r->pc += 4; - goto rti; - } - break; - } - - case 29: case 107: case 152: case 153: // POWER instructions - case 184: case 216: case 217: case 248: - case 264: case 277: case 331: case 360: - case 363: case 488: case 531: case 537: - case 541: case 664: case 665: case 696: - case 728: case 729: case 760: case 920: - case 921: case 952: - goto power_inst; - } - } - - // In GUI mode, show error alert - if (!PrefsFindBool("nogui")) { - sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->pc, segv_r[24], segv_r[1], opcode); - ErrorAlert(str); - QuitEmulator(); - return; - } - } - - // For all other errors, jump into debugger - sprintf(str, "SIGILL\n" - " pc %08lx lr %08lx ctr %08lx msr %08lx\n" - " xer %08lx cr %08lx fpscr %08lx\n" - " r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n" - " r4 %08lx r5 %08lx r6 %08lx r7 %08lx\n" - " r8 %08lx r9 %08lx r10 %08lx r11 %08lx\n" - " r12 %08lx r13 %08lx r14 %08lx r15 %08lx\n" - " r16 %08lx r17 %08lx r18 %08lx r19 %08lx\n" - " r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" - " r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" - " r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", - r->pc, r->lr, r->ctr, r->msr, - r->xer, r->cr, r->fpscr, - r->r0, r->r1, r->r2, r->r3, - r->r4, r->r5, r->r6, r->r7, - r->r8, r->r9, r->r10, r->r11, - r->r12, segv_r[13], segv_r[14], segv_r[15], - segv_r[16], segv_r[17], segv_r[18], segv_r[19], - segv_r[20], segv_r[21], segv_r[22], segv_r[23], - segv_r[24], segv_r[25], segv_r[26], segv_r[27], - segv_r[28], segv_r[29], segv_r[30], segv_r[31]); - VideoQuitFullScreen(); - disable_debugger(false); - debugger(str); - exit(1); - return; - -rti: - // Restore volatile registers - r->r0 = segv_r[0]; - r->r1 = segv_r[1]; - r->r2 = segv_r[2]; - r->r3 = segv_r[3]; - r->r4 = segv_r[4]; - r->r5 = segv_r[5]; - r->r6 = segv_r[6]; - r->r7 = segv_r[7]; - r->r8 = segv_r[8]; - r->r9 = segv_r[9]; - r->r10 = segv_r[10]; - r->r11 = segv_r[11]; - r->r12 = segv_r[12]; -} - - -/* - * Helpers to share 32-bit addressable data with MacOS - */ - -bool SheepMem::Init(void) -{ - // Delete old area - area_id old_sheep_area = find_area(SHEEP_AREA_NAME); - if (old_sheep_area > 0) - delete_area(old_sheep_area); - - // Create area for SheepShaver data - proc = base = 0x60000000; - SheepMemArea = create_area(SHEEP_AREA_NAME, (void **)&base, B_BASE_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (SheepMemArea < 0) - return false; - - // Create read-only area with all bits set to 0 - static const uint8 const_zero_page[4096] = {0,}; - zero_page = const_zero_page; - - D(bug("SheepShaver area %ld at %p\n", SheepMemArea, base)); - data = base + size; - return true; -} - -void SheepMem::Exit(void) -{ - if (SheepMemArea >= 0) - delete_area(SheepMemArea); -} - - -/* - * Display error alert - */ - -void ErrorAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_ERROR_PREFIX), text); - return; - } - char str[256]; - sprintf(str, GetString(STR_GUI_ERROR_PREFIX), text); - VideoQuitFullScreen(); - BAlert *alert = new BAlert(GetString(STR_ERROR_ALERT_TITLE), str, GetString(STR_QUIT_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); - alert->Go(); -} - - -/* - * Display warning alert - */ - -void WarningAlert(const char *text) -{ - if (PrefsFindBool("nogui")) { - printf(GetString(STR_SHELL_WARNING_PREFIX), text); - return; - } - char str[256]; - sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, GetString(STR_OK_BUTTON), NULL, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - alert->Go(); -} - - -/* - * Display choice alert - */ - -bool ChoiceAlert(const char *text, const char *pos, const char *neg) -{ - char str[256]; - sprintf(str, GetString(STR_GUI_WARNING_PREFIX), text); - BAlert *alert = new BAlert(GetString(STR_WARNING_ALERT_TITLE), str, pos, neg, NULL, B_WIDTH_AS_USUAL, B_INFO_ALERT); - return alert->Go() == 0; -} diff --git a/SheepShaver/src/BeOS/prefs_beos.cpp b/SheepShaver/src/BeOS/prefs_beos.cpp deleted file mode 100644 index cad4a8882..000000000 --- a/SheepShaver/src/BeOS/prefs_beos.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * prefs_beos.cpp - Preferences handling, BeOS specific things - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "sysdeps.h" -#include "prefs.h" -#include "main.h" - - -// Platform-specific preferences items -prefs_desc platform_prefs_items[] = { - {"bitbang", TYPE_BOOLEAN, false, "draw Mac desktop directly on screen in window mode"}, - {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, - {NULL, TYPE_END, false, NULL} // End of list -}; - - -// Preferences file name and path -const char PREFS_FILE_NAME[] = "SheepShaver_prefs"; -static BPath prefs_path; - -// Modification date of prefs file -time_t PrefsFileDate = 0; - - -/* - * Load preferences from settings file - */ - -void LoadPrefs(const char *vmdir) -{ - // Construct prefs path - find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true); - prefs_path.Append(PREFS_FILE_NAME); - - // Read preferences from settings file - FILE *f = fopen(prefs_path.Path(), "r"); - if (f == NULL) // Not found in settings directory, look in app directory - f = fopen(PREFS_FILE_NAME, "r"); - if (f != NULL) { - LoadPrefsFromStream(f); - - struct stat s; - fstat(fileno(f), &s); - PrefsFileDate = s.st_ctime; - fclose(f); - - } else { - - // No prefs file, save defaults - SavePrefs(); - PrefsFileDate = real_time_clock(); - } -} - - -/* - * Save preferences to settings file - */ - -void SavePrefs(void) -{ - FILE *f; - if ((f = fopen(prefs_path.Path(), "w")) != NULL) { - SavePrefsToStream(f); - fclose(f); - } -} - - -/* - * Add defaults of platform-specific prefs items - * You may also override the defaults set in PrefsInit() - */ - -void AddPlatformPrefsDefaults(void) -{ - PrefsReplaceString("extfs", "/boot"); - PrefsAddInt32("windowmodes", - B_8_BIT_640x480 | B_15_BIT_640x480 | B_32_BIT_640x480 | - B_8_BIT_800x600 | B_15_BIT_800x600 | B_32_BIT_800x600 - ); - PrefsAddInt32("screenmodes", - B_8_BIT_640x480 | B_15_BIT_640x480 | B_32_BIT_640x480 | - B_8_BIT_800x600 | B_15_BIT_800x600 | B_32_BIT_800x600 | - B_8_BIT_1024x768 | B_15_BIT_1024x768 - ); - PrefsAddBool("bitbang", false); - PrefsAddBool("idlewait", true); -} diff --git a/SheepShaver/src/BeOS/prefs_editor_beos.cpp b/SheepShaver/src/BeOS/prefs_editor_beos.cpp deleted file mode 100644 index 847700c22..000000000 --- a/SheepShaver/src/BeOS/prefs_editor_beos.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/* - * prefs_editor_beos.cpp - Preferences editor, BeOS implementation - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include "prefs_editor.h" -#include "prefs.h" -#include "main.h" -#include "cdrom.h" -#include "xpram.h" -#include "about_window.h" -#include "user_strings.h" - - -// Special colors -const rgb_color fill_color = {216, 216, 216, 0}; -const rgb_color slider_fill_color = {102, 152, 255, 0}; - - -// Window messages -const uint32 MSG_OK = 'okok'; // "Start" clicked -const uint32 MSG_CANCEL = 'cncl'; // "Quit" clicked -const uint32 MSG_ZAP_PRAM = 'zprm'; - -const int NUM_PANES = 4; - -const uint32 MSG_VOLUME_SELECTED = 'volu'; // "Volumes" pane -const uint32 MSG_VOLUME_INVOKED = 'voli'; -const uint32 MSG_ADD_VOLUME = 'addv'; -const uint32 MSG_CREATE_VOLUME = 'crev'; -const uint32 MSG_REMOVE_VOLUME = 'remv'; -const uint32 MSG_ADD_VOLUME_PANEL = 'advp'; -const uint32 MSG_CREATE_VOLUME_PANEL = 'crvp'; -const uint32 MSG_DEVICE_NAME = 'devn'; -const uint32 MSG_BOOT_ANY = 'bany'; -const uint32 MSG_BOOT_CDROM = 'bcdr'; -const uint32 MSG_NOCDROM = 'nocd'; - -const uint32 MSG_REF_5HZ = ' 5Hz'; // "Graphics" pane -const uint32 MSG_REF_7_5HZ = ' 7Hz'; -const uint32 MSG_REF_10HZ = '10Hz'; -const uint32 MSG_REF_15HZ = '15Hz'; -const uint32 MSG_REF_30HZ = '30Hz'; -const uint32 MSG_GFXACCEL = 'gfac'; -const uint32 MSG_WINDOW_MODE = 'wmod'; -const uint32 MSG_SCREEN_MODE = 'smod'; -const uint32 MSG_NOSOUND = 'nosn'; - -const uint32 MSG_SER_A = 'sera'; // "Serial"/"Network" pane -const uint32 MSG_SER_B = 'serb'; -const uint32 MSG_NONET = 'noet'; - -const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory" pane -const uint32 MSG_IGNORESEGV = 'isgv'; -const uint32 MSG_IDLEWAIT = 'idlw'; - - -// RAM size slider class -class RAMSlider : public BSlider { -public: - RAMSlider(BRect frame, const char *name, const char *label, BMessage *message, - int32 minValue, int32 maxValue, thumb_style thumbType = B_BLOCK_THUMB, - uint32 resizingMode = B_FOLLOW_LEFT | - B_FOLLOW_TOP, - uint32 flags = B_NAVIGABLE | B_WILL_DRAW | - B_FRAME_EVENTS) : BSlider(frame, name, label, message, minValue, maxValue, thumbType, resizingMode, flags) - { - update_text = (char *)malloc(256); - } - - virtual ~RAMSlider() - { - if (update_text) - free(update_text); - } - - virtual char *UpdateText(void) const - { - if (update_text) { - sprintf(update_text, GetString(STR_RAMSIZE_FMT), Value()); - } - return update_text; - } - -private: - char *update_text; -}; - - -// Volumes list view class -class VolumeListView : public BListView { -public: - VolumeListView(BRect frame, const char *name, list_view_type type = B_SINGLE_SELECTION_LIST, uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE) - : BListView(frame, name, type, resizeMask, flags) - {} - - // Handle dropped files and volumes - virtual void MessageReceived(BMessage *msg) - { - if (msg->what == B_SIMPLE_DATA) { - BMessage msg2(MSG_ADD_VOLUME_PANEL); - entry_ref ref; - for (int i=0; msg->FindRef("refs", i, &ref) == B_NO_ERROR; i++) - msg2.AddRef("refs", &ref); - Window()->PostMessage(&msg2); - } else - BListView::MessageReceived(msg); - } -}; - - -// Number-entry BTextControl -class NumberControl : public BTextControl { -public: - NumberControl(BRect frame, float divider, const char *name, const char *label, long value, BMessage *message) - : BTextControl(frame, name, label, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) - { - SetDivider(divider); - for (int c=0; c<256; c++) - if (!isdigit(c) && c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW) - ((BTextView *)ChildAt(0))->DisallowChar(c); - SetValue(value); - } - - // Set integer value - void SetValue(long value) - { - char str[32]; - sprintf(str, "%ld", value); - SetText(str); - } - - // Get integer value - long Value(void) - { - return atol(Text()); - } -}; - - -// Path-entry BTextControl -class PathControl : public BTextControl { -public: - PathControl(bool dir_ctrl_, BRect frame, const char *name, const char *label, const char *text, BMessage *message) : BTextControl(frame, name, label, text, message), dir_ctrl(dir_ctrl_) - { - for (int c=0; c<' '; c++) - if (c != B_BACKSPACE && c != B_LEFT_ARROW && c != B_RIGHT_ARROW) - ((BTextView *)ChildAt(0))->DisallowChar(c); - } - - virtual void MessageReceived(BMessage *msg) - { - if (msg->what == B_SIMPLE_DATA) { - entry_ref the_ref; - BEntry the_entry; - - // Look for dropped refs - if (msg->FindRef("refs", &the_ref) == B_NO_ERROR) { - if (the_entry.SetTo(&the_ref) == B_NO_ERROR && (dir_ctrl&& the_entry.IsDirectory() || !dir_ctrl && the_entry.IsFile())) { - BPath the_path; - the_entry.GetPath(&the_path); - SetText(the_path.Path()); - } - } else - BTextControl::MessageReceived(msg); - - MakeFocus(); - } else - BTextControl::MessageReceived(msg); - } - -private: - bool dir_ctrl; -}; - - -// Preferences window class -class PrefsWindow : public BWindow { -public: - PrefsWindow(uint32 msg); - virtual ~PrefsWindow(); - virtual void MessageReceived(BMessage *msg); - -private: - BView *create_volumes_pane(void); - BView *create_graphics_pane(void); - BView *create_serial_pane(void); - BView *create_memory_pane(void); - - uint32 ok_message; - bool send_quit_on_close; - - BMessenger this_messenger; - BView *top; - BRect top_frame; - BTabView *pane_tabs; - BView *panes[NUM_PANES]; - int current_pane; - - VolumeListView *volume_list; - BCheckBox *nocdrom_checkbox; - BCheckBox *gfxaccel_checkbox; - BCheckBox *nosound_checkbox; - BCheckBox *nonet_checkbox; - BCheckBox *ignoresegv_checkbox; - BCheckBox *idlewait_checkbox; - RAMSlider *ramsize_slider; - PathControl *extfs_control; - PathControl *rom_control; - - BFilePanel *add_volume_panel; - BFilePanel *create_volume_panel; - - uint32 max_ramsize; // In MB -}; - - -/* - * Show preferences editor - * When the user clicks on "OK", the message given as parameter is sent - * to the application; if he clicks on "Quit", B_QUIT_REQUESTED is sent - */ - -void PrefsEditor(uint32 msg) -{ - new PrefsWindow(msg); -} - - -/* - * Preferences window constructor - */ - -PrefsWindow::PrefsWindow(uint32 msg) : BWindow(BRect(0, 0, 400, 289), GetString(STR_PREFS_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS), this_messenger(this) -{ - int i; - ok_message = msg; - send_quit_on_close = true; - - // Move window to right position - Lock(); - MoveTo(80, 80); - - // Set up menus - BMenuBar *bar = new BMenuBar(Bounds(), "menu"); - BMenu *menu = new BMenu(GetString(STR_PREFS_MENU)); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ABOUT), new BMessage(B_ABOUT_REQUESTED))); - menu->AddItem(new BSeparatorItem); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_START), new BMessage(MSG_OK))); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_ZAP_PRAM), new BMessage(MSG_ZAP_PRAM))); - menu->AddItem(new BSeparatorItem); - menu->AddItem(new BMenuItem(GetString(STR_PREFS_ITEM_QUIT), new BMessage(MSG_CANCEL), 'Q')); - bar->AddItem(menu); - AddChild(bar); - SetKeyMenuBar(bar); - int mbar_height = bar->Bounds().bottom + 1; - - // Resize window to fit menu bar - ResizeBy(0, mbar_height); - - // Light gray background - BRect b = Bounds(); - top = new BView(BRect(0, mbar_height, b.right, b.bottom), "top", B_FOLLOW_NONE, B_WILL_DRAW); - AddChild(top); - top->SetViewColor(fill_color); - top_frame = top->Bounds(); - - // Create panes - panes[0] = create_volumes_pane(); - panes[1] = create_graphics_pane(); - panes[2] = create_serial_pane(); - panes[3] = create_memory_pane(); - - // Prefs item tab view - pane_tabs = new BTabView(BRect(10, 10, top_frame.right-10, top_frame.bottom-50), "items", B_WIDTH_FROM_LABEL); - for (i=0; iAddTab(panes[i]); - top->AddChild(pane_tabs); - - volume_list->Select(0); - - // Create volume file panels - add_volume_panel = new BFilePanel(B_OPEN_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_ADD_VOLUME_PANEL)); - add_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_ADD_VOLUME_PANEL_BUTTON)); - add_volume_panel->Window()->SetTitle(GetString(STR_ADD_VOLUME_TITLE)); - create_volume_panel = new BFilePanel(B_SAVE_PANEL, &this_messenger, NULL, B_FILE_NODE | B_DIRECTORY_NODE, false, new BMessage(MSG_CREATE_VOLUME_PANEL)); - create_volume_panel->SetButtonLabel(B_DEFAULT_BUTTON, GetString(STR_CREATE_VOLUME_PANEL_BUTTON)); - create_volume_panel->Window()->SetTitle(GetString(STR_CREATE_VOLUME_TITLE)); - - create_volume_panel->Window()->Lock(); - BView *background = create_volume_panel->Window()->ChildAt(0); - background->FindView("PoseView")->ResizeBy(0, -30); - background->FindView("VScrollBar")->ResizeBy(0, -30); - background->FindView("CountVw")->MoveBy(0, -30); - BView *v = background->FindView("HScrollBar"); - if (v) - v->MoveBy(0, -30); - else { - i = 0; - while ((v = background->ChildAt(i++)) != NULL) { - if (v->Name() == NULL || v->Name()[0] == 0) { - v->MoveBy(0, -30); // unnamed horizontal scroll bar - break; - } - } - } - BView *filename = background->FindView("text view"); - BRect fnr(filename->Frame()); - fnr.OffsetBy(0, -30); - NumberControl *nc = new NumberControl(fnr, 80, "hardfile_size", GetString(STR_HARDFILE_SIZE_CTRL), 40, NULL); - background->AddChild(nc); - create_volume_panel->Window()->Unlock(); - - // "Start" button - BButton *button = new BButton(BRect(20, top_frame.bottom-35, 90, top_frame.bottom-10), "start", GetString(STR_START_BUTTON), new BMessage(MSG_OK)); - top->AddChild(button); - SetDefaultButton(button); - - // "Quit" button - top->AddChild(new BButton(BRect(top_frame.right-90, top_frame.bottom-35, top_frame.right-20, top_frame.bottom-10), "cancel", GetString(STR_QUIT_BUTTON), new BMessage(MSG_CANCEL))); - - Unlock(); - Show(); -} - - -/* - * Preferences window destructor - */ - -PrefsWindow::~PrefsWindow() -{ - delete add_volume_panel; - if (send_quit_on_close) - be_app->PostMessage(B_QUIT_REQUESTED); -} - - -/* - * Create "Volumes" pane - */ - -BView *PrefsWindow::create_volumes_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - const char *str; - int32 index = 0; - volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 108), "volumes"); - while ((str = PrefsFindString("disk", index++)) != NULL) - volume_list->AddItem(new BStringItem(str)); - volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED)); - volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED)); - pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true)); - - pane->AddChild(new BButton(BRect(10, 113, pane->Bounds().right/3, 133), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME))); - pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 113, pane->Bounds().right*2/3, 133), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME))); - pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 113, pane->Bounds().right-11, 133), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME))); - - extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL); - extfs_control->SetDivider(90); - pane->AddChild(extfs_control); - - BMenuField *menu_field; - BPopUpMenu *menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu); - menu_field->SetDivider(90); - menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY))); - menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM))); - pane->AddChild(menu_field); - int16 i16 = PrefsFindInt32("bootdriver"); - BMenuItem *item; - if (i16 == 0) { - if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL) - item->SetMarked(true); - } else if (i16 == CDROMRefNum) { - if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL) - item->SetMarked(true); - } - - nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM)); - pane->AddChild(nocdrom_checkbox); - nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF); - - return pane; -} - - -/* - * Create "Graphics/Sound" pane - */ - -struct video_mode_box { - uint32 mode; - int mode_string_id, bit_string_id; - float left, top; - BCheckBox *box; -}; - -const int NUM_WINDOW_MODES = 6; -const int NUM_SCREEN_MODES = 18; - -static video_mode_box window_mode_boxes[NUM_SCREEN_MODES] = { - {B_8_BIT_640x480, STR_W_640x480_CTRL, STR_8_BIT_CTRL, 140, 48, NULL}, - {B_15_BIT_640x480, STR_W_640x480_CTRL, STR_16_BIT_CTRL, 220, 48, NULL}, - {B_32_BIT_640x480, STR_W_640x480_CTRL, STR_32_BIT_CTRL, 300, 48, NULL}, - {B_8_BIT_800x600, STR_W_800x600_CTRL, STR_8_BIT_CTRL, 140, 65, NULL}, - {B_15_BIT_800x600, STR_W_800x600_CTRL, STR_16_BIT_CTRL, 220, 65, NULL}, - {B_32_BIT_800x600, STR_W_800x600_CTRL, STR_32_BIT_CTRL, 300, 65, NULL}, -}; - -static video_mode_box screen_mode_boxes[NUM_SCREEN_MODES] = { - {B_8_BIT_640x480, STR_640x480_CTRL, STR_8_BIT_CTRL, 140, 82, NULL}, - {B_15_BIT_640x480, STR_640x480_CTRL, STR_16_BIT_CTRL, 220, 82, NULL}, - {B_32_BIT_640x480, STR_640x480_CTRL, STR_32_BIT_CTRL, 300, 82, NULL}, - {B_8_BIT_800x600, STR_800x600_CTRL, STR_8_BIT_CTRL, 140, 99, NULL}, - {B_15_BIT_800x600, STR_800x600_CTRL, STR_16_BIT_CTRL, 220, 99, NULL}, - {B_32_BIT_800x600, STR_800x600_CTRL, STR_32_BIT_CTRL, 300, 99, NULL}, - {B_8_BIT_1024x768, STR_1024x768_CTRL, STR_8_BIT_CTRL, 140, 116, NULL}, - {B_15_BIT_1024x768, STR_1024x768_CTRL, STR_16_BIT_CTRL, 220, 116, NULL}, - {B_32_BIT_1024x768, STR_1024x768_CTRL, STR_32_BIT_CTRL, 300, 116, NULL}, - {B_8_BIT_1152x900, STR_1152x900_CTRL, STR_8_BIT_CTRL, 140, 133, NULL}, - {B_15_BIT_1152x900, STR_1152x900_CTRL, STR_16_BIT_CTRL, 220, 133, NULL}, - {B_32_BIT_1152x900, STR_1152x900_CTRL, STR_32_BIT_CTRL, 300, 133, NULL}, - {B_8_BIT_1280x1024, STR_1280x1024_CTRL, STR_8_BIT_CTRL, 140, 150, NULL}, - {B_15_BIT_1280x1024, STR_1280x1024_CTRL, STR_16_BIT_CTRL, 220, 150, NULL}, - {B_32_BIT_1280x1024, STR_1280x1024_CTRL, STR_32_BIT_CTRL, 300, 150, NULL}, - {B_8_BIT_1600x1200, STR_1600x1200_CTRL, STR_8_BIT_CTRL, 140, 167, NULL}, - {B_15_BIT_1600x1200, STR_1600x1200_CTRL, STR_16_BIT_CTRL, 220, 167, NULL}, - {B_32_BIT_1600x1200, STR_1600x1200_CTRL, STR_32_BIT_CTRL, 300, 167, NULL} -}; - -BView *PrefsWindow::create_graphics_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BMenuField *menu_field; - BPopUpMenu *menu = new BPopUpMenu(""); - menu_field = new BMenuField(BRect(10, 5, right, 20), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu); - menu_field->SetDivider(120); - menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); - menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); - pane->AddChild(menu_field); - int32 i32 = PrefsFindInt32("frameskip"); - BMenuItem *item; - if (i32 == 12) { - if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 8) { - if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 6) { - if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 4) { - if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (i32 == 2) { - if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) - item->SetMarked(true); - } - - gfxaccel_checkbox = new BCheckBox(BRect(10, 25, right, 40), "gfxaccel", GetString(STR_GFXACCEL_CTRL), new BMessage(MSG_GFXACCEL)); - pane->AddChild(gfxaccel_checkbox); - gfxaccel_checkbox->SetValue(PrefsFindBool("gfxaccel") ? B_CONTROL_ON : B_CONTROL_OFF); - - uint32 window_modes = PrefsFindInt32("windowmodes"); - for (int i=0; ibit_string_id == STR_8_BIT_CTRL) { - BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id)); - pane->AddChild(text); - } - p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_WINDOW_MODE)); - pane->AddChild(p->box); - p->box->SetValue(window_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF); - } - uint32 screen_modes = PrefsFindInt32("screenmodes"); - for (int i=0; ibit_string_id == STR_8_BIT_CTRL) { - BStringView *text = new BStringView(BRect(10, p->top, 120, p->top + 15), "", GetString(p->mode_string_id)); - pane->AddChild(text); - } - p->box = new BCheckBox(BRect(p->left, p->top, p->left + 80, p->top + 15), "", GetString(p->bit_string_id), new BMessage(MSG_SCREEN_MODE)); - pane->AddChild(p->box); - p->box->SetValue(screen_modes & p->mode ? B_CONTROL_ON : B_CONTROL_OFF); - } - - nosound_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND)); - pane->AddChild(nosound_checkbox); - nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF); - - return pane; -} - - -/* - * Create "Serial/Network" pane - */ - -static void add_serial_names(BPopUpMenu *menu, uint32 msg) -{ - BSerialPort *port = new BSerialPort; - char name[B_PATH_NAME_LENGTH]; - for (int i=0; iCountDevices(); i++) { - port->GetDeviceName(i, name); - menu->AddItem(new BMenuItem(name, new BMessage(msg))); - } - if (SysInfo.platform_type == B_BEBOX_PLATFORM) { - BDirectory dir; - BEntry entry; - dir.SetTo("/dev/parallel"); - if (dir.InitCheck() == B_NO_ERROR) { - dir.Rewind(); - while (dir.GetNextEntry(&entry) >= 0) { - if (!entry.IsDirectory()) { - entry.GetName(name); - menu->AddItem(new BMenuItem(name, new BMessage(msg))); - } - } - } - } - delete port; -} - -static void set_serial_label(BPopUpMenu *menu, const char *prefs_name) -{ - const char *str; - BMenuItem *item; - if ((str = PrefsFindString(prefs_name)) != NULL) - if ((item = menu->FindItem(str)) != NULL) - item->SetMarked(true); -} - -BView *PrefsWindow::create_serial_pane(void) -{ - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BMenuField *menu_field; - BPopUpMenu *menu_a = new BPopUpMenu(""); - add_serial_names(menu_a, MSG_SER_A); - menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERPORTA_CTRL), menu_a); - menu_field->SetDivider(90); - pane->AddChild(menu_field); - set_serial_label(menu_a, "seriala"); - - BPopUpMenu *menu_b = new BPopUpMenu(""); - add_serial_names(menu_b, MSG_SER_B); - menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERPORTB_CTRL), menu_b); - menu_field->SetDivider(90); - pane->AddChild(menu_field); - set_serial_label(menu_b, "serialb"); - - nonet_checkbox = new BCheckBox(BRect(10, 47, right, 62), "nonet", GetString(STR_NONET_CTRL), new BMessage(MSG_NONET)); - pane->AddChild(nonet_checkbox); - nonet_checkbox->SetValue(PrefsFindBool("nonet") ? B_CONTROL_ON : B_CONTROL_OFF); - - return pane; -} - - -/* - * Create "Memory/Misc" pane - */ - -BView *PrefsWindow::create_memory_pane(void) -{ - char str[256], str2[256]; - BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); - pane->SetViewColor(fill_color); - float right = pane->Bounds().right-10; - - BEntry entry("/boot/var/swap"); - off_t swap_space; - if (entry.GetSize(&swap_space) == B_NO_ERROR) - max_ramsize = swap_space / (1024 * 1024) - 8; - else - max_ramsize = SysInfo.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8; - - int32 value = PrefsFindInt32("ramsize") / (1024 * 1024); - - ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 8, max_ramsize, B_TRIANGLE_THUMB); - ramsize_slider->SetValue(value); - ramsize_slider->UseFillColor(true, &slider_fill_color); - sprintf(str, GetString(STR_RAMSIZE_FMT), 8); - sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize); - ramsize_slider->SetLimitLabels(str, str2); - pane->AddChild(ramsize_slider); - - ignoresegv_checkbox = new BCheckBox(BRect(10, 60, right, 75), "ignoresegv", GetString(STR_IGNORESEGV_CTRL), new BMessage(MSG_IGNORESEGV)); - pane->AddChild(ignoresegv_checkbox); - ignoresegv_checkbox->SetValue(PrefsFindBool("ignoresegv") ? B_CONTROL_ON : B_CONTROL_OFF); - - idlewait_checkbox = new BCheckBox(BRect(10, 80, right, 95), "idlewait", GetString(STR_IDLEWAIT_CTRL), new BMessage(MSG_IDLEWAIT)); - pane->AddChild(idlewait_checkbox); - idlewait_checkbox->SetValue(PrefsFindBool("idlewait") ? B_CONTROL_ON : B_CONTROL_OFF); - - rom_control = new PathControl(false, BRect(10, 100, right, 115), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL); - rom_control->SetDivider(117); - pane->AddChild(rom_control); - - return pane; -} - - -/* - * Message from controls/menus received - */ - -void PrefsWindow::MessageReceived(BMessage *msg) -{ - switch (msg->what) { - case MSG_OK: // "Start" button clicked - PrefsReplaceString("extfs", extfs_control->Text()); - const char *str = rom_control->Text(); - if (strlen(str)) - PrefsReplaceString("rom", str); - else - PrefsRemoveItem("rom"); - SavePrefs(); - send_quit_on_close = false; - PostMessage(B_QUIT_REQUESTED); - be_app->PostMessage(ok_message); - break; - - case MSG_CANCEL: // "Quit" button clicked - send_quit_on_close = false; - PostMessage(B_QUIT_REQUESTED); - be_app->PostMessage(B_QUIT_REQUESTED); - break; - - case B_ABOUT_REQUESTED: // "About" menu item selected - OpenAboutWindow(); - break; - - case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected - ZapPRAM(); - break; - - case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag - int selected = volume_list->CurrentSelection(); - if (selected >= 0) { - const char *str = PrefsFindString("disk", selected); - BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); - delete item; - char newstr[256]; - if (str[0] == '*') - strcpy(newstr, str+1); - else { - strcpy(newstr, "*"); - strcat(newstr, str); - } - PrefsReplaceString("disk", newstr, selected); - volume_list->AddItem(new BStringItem(newstr), selected); - volume_list->Select(selected); - } - break; - } - - case MSG_ADD_VOLUME: - add_volume_panel->Show(); - break; - - case MSG_CREATE_VOLUME: - create_volume_panel->Show(); - break; - - case MSG_ADD_VOLUME_PANEL: { - entry_ref ref; - if (msg->FindRef("refs", &ref) == B_NO_ERROR) { - BEntry entry(&ref, true); - BPath path; - entry.GetPath(&path); - if (entry.IsFile()) { - PrefsAddString("disk", path.Path()); - volume_list->AddItem(new BStringItem(path.Path())); - } else if (entry.IsDirectory()) { - BVolume volume; - if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) { - int32 i = 0; - dev_t d; - fs_info info; - while ((d = next_dev(&i)) >= 0) { - fs_stat_dev(d, &info); - if (volume.Device() == info.dev) { - PrefsAddString("disk", info.device_name); - volume_list->AddItem(new BStringItem(info.device_name)); - } - } - } - } - } - break; - } - - case MSG_CREATE_VOLUME_PANEL: { - entry_ref dir; - if (msg->FindRef("directory", &dir) == B_NO_ERROR) { - BEntry entry(&dir, true); - BPath path; - entry.GetPath(&path); - path.Append(msg->FindString("name")); - - create_volume_panel->Window()->Lock(); - BView *background = create_volume_panel->Window()->ChildAt(0); - NumberControl *v = (NumberControl *)background->FindView("hardfile_size"); - int size = v->Value(); - - char cmd[1024]; - sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size); - int ret = system(cmd); - if (ret == 0) { - PrefsAddString("disk", path.Path()); - volume_list->AddItem(new BStringItem(path.Path())); - } else { - sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret)); - WarningAlert(cmd); - } - } - break; - } - - case MSG_REMOVE_VOLUME: { - int selected = volume_list->CurrentSelection(); - if (selected >= 0) { - PrefsRemoveItem("disk", selected); - BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); - delete item; - volume_list->Select(selected); - } - break; - } - - case MSG_BOOT_ANY: - PrefsReplaceInt32("bootdriver", 0); - break; - - case MSG_BOOT_CDROM: - PrefsReplaceInt32("bootdriver", CDROMRefNum); - break; - - case MSG_NOCDROM: - PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_GFXACCEL: - PrefsReplaceBool("gfxaccel", gfxaccel_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_NOSOUND: - PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_WINDOW_MODE: { - BCheckBox *source = NULL; - msg->FindPointer("source", &source); - if (source == NULL) - break; - for (int i=0; ibox == source) { - if (p->box->Value() == B_CONTROL_ON) - PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") | p->mode); - else - PrefsReplaceInt32("windowmodes", PrefsFindInt32("windowmodes") & ~(p->mode)); - break; - } - } - break; - } - - case MSG_SCREEN_MODE: { - BCheckBox *source = NULL; - msg->FindPointer("source", &source); - if (source == NULL) - break; - for (int i=0; ibox == source) { - if (p->box->Value() == B_CONTROL_ON) - PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") | p->mode); - else - PrefsReplaceInt32("screenmodes", PrefsFindInt32("screenmodes") & ~(p->mode)); - break; - } - } - break; - } - - case MSG_REF_5HZ: - PrefsReplaceInt32("frameskip", 12); - break; - - case MSG_REF_7_5HZ: - PrefsReplaceInt32("frameskip", 8); - break; - - case MSG_REF_10HZ: - PrefsReplaceInt32("frameskip", 6); - break; - - case MSG_REF_15HZ: - PrefsReplaceInt32("frameskip", 4); - break; - - case MSG_REF_30HZ: - PrefsReplaceInt32("frameskip", 2); - break; - - case MSG_SER_A: { - BMenuItem *source = NULL; - msg->FindPointer("source", &source); - if (source) - PrefsReplaceString("seriala", source->Label()); - break; - } - - case MSG_SER_B: { - BMenuItem *source = NULL; - msg->FindPointer("source", &source); - if (source) - PrefsReplaceString("serialb", source->Label()); - break; - } - - case MSG_NONET: - PrefsReplaceBool("nonet", nonet_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_IGNORESEGV: - PrefsReplaceBool("ignoresegv", ignoresegv_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_IDLEWAIT: - PrefsReplaceBool("idlewait", idlewait_checkbox->Value() == B_CONTROL_ON); - break; - - case MSG_RAMSIZE: - PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024); - break; - - default: - BWindow::MessageReceived(msg); - } -} diff --git a/SheepShaver/src/BeOS/scsi_beos.cpp b/SheepShaver/src/BeOS/scsi_beos.cpp deleted file mode 120000 index c495dce0c..000000000 --- a/SheepShaver/src/BeOS/scsi_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/scsi_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/BeOS/serial_beos.cpp b/SheepShaver/src/BeOS/serial_beos.cpp deleted file mode 120000 index 2231c6d0a..000000000 --- a/SheepShaver/src/BeOS/serial_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/serial_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/BeOS/sys_beos.cpp b/SheepShaver/src/BeOS/sys_beos.cpp deleted file mode 120000 index 4e238dac8..000000000 --- a/SheepShaver/src/BeOS/sys_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/sys_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/BeOS/sysdeps.h b/SheepShaver/src/BeOS/sysdeps.h deleted file mode 100644 index 6a7861a59..000000000 --- a/SheepShaver/src/BeOS/sysdeps.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * sysdeps.h - System dependent definitions for BeOS - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SYSDEPS_H -#define SYSDEPS_H - -// Do we have std namespace? -#ifdef __POWERPC__ -#define NO_STD_NAMESPACE -#endif - -#include -#include -#include - -#include "user_strings_beos.h" - -// Are we using a PPC emulator or the real thing? -#ifdef __POWERPC__ -#define EMULATED_PPC 0 -#define WORDS_BIGENDIAN 1 -#define SYSTEM_CLOBBERS_R2 1 -#else -#define EMULATED_PPC 1 -#undef WORDS_BIGENDIAN -#endif - -// High precision timing -#define PRECISE_TIMING 1 -#define PRECISE_TIMING_BEOS 1 - -#define POWERPC_ROM 1 - -// Time data type for Time Manager emulation -typedef bigtime_t tm_time_t; - -// 64 bit file offsets -typedef off_t loff_t; - -// Data types -typedef uint32 uintptr; -typedef int32 intptr; - -// Timing functions -extern void Delay_usec(uint32 usec); - -// Macro for calling MacOS routines -#define CallMacOS(type, proc) (*(type)proc)() -#define CallMacOS1(type, proc, arg1) (*(type)proc)(arg1) -#define CallMacOS2(type, proc, arg1, arg2) (*(type)proc)(arg1, arg2) -#define CallMacOS3(type, proc, arg1, arg2, arg3) (*(type)proc)(arg1, arg2, arg3) -#define CallMacOS4(type, proc, arg1, arg2, arg3, arg4) (*(type)proc)(arg1, arg2, arg3, arg4) -#define CallMacOS5(type, proc, arg1, arg2, arg3, arg4, arg5) (*(type)proc)(arg1, arg2, arg3, arg4, arg5) -#define CallMacOS6(type, proc, arg1, arg2, arg3, arg4, arg5, arg6) (*(type)proc)(arg1, arg2, arg3, arg4, arg5, arg6) -#define CallMacOS7(type, proc, arg1, arg2, arg3, arg4, arg5, arg6, arg7) (*(type)proc)(arg1, arg2, arg3, arg4, arg5, arg6, arg7) - -#endif diff --git a/SheepShaver/src/BeOS/timer_beos.cpp b/SheepShaver/src/BeOS/timer_beos.cpp deleted file mode 120000 index 0d9e80149..000000000 --- a/SheepShaver/src/BeOS/timer_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/timer_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/BeOS/user_strings_beos.cpp b/SheepShaver/src/BeOS/user_strings_beos.cpp deleted file mode 100644 index 0f7b13673..000000000 --- a/SheepShaver/src/BeOS/user_strings_beos.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * user_strings_beos.cpp - Localizable strings, BeOS specific strings - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" -#include "user_strings.h" - - -// Platform-specific string definitions -user_string_def platform_strings[] = { - // Common strings that have a platform-specific variant - {STR_VOLUME_IS_MOUNTED_WARN, "The volume '%s' is mounted under BeOS. Basilisk II will try to unmount it."}, - {STR_EXTFS_CTRL, "BeOS Root"}, - {STR_EXTFS_NAME, "BeOS Directory Tree"}, - {STR_EXTFS_VOLUME_NAME, "BeOS"}, - - // Purely platform-specific strings - {STR_NO_SHEEP_DRIVER_ERR, "Cannot open /dev/sheep: %s (%08x). SheepShaver is not properly installed."}, - {STR_NO_RAM_AREA_ERR, "Not enough memory to create RAM area: %s (%08x)."}, - {STR_NO_ROM_AREA_ERR, "Not enough memory to create ROM area."}, - {STR_NO_SHEEP_MEM_AREA_ERR, "Not enough memory to create SheepShaver area."}, - {STR_SHEEP_UP_ERR, "Cannot allocate Low Memory Globals: %s (%08x)."}, - {STR_NO_NET_ADDON_WARN, "The SheepShaver net server add-on cannot be found. Ethernet will not be available."}, - {STR_NET_CONFIG_MODIFY_WARN, "To enable Ethernet networking for SheepShaver, your network configuration has to be modified and the network restarted. Do you want this to be done now (selecting \"Cancel\" will disable Ethernet under SheepShaver)?."}, - {STR_NET_ADDON_INIT_FAILED, "SheepShaver net server add-on found\nbut there seems to be no network hardware.\nPlease check your network preferences."}, - {STR_NET_ADDON_CLONE_FAILED, "Cloning of the network transfer area failed."}, - {STR_NO_SHEEP_MEM_AREA_ERR, "Cannot create SheepShaver Globals area: %s (%08x)."}, - {STR_NO_DR_CACHE_AREA_ERR, "Cannot create DR Cache area: %s (%08x)."}, - {STR_NO_DR_EMULATOR_AREA_ERR, "Cannot create DR Emulator area: %s (%08x)."}, - - {-1, NULL} // End marker -}; - - -/* - * Fetch pointer to string, given the string number - */ - -const char *GetString(int num) -{ - // First search for platform-specific string - int i = 0; - while (platform_strings[i].num >= 0) { - if (platform_strings[i].num == num) - return platform_strings[i].str; - i++; - } - - // Not found, search for common string - i = 0; - while (common_strings[i].num >= 0) { - if (common_strings[i].num == num) - return common_strings[i].str; - i++; - } - return NULL; -} diff --git a/SheepShaver/src/BeOS/user_strings_beos.h b/SheepShaver/src/BeOS/user_strings_beos.h deleted file mode 100644 index b82481104..000000000 --- a/SheepShaver/src/BeOS/user_strings_beos.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * user_strings_beos.h - BeOS-specific localizable strings - * - * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USER_STRINGS_BEOS_H -#define USER_STRINGS_BEOS_H - -enum { - STR_NO_SHEEP_DRIVER_ERR = 10000, - STR_NO_ROM_AREA_ERR, - STR_SHEEP_UP_ERR, - STR_NO_NET_ADDON_WARN, - STR_NET_CONFIG_MODIFY_WARN, - STR_NET_ADDON_INIT_FAILED, - STR_NET_ADDON_CLONE_FAILED, - STR_NO_SHEEP_MEM_AREA_ERR, - STR_NO_DR_CACHE_AREA_ERR, - STR_NO_DR_EMULATOR_AREA_ERR -}; - -#endif diff --git a/SheepShaver/src/BeOS/video_beos.cpp b/SheepShaver/src/BeOS/video_beos.cpp deleted file mode 100644 index aa4f24966..000000000 --- a/SheepShaver/src/BeOS/video_beos.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/* - * video_beos.cpp - Video/graphics emulation, BeOS specific things - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include "video.h" -#include "video_defs.h" -#include "main.h" -#include "adb.h" -#include "prefs.h" -#include "user_strings.h" -#include "about_window.h" -#include "version.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static sem_id video_lock = -1; // Protection during mode changes -static sem_id mac_os_lock = -1; // This is used to stop the MacOS thread when the SheepShaver workspace is switched out - -// Prototypes -static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter); - -// From sys_beos.cpp -extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg); -extern void SysMountVolume(const char *name); - - -#include "video_window.h" -#include "video_screen.h" - - -/* - * Display manager thread (for opening and closing windows and screens; - * this is not safe under R4 when running on the MacOS stack in kernel - * space) - */ - -// Message constants -const uint32 MSG_OPEN_WINDOW = 'owin'; -const uint32 MSG_CLOSE_WINDOW = 'cwin'; -const uint32 MSG_OPEN_SCREEN = 'oscr'; -const uint32 MSG_CLOSE_SCREEN = 'cscr'; -const uint32 MSG_QUIT_DISPLAY_MANAGER = 'quit'; - -static thread_id dm_thread = -1; -static sem_id dm_done_sem = -1; - -static status_t display_manager(void *arg) -{ - for (;;) { - - // Receive message - thread_id sender; - uint32 code = receive_data(&sender, NULL, 0); - D(bug("Display manager received %08lx\n", code)); - switch (code) { - case MSG_QUIT_DISPLAY_MANAGER: - return 0; - - case MSG_OPEN_WINDOW: - D(bug("Opening window\n")); - the_window = new MacWindow(BRect(0, 0, VModes[cur_mode].viXsize-1, VModes[cur_mode].viYsize-1)); - D(bug("Opened\n")); - break; - - case MSG_CLOSE_WINDOW: - if (the_window != NULL) { - D(bug("Posting quit to window\n")); - the_window->PostMessage(B_QUIT_REQUESTED); - D(bug("Posted, waiting\n")); - while (the_window) - snooze(200000); - D(bug("Window closed\n")); - } - break; - - case MSG_OPEN_SCREEN: { - D(bug("Opening screen\n")); - long scr_mode = 0; - switch (VModes[cur_mode].viAppleMode) { - case APPLE_8_BIT: - switch (VModes[cur_mode].viAppleID) { - case APPLE_640x480: - scr_mode = B_8_BIT_640x480; - break; - case APPLE_800x600: - scr_mode = B_8_BIT_800x600; - break; - case APPLE_1024x768: - scr_mode = B_8_BIT_1024x768; - break; - case APPLE_1152x900: - scr_mode = B_8_BIT_1152x900; - break; - case APPLE_1280x1024: - scr_mode = B_8_BIT_1280x1024; - break; - case APPLE_1600x1200: - scr_mode = B_8_BIT_1600x1200; - break; - } - break; - case APPLE_16_BIT: - switch (VModes[cur_mode].viAppleID) { - case APPLE_640x480: - scr_mode = B_15_BIT_640x480; - break; - case APPLE_800x600: - scr_mode = B_15_BIT_800x600; - break; - case APPLE_1024x768: - scr_mode = B_15_BIT_1024x768; - break; - case APPLE_1152x900: - scr_mode = B_15_BIT_1152x900; - break; - case APPLE_1280x1024: - scr_mode = B_15_BIT_1280x1024; - break; - case APPLE_1600x1200: - scr_mode = B_15_BIT_1600x1200; - break; - } - break; - case APPLE_32_BIT: - switch (VModes[cur_mode].viAppleID) { - case APPLE_640x480: - scr_mode = B_32_BIT_640x480; - break; - case APPLE_800x600: - scr_mode = B_32_BIT_800x600; - break; - case APPLE_1024x768: - scr_mode = B_32_BIT_1024x768; - break; - case APPLE_1152x900: - scr_mode = B_32_BIT_1152x900; - break; - case APPLE_1280x1024: - scr_mode = B_32_BIT_1280x1024; - break; - case APPLE_1600x1200: - scr_mode = B_32_BIT_1600x1200; - break; - } - break; - } - the_screen = new MacScreen(GetString(STR_WINDOW_TITLE), scr_mode); - D(bug("Opened, error %08lx\n", screen_error)); - if (screen_error != B_NO_ERROR) { - D(bug("Error, posting quit to screen\n")); - the_screen->PostMessage(B_QUIT_REQUESTED); - D(bug("Posted, waiting\n")); - while (the_screen) - snooze(200000); - D(bug("Screen closed\n")); - break; - } - - // Wait for video mem access - D(bug("Showing screen\n")); - the_screen->Show(); - D(bug("Shown, waiting for frame buffer access\n")); - while (!drawing_enable) - snooze(200000); - D(bug("Access granted\n")); - break; - } - - case MSG_CLOSE_SCREEN: - if (the_screen != NULL) { - D(bug("Posting quit to screen\n")); - the_screen->PostMessage(B_QUIT_REQUESTED); - D(bug("Posted, waiting\n")); - while (the_screen) - snooze(200000); - D(bug("Screen closed\n")); - } - break; - } - - // Acknowledge - release_sem(dm_done_sem); - } -} - - -/* - * Open display (window or screen) - */ - -static void open_display(void) -{ - D(bug("entering open_display()\n")); - display_type = VModes[cur_mode].viType; - if (display_type == DIS_SCREEN) { - while (send_data(dm_thread, MSG_OPEN_SCREEN, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ; - } else if (display_type == DIS_WINDOW) { - while (send_data(dm_thread, MSG_OPEN_WINDOW, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ; - } - D(bug("exiting open_display()\n")); -} - - -/* - * Close display - */ - -static void close_display(void) -{ - D(bug("entering close_display()\n")); - if (display_type == DIS_SCREEN) { - while (send_data(dm_thread, MSG_CLOSE_SCREEN, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ; - } else if (display_type == DIS_WINDOW) { - while (send_data(dm_thread, MSG_CLOSE_WINDOW, NULL, 0) == B_INTERRUPTED) ; - while (acquire_sem(dm_done_sem) == B_INTERRUPTED) ; - } - D(bug("exiting close_display()\n")); -} - - -/* - * Initialization - */ - -static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, long apple_mode, long apple_id, int type) -{ - if (allow & test) { - p->viType = type; - switch (apple_id) { - case APPLE_W_640x480: - case APPLE_640x480: - p->viXsize = 640; - p->viYsize = 480; - break; - case APPLE_W_800x600: - case APPLE_800x600: - p->viXsize = 800; - p->viYsize = 600; - break; - case APPLE_1024x768: - p->viXsize = 1024; - p->viYsize = 768; - break; - case APPLE_1152x900: - p->viXsize = 1152; - p->viYsize = 900; - break; - case APPLE_1280x1024: - p->viXsize = 1280; - p->viYsize = 1024; - break; - case APPLE_1600x1200: - p->viXsize = 1600; - p->viYsize = 1200; - break; - } - switch (apple_mode) { - case APPLE_8_BIT: - p->viRowBytes = p->viXsize; - break; - case APPLE_16_BIT: - p->viRowBytes = p->viXsize * 2; - break; - case APPLE_32_BIT: - p->viRowBytes = p->viXsize * 4; - break; - } - p->viAppleMode = apple_mode; - p->viAppleID = apple_id; - p++; - } -} - -bool VideoInit(void) -{ - // Init variables, create semaphores - private_data = NULL; - cur_mode = 0; // Window 640x480 - video_lock = create_sem(1, "Video Lock"); - mac_os_lock = create_sem(0, "MacOS Frame Buffer Lock"); - dm_done_sem = create_sem(0, "Display Manager Done"); - - // Construct video mode table - VideoInfo *p = VModes; - uint32 window_modes = PrefsFindInt32("windowmodes"); - uint32 screen_modes = PrefsFindInt32("screenmodes"); - if (window_modes == 0 && screen_modes == 0) - window_modes |= B_8_BIT_640x480 | B_8_BIT_800x600; // Allow at least 640x480 and 800x600 window modes - add_mode(p, window_modes, B_8_BIT_640x480, APPLE_8_BIT, APPLE_W_640x480, DIS_WINDOW); - add_mode(p, window_modes, B_8_BIT_800x600, APPLE_8_BIT, APPLE_W_800x600, DIS_WINDOW); - add_mode(p, window_modes, B_15_BIT_640x480, APPLE_16_BIT, APPLE_W_640x480, DIS_WINDOW); - add_mode(p, window_modes, B_15_BIT_800x600, APPLE_16_BIT, APPLE_W_800x600, DIS_WINDOW); - add_mode(p, window_modes, B_32_BIT_640x480, APPLE_32_BIT, APPLE_W_640x480, DIS_WINDOW); - add_mode(p, window_modes, B_32_BIT_800x600, APPLE_32_BIT, APPLE_W_800x600, DIS_WINDOW); - add_mode(p, screen_modes, B_8_BIT_640x480, APPLE_8_BIT, APPLE_640x480, DIS_SCREEN); - add_mode(p, screen_modes, B_8_BIT_800x600, APPLE_8_BIT, APPLE_800x600, DIS_SCREEN); - add_mode(p, screen_modes, B_8_BIT_1024x768, APPLE_8_BIT, APPLE_1024x768, DIS_SCREEN); - add_mode(p, screen_modes, B_8_BIT_1152x900, APPLE_8_BIT, APPLE_1152x900, DIS_SCREEN); - add_mode(p, screen_modes, B_8_BIT_1280x1024, APPLE_8_BIT, APPLE_1280x1024, DIS_SCREEN); - add_mode(p, screen_modes, B_8_BIT_1600x1200, APPLE_8_BIT, APPLE_1600x1200, DIS_SCREEN); - add_mode(p, screen_modes, B_15_BIT_640x480, APPLE_16_BIT, APPLE_640x480, DIS_SCREEN); - add_mode(p, screen_modes, B_15_BIT_800x600, APPLE_16_BIT, APPLE_800x600, DIS_SCREEN); - add_mode(p, screen_modes, B_15_BIT_1024x768, APPLE_16_BIT, APPLE_1024x768, DIS_SCREEN); - add_mode(p, screen_modes, B_15_BIT_1152x900, APPLE_16_BIT, APPLE_1152x900, DIS_SCREEN); - add_mode(p, screen_modes, B_15_BIT_1280x1024, APPLE_16_BIT, APPLE_1280x1024, DIS_SCREEN); - add_mode(p, screen_modes, B_15_BIT_1600x1200, APPLE_16_BIT, APPLE_1600x1200, DIS_SCREEN); - add_mode(p, screen_modes, B_32_BIT_640x480, APPLE_32_BIT, APPLE_640x480, DIS_SCREEN); - add_mode(p, screen_modes, B_32_BIT_800x600, APPLE_32_BIT, APPLE_800x600, DIS_SCREEN); - add_mode(p, screen_modes, B_32_BIT_1024x768, APPLE_32_BIT, APPLE_1024x768, DIS_SCREEN); - add_mode(p, screen_modes, B_32_BIT_1152x900, APPLE_32_BIT, APPLE_1152x900, DIS_SCREEN); - add_mode(p, screen_modes, B_32_BIT_1280x1024, APPLE_32_BIT, APPLE_1280x1024, DIS_SCREEN); - add_mode(p, screen_modes, B_32_BIT_1600x1200, APPLE_32_BIT, APPLE_1600x1200, DIS_SCREEN); - p->viType = DIS_INVALID; // End marker - p->viRowBytes = 0; - p->viXsize = p->viYsize = 0; - p->viAppleMode = 0; - p->viAppleID = 0; - - // Start display manager thread - dm_thread = spawn_thread(display_manager, "Display Manager", B_NORMAL_PRIORITY, NULL); - resume_thread(dm_thread); - - // Open window/screen - open_display(); - if (display_type == DIS_SCREEN && the_screen == NULL) { - char str[256]; - sprintf(str, GetString(STR_FULL_SCREEN_ERR), strerror(screen_error), screen_error); - ErrorAlert(str); - return false; - } - return true; -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - if (dm_thread >= 0) { - - // Close display - acquire_sem(video_lock); - close_display(); - if (private_data != NULL) { - delete private_data->gammaTable; - delete private_data; - } - - // Stop display manager - status_t l; - send_data(dm_thread, MSG_QUIT_DISPLAY_MANAGER, NULL, 0); - while (wait_for_thread(dm_thread, &l) == B_INTERRUPTED) ; - } - - // Delete semaphores - delete_sem(video_lock); - delete_sem(mac_os_lock); - delete_sem(dm_done_sem); -} - - -/* - * Close screen in full-screen mode - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - if (display_type == DIS_SCREEN) { - acquire_sem(video_lock); - close_display(); - release_sem(video_lock); - } -} - - -/* - * Execute video VBL routine - */ - -void VideoVBL(void) -{ - release_sem(mac_os_lock); - if (private_data != NULL && private_data->interruptsEnabled) - VSLDoInterruptService(private_data->vslServiceID); - while (acquire_sem(mac_os_lock) == B_INTERRUPTED) ; -} - - -/* - * Filter function for receiving mouse and keyboard events - */ - -#define MENU_IS_POWER 0 - -// Be -> Mac raw keycode translation table -static const uint8 keycode2mac[0x80] = { - 0xff, 0x35, 0x7a, 0x78, 0x63, 0x76, 0x60, 0x61, // inv Esc F1 F2 F3 F4 F5 F6 - 0x62, 0x64, 0x65, 0x6d, 0x67, 0x6f, 0x69, 0x6b, // F7 F8 F9 F10 F11 F12 F13 F14 - 0x71, 0x0a, 0x12, 0x13, 0x14, 0x15, 0x17, 0x16, // F15 ` 1 2 3 4 5 6 - 0x1a, 0x1c, 0x19, 0x1d, 0x1b, 0x18, 0x33, 0x72, // 7 8 9 0 - = BSP INS - 0x73, 0x74, 0x47, 0x4b, 0x43, 0x4e, 0x30, 0x0c, // HOM PUP NUM / * - TAB Q - 0x0d, 0x0e, 0x0f, 0x11, 0x10, 0x20, 0x22, 0x1f, // W E R T Y U I O - 0x23, 0x21, 0x1e, 0x2a, 0x75, 0x77, 0x79, 0x59, // P [ ] \ DEL END PDN 7 - 0x5b, 0x5c, 0x45, 0x39, 0x00, 0x01, 0x02, 0x03, // 8 9 + CAP A S D F - 0x05, 0x04, 0x26, 0x28, 0x25, 0x29, 0x27, 0x24, // G H J K L ; ' RET - 0x56, 0x57, 0x58, 0x38, 0x06, 0x07, 0x08, 0x09, // 4 5 6 SHL Z X C V - 0x0b, 0x2d, 0x2e, 0x2b, 0x2f, 0x2c, 0x38, 0x3e, // B N M , . / SHR CUP - 0x53, 0x54, 0x55, 0x4c, 0x36, 0x37, 0x31, 0x37, // 1 2 3 ENT CTL ALT SPC ALT - 0x36, 0x3b, 0x3d, 0x3c, 0x52, 0x41, 0x3a, 0x3a, // CTR CLF CDN CRT 0 . CMD CMD -#if MENU_IS_POWER - 0x7f, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv -#else - 0x32, 0x32, 0x51, 0x7f, 0xff, 0xff, 0xff, 0xff, // MNU EUR = POW inv inv inv inv -#endif - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - -static const uint8 modifier2mac[0x20] = { -#if MENU_IS_POWER - 0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x7f, // SHF CMD inv CAP F14 NUM OPT MNU -#else - 0x38, 0x37, 0x36, 0x39, 0x6b, 0x47, 0x3a, 0x32, // SHF CMD CTR CAP F14 NUM OPT MNU -#endif - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // inv inv inv inv inv inv inv inv - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // inv inv inv inv inv inv inv inv -}; - -static filter_result filter_func(BMessage *msg, BHandler **target, BMessageFilter *filter) -{ -// msg->PrintToStream(); - switch (msg->what) { - case B_KEY_DOWN: - case B_KEY_UP: { - uint32 be_code = msg->FindInt32("key") & 0xff; - uint32 mac_code = keycode2mac[be_code]; - - // Intercept Ctrl-F1 (mount floppy disk shortcut) - uint32 mods = msg->FindInt32("modifiers"); - if (be_code == 0x02 && (mods & B_CONTROL_KEY)) - SysMountVolume("/dev/disk/floppy/raw"); - - if (mac_code == 0xff) - return B_DISPATCH_MESSAGE; - if (msg->what == B_KEY_DOWN) - ADBKeyDown(mac_code); - else - ADBKeyUp(mac_code); - return B_SKIP_MESSAGE; - } - - case B_MODIFIERS_CHANGED: { - uint32 mods = msg->FindInt32("modifiers"); - uint32 old_mods = msg->FindInt32("be:old_modifiers"); - uint32 changed = mods ^ old_mods; - uint32 mask = 1; - for (int i=0; i<32; i++, mask<<=1) - if (changed & mask) { - uint32 mac_code = modifier2mac[i]; - if (mac_code == 0xff) - continue; - if (mods & mask) - ADBKeyDown(mac_code); - else - ADBKeyUp(mac_code); - } - return B_SKIP_MESSAGE; - } - - case B_MOUSE_MOVED: { - BPoint point; - msg->FindPoint("where", &point); - ADBMouseMoved(int(point.x), int(point.y)); - return B_DISPATCH_MESSAGE; // Otherwise BitmapView::MouseMoved() wouldn't be called - } - - case B_MOUSE_DOWN: { - uint32 buttons = msg->FindInt32("buttons"); - if (buttons & B_PRIMARY_MOUSE_BUTTON) - ADBMouseDown(0); - if (buttons & B_SECONDARY_MOUSE_BUTTON) - ADBMouseDown(1); - if (buttons & B_TERTIARY_MOUSE_BUTTON) - ADBMouseDown(2); - return B_SKIP_MESSAGE; - } - - case B_MOUSE_UP: // B_MOUSE_UP means "all buttons released" - ADBMouseUp(0); - ADBMouseUp(1); - ADBMouseUp(2); - return B_SKIP_MESSAGE; - - default: - return B_DISPATCH_MESSAGE; - } -} - - -/* - * Install graphics acceleration - */ - -// Rectangle blitting -static void accl_bitblt(accl_params *p) -{ - D(bug("accl_bitblt\n")); - - // Get blitting parameters - int16 src_X = p->src_rect[1] - p->src_bounds[1]; - int16 src_Y = p->src_rect[0] - p->src_bounds[0]; - int16 dest_X = p->dest_rect[1] - p->dest_bounds[1]; - int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0]; - int16 width = p->dest_rect[3] - p->dest_rect[1] - 1; - int16 height = p->dest_rect[2] - p->dest_rect[0] - 1; - D(bug(" src X %d, src Y %d, dest X %d, dest Y %d\n", src_X, src_Y, dest_X, dest_Y)); - D(bug(" width %d, height %d\n", width, height)); - - // And perform the blit - bitblt_hook(src_X, src_Y, dest_X, dest_Y, width, height); -} - -static bool accl_bitblt_hook(accl_params *p) -{ - D(bug("accl_draw_hook %p\n", p)); - - // Check if we can accelerate this bitblt - if (p->src_base_addr == screen_base && p->dest_base_addr == screen_base && - display_type == DIS_SCREEN && bitblt_hook != NULL && - ((uint32 *)p)[0x18 >> 2] + ((uint32 *)p)[0x128 >> 2] == 0 && - ((uint32 *)p)[0x130 >> 2] == 0 && - p->transfer_mode == 0 && - p->src_row_bytes > 0 && ((uint32 *)p)[0x15c >> 2] > 0) { - - // Yes, set function pointer - p->draw_proc = (uint32)accl_bitblt; - return true; - } - return false; -} - -// Rectangle filling/inversion -static void accl_fillrect8(accl_params *p) -{ - D(bug("accl_fillrect8\n")); - - // Get filling parameters - int16 dest_X = p->dest_rect[1] - p->dest_bounds[1]; - int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0]; - int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1; - int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1; - uint8 color = p->pen_mode == 8 ? p->fore_pen : p->back_pen; - D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y)); - D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max)); - - // And perform the fill - fillrect8_hook(dest_X, dest_Y, dest_X_max, dest_Y_max, color); -} - -static void accl_fillrect32(accl_params *p) -{ - D(bug("accl_fillrect32\n")); - - // Get filling parameters - int16 dest_X = p->dest_rect[1] - p->dest_bounds[1]; - int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0]; - int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1; - int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1; - uint32 color = p->pen_mode == 8 ? p->fore_pen : p->back_pen; - D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y)); - D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max)); - - // And perform the fill - fillrect32_hook(dest_X, dest_Y, dest_X_max, dest_Y_max, color); -} - -static void accl_invrect(accl_params *p) -{ - D(bug("accl_invrect\n")); - - // Get inversion parameters - int16 dest_X = p->dest_rect[1] - p->dest_bounds[1]; - int16 dest_Y = p->dest_rect[0] - p->dest_bounds[0]; - int16 dest_X_max = p->dest_rect[3] - p->dest_bounds[1] - 1; - int16 dest_Y_max = p->dest_rect[2] - p->dest_bounds[0] - 1; - D(bug(" dest X %d, dest Y %d\n", dest_X, dest_Y)); - D(bug(" dest X max %d, dest Y max %d\n", dest_X_max, dest_Y_max)); - - //!!?? pen_mode == 14 - - // And perform the inversion - invrect_hook(dest_X, dest_Y, dest_X_max, dest_Y_max); -} - -static bool accl_fillrect_hook(accl_params *p) -{ - D(bug("accl_fillrect_hook %p\n", p)); - - // Check if we can accelerate this fillrect - if (p->dest_base_addr == screen_base && ((uint32 *)p)[0x284 >> 2] != 0 && display_type == DIS_SCREEN) { - if (p->transfer_mode == 8) { - // Fill - if (p->dest_pixel_size == 8 && fillrect8_hook != NULL) { - p->draw_proc = (uint32)accl_fillrect8; - return true; - } else if (p->dest_pixel_size == 32 && fillrect32_hook != NULL) { - p->draw_proc = (uint32)accl_fillrect32; - return true; - } - } else if (p->transfer_mode == 10 && invrect_hook != NULL) { - // Invert - p->draw_proc = (uint32)accl_invrect; - return true; - } - } - return false; -} - -// Dummy for testing -/* -static void do_nothing(accl_params *p) {} -static bool accl_foobar_hook(accl_params *p) -{ - printf("accl_foobar_hook %p\n", p); - printf(" src_base_addr %p, dest_base_addr %p\n", p->src_base_addr, p->dest_base_addr); - printf(" src_row_bytes %d, dest_row_bytes %d\n", p->src_row_bytes, p->dest_row_bytes); - printf(" src_pixel_size %d, dest_pixel_size %d\n", p->src_pixel_size, p->dest_pixel_size); - printf(" src_bounds (%d,%d,%d,%d), dest_bounds (%d,%d,%d,%d)\n", p->src_bounds[0], p->src_bounds[1], p->src_bounds[2], p->src_bounds[3], p->dest_bounds[0], p->dest_bounds[1], p->dest_bounds[2], p->dest_bounds[3]); - printf(" src_rect (%d,%d,%d,%d), dest_rect (%d,%d,%d,%d)\n", p->src_rect[0], p->src_rect[1], p->src_rect[2], p->src_rect[3], p->dest_rect[0], p->dest_rect[1], p->dest_rect[2], p->dest_rect[3]); - printf(" transfer mode %d\n", p->transfer_mode); - printf(" pen mode %d\n", p->pen_mode); - printf(" fore_pen %08x, back_pen %08x\n", p->fore_pen, p->back_pen); - printf(" val1 %08x, val2 %08x\n", ((uint32 *)p)[0x18 >> 2], ((uint32 *)p)[0x128 >> 2]); - printf(" val3 %08x\n", ((uint32 *)p)[0x130 >> 2]); - printf(" val4 %08x\n", ((uint32 *)p)[0x15c >> 2]); - printf(" val5 %08x\n", ((uint32 *)p)[0x160 >> 2]); - printf(" val6 %08x\n", ((uint32 *)p)[0x1b4 >> 2]); - printf(" val7 %08x\n", ((uint32 *)p)[0x284 >> 2]); - p->draw_proc = (uint32)do_nothing; - return true; -} -static struct accl_hook_info foobar_hook_info = {(uint32)accl_foobar_hook, (uint32)accl_sync_hook, 6}; -*/ - -// Wait for graphics operation to finish -static bool accl_sync_hook(void *arg) -{ - D(bug("accl_sync_hook %p\n", arg)); - if (sync_hook != NULL) - sync_hook(); - return true; -} - -static struct accl_hook_info bitblt_hook_info = {(uint32)accl_bitblt_hook, (uint32)accl_sync_hook, ACCL_BITBLT}; -static struct accl_hook_info fillrect_hook_info = {(uint32)accl_fillrect_hook, (uint32)accl_sync_hook, ACCL_FILLRECT}; - -void VideoInstallAccel(void) -{ - // Install acceleration hooks - if (PrefsFindBool("gfxaccel")) { - D(bug("Video: Installing acceleration hooks\n")); - NQDMisc(6, (uintptr)&bitblt_hook_info); - NQDMisc(6, (uintptr)&fillrect_hook_info); - } -} - - -/* - * Change video mode - */ - -int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) -{ - /* return if no mode change */ - if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && - (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; - - /* first find video mode in table */ - for (int i=0; VModes[i].viType != DIS_INVALID; i++) { - if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && - (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { - csSave->saveMode = ReadMacInt16(ParamPtr + csMode); - csSave->saveData = ReadMacInt32(ParamPtr + csData); - csSave->savePage = ReadMacInt16(ParamPtr + csPage); - - while (acquire_sem(video_lock) == B_INTERRUPTED) ; - DisableInterrupt(); - - /* close old display */ - close_display(); - - /* open new display */ - cur_mode = i; - open_display(); - - /* opening the screen failed? Then bail out */ - if (display_type == DIS_SCREEN && the_screen == NULL) { - release_sem(video_lock); - ErrorAlert(GetString(STR_FULL_SCREEN_ERR)); - QuitEmulator(); - } - - WriteMacInt32(ParamPtr + csBaseAddr, screen_base); - csSave->saveBaseAddr=screen_base; - csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ - csSave->saveMode=VModes[cur_mode].viAppleMode; - - EnableInterrupt(); - release_sem(video_lock); - return noErr; - } - } - return paramErr; -} - - -/* - * Set color palette - */ - -void video_set_palette(void) -{ - if (display_type == DIS_SCREEN && the_screen != NULL) - the_screen->palette_changed = true; - else { // remap colors to BeOS-Palette - BScreen screen; - for (int i=0;i<256;i++) - remap_mac_be[i]=screen.IndexForColor(mac_pal[i].red,mac_pal[i].green,mac_pal[i].blue); - } -} - - -/* - * Can we set the MacOS cursor image into the window? - */ - -bool video_can_change_cursor(void) -{ - return (display_type != DIS_SCREEN); -} - - -/* - * Set cursor image for window - */ - -void video_set_cursor(void) -{ - the_window->cursor_changed = true; // Inform window (don't set cursor directly because this may run at interrupt (i.e. signal handler) time) -} - - -/* - * Record dirty area from NQD - */ - -void video_set_dirty_area(int x, int y, int w, int h) -{ -} diff --git a/SheepShaver/src/BeOS/video_screen.h b/SheepShaver/src/BeOS/video_screen.h deleted file mode 100644 index a3b5f2683..000000000 --- a/SheepShaver/src/BeOS/video_screen.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * video_screen.h - Full screen video modes - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -static bool drawing_enable = false; // This flag indicated if the access to the screen is allowed -static int page_num; // Index of the currently displayed buffer - - -// Blitter functions -typedef void (*bitblt_ptr)(int32, int32, int32, int32, int32, int32); -static bitblt_ptr bitblt_hook; -typedef void (*fillrect8_ptr)(int32, int32, int32, int32, uint8); -static fillrect8_ptr fillrect8_hook; -typedef void (*fillrect32_ptr)(int32, int32, int32, int32, uint32); -static fillrect32_ptr fillrect32_hook; -typedef void (*invrect_ptr)(int32, int32, int32, int32); -static invrect_ptr invrect_hook; -typedef void (*sync_ptr)(void); -static sync_ptr sync_hook; - - -class MacScreen : public BWindowScreen { -public: - MacScreen(const char *name, uint32 space); - virtual ~MacScreen(); - virtual void Quit(void); - virtual void ScreenConnected(bool active); - - bool palette_changed; - -private: - static status_t tick_func(void *arg); - - BView *view; // Main view for GetMouse() - - uint8 *frame_backup; // Frame buffer backup when switching from/to different workspace - bool quitting; // Flag for ScreenConnected: We are quitting, don't pause emulator thread - bool first; // Flag for ScreenConnected: This is the first time we become active - - thread_id tick_thread; - bool tick_thread_active; -}; - - -// Pointer to our screen -static MacScreen *the_screen = NULL; - -// Error code from BWindowScreen constructor -static status_t screen_error; - -// to enable debugger mode. -#define SCREEN_DEBUG false - - -/* - * Screen constructor - */ - -MacScreen::MacScreen(const char *name, uint32 space) : BWindowScreen(name, space, &screen_error, SCREEN_DEBUG), tick_thread(-1) -{ - D(bug("Screen constructor\n")); - - // Set all variables - frame_backup = NULL; - palette_changed = false; - quitting = false; - first = true; - drawing_enable = false; - ADBSetRelMouseMode(true); - - // Create view to poll the mouse - view = new BView (BRect(0,0,VModes[cur_mode].viXsize-1,VModes[cur_mode].viYsize-1),NULL,B_FOLLOW_NONE,0); - AddChild(view); - - // Start 60Hz interrupt - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "Polling sucks...", B_DISPLAY_PRIORITY, this); - RegisterThread(tick_thread); - resume_thread(tick_thread); - - // Add filter for keyboard and mouse events - BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func); - AddCommonFilter(filter); - D(bug("Screen constructor done\n")); -} - - -/* - * Screen destructor - */ - -MacScreen::~MacScreen() -{ - D(bug("Screen destructor, quitting tick thread\n")); - - // Stop 60Hz interrupt - if (tick_thread > 0) { - status_t l; - tick_thread_active = false; - while (wait_for_thread(tick_thread, &l) == B_INTERRUPTED) ; - } - D(bug("tick thread quit\n")); - - // Tell the emulator that we're done - the_screen = NULL; - D(bug("Screen destructor done\n")); -} - - -/* - * Screen closed - */ - -void MacScreen::Quit(void) -{ - // Tell ScreenConnected() that we are quitting - quitting = true; - D(bug("MacScreen::Quit(), disconnecting\n")); - Disconnect(); - D(bug("disconnected\n")); - BWindowScreen::Quit(); -} - - -/* - * Screen connected/disconnected - */ - -void MacScreen::ScreenConnected(bool active) -{ - D(bug("ScreenConnected(%d)\n", active)); - graphics_card_info *info = CardInfo(); - D(bug(" card_info %p\n", info)); - - if (active) { - - // Read graphics parameters - D(bug(" active\n")); - screen_base = (uint32)info->frame_buffer; - D(bug(" screen_base %p\n", screen_base)); - VModes[cur_mode].viRowBytes = info->bytes_per_row; - D(bug(" xmod %d\n", info->bytes_per_row)); - - // Get acceleration functions - if (PrefsFindBool("gfxaccel")) { - bitblt_hook = (bitblt_ptr)CardHookAt(7); - D(bug(" bitblt_hook %p\n", bitblt_hook)); - fillrect8_hook = (fillrect8_ptr)CardHookAt(5); - D(bug(" fillrect8_hook %p\n", fillrect8_hook)); - fillrect32_hook = (fillrect32_ptr)CardHookAt(6); - D(bug(" fillrect32_hook %p\n", fillrect32_hook)); - invrect_hook = (invrect_ptr)CardHookAt(11); - D(bug(" invrect_hook %p\n", invrect_hook)); - sync_hook = (sync_ptr)CardHookAt(10); - D(bug(" sync_hook %p\n", sync_hook)); - } else { - bitblt_hook = NULL; - fillrect8_hook = NULL; - fillrect32_hook = NULL; - invrect_hook = NULL; - sync_hook = NULL; - } - - // The first time we got the screen, we need to init the Window - if (first) { - D(bug(" first time\n")); - first = false; - page_num = 0; // current display : page 0 - } else { // we get our screen back - D(bug(" not first time\n")); - // copy from backup bitmap to framebuffer - memcpy((void *)screen_base, frame_backup, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - // delete backup bitmap - delete[] frame_backup; - frame_backup = NULL; - // restore palette - if (info->bits_per_pixel == 8) - SetColorList(mac_pal); - // restart emul thread - release_sem(mac_os_lock); - } - - // allow the drawing in the frame buffer - D(bug(" enabling frame buffer access\n")); - drawing_enable = true; - video_activated = true; - - } else { - - drawing_enable = false; // stop drawing. - video_activated = false; - if (!quitting) { - // stop emul thread - acquire_sem(mac_os_lock); - // create bitmap and store frame buffer into - frame_backup = new uint8[VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize]; - memcpy(frame_backup, (void *)screen_base, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - } - } - D(bug("ScreenConnected() done\n")); -} - - -/* - * 60Hz interrupt routine - */ - -status_t MacScreen::tick_func(void *arg) -{ - MacScreen *obj = (MacScreen *)arg; - while (obj->tick_thread_active) { - - // Wait - snooze(16667); - - // Workspace activated? Then poll the mouse and change the palette if needed - if (video_activated) { - BPoint pt; - uint32 button = 0; - if (obj->LockWithTimeout(200000) == B_OK) { - if (obj->palette_changed) { - obj->palette_changed = false; - obj->SetColorList(mac_pal); - } - obj->view->GetMouse(&pt, &button); - obj->Unlock(); - set_mouse_position(320, 240); - ADBMouseMoved(int(pt.x) - 320, int(pt.y) - 240); - if (button & B_PRIMARY_MOUSE_BUTTON) - ADBMouseDown(0); - if (!(button & B_PRIMARY_MOUSE_BUTTON)) - ADBMouseUp(0); - if (button & B_SECONDARY_MOUSE_BUTTON) - ADBMouseDown(1); - if (!(button & B_SECONDARY_MOUSE_BUTTON)) - ADBMouseUp(1); - if (button & B_TERTIARY_MOUSE_BUTTON) - ADBMouseDown(2); - if (!(button & B_TERTIARY_MOUSE_BUTTON)) - ADBMouseUp(2); - } - } - } - return 0; -} diff --git a/SheepShaver/src/BeOS/video_window.h b/SheepShaver/src/BeOS/video_window.h deleted file mode 100644 index 60c4e1bf6..000000000 --- a/SheepShaver/src/BeOS/video_window.h +++ /dev/null @@ -1,523 +0,0 @@ -/* - * video_window.h - Window video modes - * - * SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - - -// Messages -static const uint32 MSG_REDRAW = 'draw'; -static const uint32 MSG_ABOUT_REQUESTED = B_ABOUT_REQUESTED; -static const uint32 MSG_REF_5HZ = ' 5Hz'; -static const uint32 MSG_REF_7_5HZ = ' 7Hz'; -static const uint32 MSG_REF_10HZ = '10Hz'; -static const uint32 MSG_REF_15HZ = '15Hz'; -static const uint32 MSG_REF_30HZ = '30Hz'; -static const uint32 MSG_REF_60HZ = '60Hz'; -static const uint32 MSG_MOUNT = 'moun'; - -static bool mouse_in_view; // Flag: Mouse pointer within bitmap view - -// From sys_beos.cpp -extern void SysCreateVolumeMenu(BMenu *menu, uint32 msg); -extern void SysMountVolume(const char *name); - - -/* - * A simple view class for blitting a bitmap on the screen - */ - -class BitmapView : public BView { -public: - BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "bitmap", B_FOLLOW_NONE, B_WILL_DRAW) - { - the_bitmap = bitmap; - } - virtual void Draw(BRect update) - { - if (the_bitmap) - DrawBitmap(the_bitmap, update, update); - } - virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); - -private: - BBitmap *the_bitmap; -}; - - -/* - * Window class - */ - -class MacWindow : public BDirectWindow { -public: - MacWindow(BRect frame); - virtual ~MacWindow(); - virtual void MessageReceived(BMessage *msg); - virtual void DirectConnected(direct_buffer_info *info); - virtual void WindowActivated(bool active); - - int32 frame_skip; - bool cursor_changed; // Flag: set new cursor image in tick function - -private: - static status_t tick_func(void *arg); - - BitmapView *main_view; - BBitmap *the_bitmap; - uint8 *the_buffer; - - uint32 old_scroll_lock_state; - - thread_id tick_thread; - bool tick_thread_active; - - bool supports_direct_mode; - bool bit_bang; - sem_id drawing_sem; - - color_space mode; - void *bits; - int32 bytes_per_row; - color_space pixel_format; - bool unclipped; -}; - - -// Pointer to our window -static MacWindow *the_window = NULL; - - -/* - * Window constructor - */ - -MacWindow::MacWindow(BRect frame) : BDirectWindow(frame, GetString(STR_WINDOW_TITLE), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE) -{ - D(bug("Window constructor\n")); - supports_direct_mode = SupportsWindowMode(); - cursor_changed = false; - bit_bang = supports_direct_mode && PrefsFindBool("bitbang"); - - // Move window to right position - Lock(); - MoveTo(80, 60); - - // Allocate bitmap - { - BScreen scr(this); - mode = B_COLOR_8_BIT; - switch (VModes[cur_mode].viAppleMode) { - case APPLE_8_BIT: - mode = B_COLOR_8_BIT; - bit_bang = false; - break; - case APPLE_16_BIT: - mode = B_RGB_16_BIT; - if (scr.ColorSpace() != B_RGB15_BIG && scr.ColorSpace() != B_RGBA15_BIG) - bit_bang = false; - break; - case APPLE_32_BIT: - mode = B_RGB_32_BIT; - if (scr.ColorSpace() != B_RGB32_BIG && scr.ColorSpace() != B_RGBA32_BIG) - bit_bang = false; - break; - } - } - if (bit_bang) { - the_bitmap = NULL; - the_buffer = NULL; - } else { - the_bitmap = new BBitmap(frame, mode); - the_buffer = new uint8[VModes[cur_mode].viRowBytes * (VModes[cur_mode].viYsize + 2)]; // ("height + 2" for safety) - screen_base = (uint32)the_buffer; - } - - // Create bitmap view - main_view = new BitmapView(frame, the_bitmap); - AddChild(main_view); - main_view->MakeFocus(); - - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - - // Set up menus - BRect bounds = Bounds(); - bounds.OffsetBy(0, bounds.IntegerHeight() + 1); - BMenuItem *item; - BMenuBar *bar = new BMenuBar(bounds, "menu"); - BMenu *menu = new BMenu(GetString(STR_WINDOW_MENU)); - menu->AddItem(new BMenuItem(GetString(STR_WINDOW_ITEM_ABOUT), new BMessage(MSG_ABOUT_REQUESTED))); - menu->AddItem(new BSeparatorItem); - BMenu *submenu = new BMenu(GetString(STR_WINDOW_ITEM_REFRESH)); - submenu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); - submenu->AddItem(new BMenuItem(GetString(STR_REF_60HZ_LAB), new BMessage(MSG_REF_60HZ))); - submenu->SetRadioMode(true); - if (frame_skip == 12) { - if ((item = submenu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 8) { - if ((item = submenu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 6) { - if ((item = submenu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 4) { - if ((item = submenu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 2) { - if ((item = submenu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) - item->SetMarked(true); - } else if (frame_skip == 1) { - if ((item = submenu->FindItem(GetString(STR_REF_60HZ_LAB))) != NULL) - item->SetMarked(true); - } - menu->AddItem(submenu); - submenu = new BMenu(GetString(STR_WINDOW_ITEM_MOUNT)); - SysCreateVolumeMenu(submenu, MSG_MOUNT); - menu->AddItem(submenu); - bar->AddItem(menu); - AddChild(bar); - SetKeyMenuBar(bar); - int mbar_height = bar->Frame().IntegerHeight() + 1; - - // Resize window to fit menu bar - ResizeBy(0, mbar_height); - - // Set mouse mode and scroll lock state - ADBSetRelMouseMode(false); - mouse_in_view = true; - old_scroll_lock_state = modifiers() & B_SCROLL_LOCK; - if (old_scroll_lock_state) - SetTitle(GetString(STR_WINDOW_TITLE_FROZEN)); - else - SetTitle(GetString(STR_WINDOW_TITLE)); - - // Clear Mac cursor image - memset(MacCursor + 4, 0, 64); - - // Keep window aligned to 8-byte frame buffer boundaries for faster blitting - SetWindowAlignment(B_BYTE_ALIGNMENT, 8); - - // Create drawing semaphore (for direct mode) - drawing_sem = create_sem(0, "direct frame buffer access"); - - // Start 60Hz interrupt - tick_thread_active = true; - tick_thread = spawn_thread(tick_func, "Window Redraw", B_DISPLAY_PRIORITY, this); - resume_thread(tick_thread); - - // Add filter for keyboard and mouse events - BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, filter_func); - main_view->AddFilter(filter); - - // Show window - Unlock(); - Show(); - Sync(); - D(bug("Window constructor done\n")); -} - - -/* - * Window destructor - */ - -MacWindow::~MacWindow() -{ - // Restore cursor - mouse_in_view = false; - be_app->SetCursor(B_HAND_CURSOR); - - // Hide window - D(bug("Window destructor, hiding window\n")); - Hide(); - Sync(); - - // Stop 60Hz interrupt - D(bug("Quitting tick thread\n")); - status_t l; - tick_thread_active = false; - delete_sem(drawing_sem); - while (wait_for_thread(tick_thread, &l) == B_INTERRUPTED) ; - D(bug("tick thread quit\n")); - - // dispose allocated memory - delete the_bitmap; - delete[] the_buffer; - - // Tell emulator that we're done - the_window = NULL; - D(bug("Window destructor done\n")); -} - - -/* - * Window connected/disconnected - */ - -void MacWindow::DirectConnected(direct_buffer_info *info) -{ - D(bug("DirectConnected, state %d\n", info->buffer_state)); - switch (info->buffer_state & B_DIRECT_MODE_MASK) { - case B_DIRECT_STOP: - acquire_sem(drawing_sem); - break; - case B_DIRECT_MODIFY: - acquire_sem(drawing_sem); - case B_DIRECT_START: - bits = (void *)((uint8 *)info->bits + info->window_bounds.top * info->bytes_per_row + info->window_bounds.left * info->bits_per_pixel / 8); - bytes_per_row = info->bytes_per_row; - pixel_format = info->pixel_format; - unclipped = false; - if (info->clip_list_count == 1) - if (memcmp(&info->clip_bounds, &info->window_bounds, sizeof(clipping_rect)) == 0) - unclipped = true; - if (bit_bang) { - screen_base = (uint32)bits; - VModes[cur_mode].viRowBytes = bytes_per_row; - } - release_sem(drawing_sem); - break; - } - D(bug("DirectConnected done\n")); -} - - -/* - * Handles redraw messages - */ - -void MacWindow::MessageReceived(BMessage *msg) -{ - BMessage *msg2; - - switch (msg->what) { - case MSG_REDRAW: { - - // Prevent backlog of messages - MessageQueue()->Lock(); - while ((msg2 = MessageQueue()->FindMessage(MSG_REDRAW, 0)) != NULL) { - MessageQueue()->RemoveMessage(msg2); - delete msg2; - } - MessageQueue()->Unlock(); - - // Convert Mac screen buffer to BeOS palette and blit - uint32 length = VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize; - if (mode == B_COLOR_8_BIT) { - // Palette conversion - uint8 *source = the_buffer - 1; - uint8 *dest = (uint8 *)the_bitmap->Bits() - 1; - for (int i=0; iBits() - 1; - for (int i=0; iBits() - 1; - for (int i=0; iDrawBitmapAsync(the_bitmap, update_rect, update_rect); - break; - } - - case MSG_ABOUT_REQUESTED: - OpenAboutWindow(); - break; - - case MSG_REF_5HZ: - PrefsReplaceInt32("frameskip", frame_skip = 12); - break; - - case MSG_REF_7_5HZ: - PrefsReplaceInt32("frameskip", frame_skip = 8); - break; - - case MSG_REF_10HZ: - PrefsReplaceInt32("frameskip", frame_skip = 6); - break; - - case MSG_REF_15HZ: - PrefsReplaceInt32("frameskip", frame_skip = 4); - break; - - case MSG_REF_30HZ: - PrefsReplaceInt32("frameskip", frame_skip = 2); - break; - - case MSG_REF_60HZ: - PrefsReplaceInt32("frameskip", frame_skip = 1); - break; - - case MSG_MOUNT: { - BMenuItem *source = NULL; - msg->FindPointer("source", (void **)&source); - if (source) - SysMountVolume(source->Label()); - break; - } - - default: - BDirectWindow::MessageReceived(msg); - } -} - - -/* - * Window activated/deactivated - */ - -void MacWindow::WindowActivated(bool active) -{ - video_activated = active; - if (active) - frame_skip = PrefsFindInt32("frameskip"); - else - frame_skip = 12; // 5Hz in background - BDirectWindow::WindowActivated(active); -} - - -/* - * 60Hz interrupt routine - */ - -status_t MacWindow::tick_func(void *arg) -{ - MacWindow *obj = (MacWindow *)arg; - static int tick_counter = 0; - while (obj->tick_thread_active) { - - // Wait - snooze(16667); - - // Refresh window - if (!obj->bit_bang) - tick_counter++; - if (tick_counter >= obj->frame_skip) { - tick_counter = 0; - - // Window title is determined by Scroll Lock state - uint32 scroll_lock_state = modifiers() & B_SCROLL_LOCK; - if (scroll_lock_state != obj->old_scroll_lock_state) { - if (scroll_lock_state) - obj->SetTitle(GetString(STR_WINDOW_TITLE_FROZEN)); - else - obj->SetTitle(GetString(STR_WINDOW_TITLE)); - obj->old_scroll_lock_state = scroll_lock_state; - } - - // Refresh display unless Scroll Lock is down - if (!scroll_lock_state) { - - // If direct frame buffer access is supported and the content area is completely visible, - // convert the Mac screen buffer directly. Otherwise, send a message to the window to do - // it into a bitmap - if (obj->supports_direct_mode) { - if (acquire_sem_etc(obj->drawing_sem, 1, B_TIMEOUT, 200000) == B_NO_ERROR) { - if (obj->unclipped && obj->mode == B_COLOR_8_BIT && obj->pixel_format == B_CMAP8) { - uint8 *source = obj->the_buffer - 1; - uint8 *dest = (uint8 *)obj->bits; - uint32 bytes_per_row = obj->bytes_per_row; - int xsize = VModes[cur_mode].viXsize; - int ysize = VModes[cur_mode].viYsize; - for (int y=0; yunclipped && obj->mode == B_RGB_16_BIT && (obj->pixel_format == B_RGB15_BIG || obj->pixel_format == B_RGBA15_BIG)) { - uint8 *source = obj->the_buffer; - uint8 *dest = (uint8 *)obj->bits; - uint32 sbpr = VModes[cur_mode].viRowBytes; - uint32 dbpr = obj->bytes_per_row; - int xsize = VModes[cur_mode].viXsize; - int ysize = VModes[cur_mode].viYsize; - for (int y=0; yunclipped && obj->mode == B_RGB_32_BIT && (obj->pixel_format == B_RGB32_BIG || obj->pixel_format == B_RGBA32_BIG)) { - uint8 *source = obj->the_buffer; - uint8 *dest = (uint8 *)obj->bits; - uint32 sbpr = VModes[cur_mode].viRowBytes; - uint32 dbpr = obj->bytes_per_row; - int xsize = VModes[cur_mode].viXsize; - int ysize = VModes[cur_mode].viYsize; - for (int y=0; yPostMessage(MSG_REDRAW); - release_sem(obj->drawing_sem); - } - } else - obj->PostMessage(MSG_REDRAW); - } - } - - // Set new cursor image if desired - if (obj->cursor_changed) { - if (mouse_in_view) - be_app->SetCursor(MacCursor); - obj->cursor_changed = false; - } - } - return 0; -} - - -/* - * Mouse moved - */ - -void BitmapView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - switch (transit) { - case B_ENTERED_VIEW: - mouse_in_view = true; - be_app->SetCursor(MacCursor); - break; - case B_EXITED_VIEW: - mouse_in_view = false; - be_app->SetCursor(B_HAND_CURSOR); - break; - } -} diff --git a/SheepShaver/src/BeOS/xpram_beos.cpp b/SheepShaver/src/BeOS/xpram_beos.cpp deleted file mode 120000 index e5d7f9658..000000000 --- a/SheepShaver/src/BeOS/xpram_beos.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/xpram_beos.cpp \ No newline at end of file diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index 5a470e6cb..94bb47862 100755 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -21,9 +21,7 @@ /* * NOTES: * - * See main_beos.cpp for a description of the three operating modes. - * - * In addition to that, we have to handle the fact that the MacOS ABI + * We have to handle the fact that the MacOS ABI * is slightly different from the SysV ABI used by Linux: * - Stack frames are different (e.g. LR is stored in 8(r1) under * MacOS, but in 4(r1) under Linux) @@ -41,7 +39,7 @@ * asm_linux.S that create a MacOS stack frame, load the TOC pointer * and put the arguments into the right registers. * - * As on the BeOS, we have to specify an alternate signal stack because + * We have to specify an alternate signal stack because * interrupts (and, under Linux, Low Memory accesses) may occur when r1 * is pointing to the Kernel Data or to Low Memory. There is one * problem, however, due to the alternate signal stack being global to @@ -607,7 +605,7 @@ static bool load_mac_rom(void) rom_tmp = new uint8[ROM_SIZE]; actual = read(rom_fd, (void *)rom_tmp, ROM_SIZE); close(rom_fd); - + // Decode Mac ROM if (!DecodeROM(rom_tmp, actual)) { if (rom_size != 4*1024*1024) { @@ -1015,7 +1013,7 @@ int main(int argc, char **argv) ErrorAlert(GetString(STR_RAM_AREA_TOO_HIGH_ERR)); goto quit; } - + // Create area for Mac ROM if (!ram_rom_areas_contiguous) { if (vm_mac_acquire_fixed(ROM_BASE, ROM_AREA_SIZE + SIG_STACK_SIZE) < 0) { @@ -1508,7 +1506,7 @@ void Set_pthread_attr(pthread_attr_t *attr, int priority) pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(attr, SCHED_FIFO); struct sched_param fifo_param; - fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) + + fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 + priority); pthread_attr_setschedparam(attr, &fifo_param); @@ -1534,7 +1532,7 @@ void Set_pthread_attr(pthread_attr_t *attr, int priority) #ifdef HAVE_PTHREADS struct B2_mutex { - B2_mutex() { + B2_mutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); // Initialize the mutex for priority inheritance -- @@ -1551,7 +1549,7 @@ struct B2_mutex { pthread_mutex_init(&m, &attr); pthread_mutexattr_destroy(&attr); } - ~B2_mutex() { + ~B2_mutex() { pthread_mutex_trylock(&m); // Make sure it's locked before pthread_mutex_unlock(&m); // unlocking it. pthread_mutex_destroy(&m); @@ -1711,7 +1709,7 @@ void sigusr2_handler(int sig, siginfo_t *sip, void *scp) // Set extra stack for SIGSEGV handler sigaltstack(&extra_stack, NULL); - + // Prepare for 68k interrupt level 1 WriteMacInt16(ReadMacInt32(0x67c), 1); WriteMacInt32(ReadMacInt32(0x658) + 0xdc, ReadMacInt32(ReadMacInt32(0x658) + 0xdc) | ReadMacInt32(0x674)); @@ -1782,7 +1780,7 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp) // Get effective address uint32 addr = r->dar(); - + #ifdef SYSTEM_CLOBBERS_R2 // Restore pointer to Thread Local Storage set_r2(TOC); @@ -1813,19 +1811,19 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp) r->pc() += 4; r->gpr(8) = 0; return; - + // MacOS 8.5 installation } else if (r->pc() == ROMBase + 0x488140 && r->gpr(16) == 0xf8000000) { r->pc() += 4; r->gpr(8) = 0; return; - + // MacOS 8 serial drivers on startup } else if (r->pc() == ROMBase + 0x48e080 && (r->gpr(8) == 0xf3012002 || r->gpr(8) == 0xf3012000)) { r->pc() += 4; r->gpr(8) = 0; return; - + // MacOS 8.1 serial drivers on startup } else if (r->pc() == ROMBase + 0x48c5e0 && (r->gpr(20) == 0xf3012002 || r->gpr(20) == 0xf3012000)) { r->pc() += 4; @@ -1833,7 +1831,7 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp) } else if (r->pc() == ROMBase + 0x4a10a0 && (r->gpr(20) == 0xf3012002 || r->gpr(20) == 0xf3012000)) { r->pc() += 4; return; - + // MacOS 8.6 serial drivers on startup (with DR Cache and OldWorld ROM) } else if ((r->pc() - DR_CACHE_BASE) < DR_CACHE_SIZE && (r->gpr(16) == 0xf3012002 || r->gpr(16) == 0xf3012000)) { r->pc() += 4; @@ -1904,7 +1902,7 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp) transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_UX; break; } break; - + case 32: // lwz transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; case 33: // lwzu @@ -1960,7 +1958,7 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp) break; #endif } - + // Ignore ROM writes (including to the zero page, which is read-only) if (transfer_type == TYPE_STORE && ((addr >= ROMBase && addr < ROMBase + ROM_SIZE) || diff --git a/SheepShaver/src/include/main.h b/SheepShaver/src/include/main.h index 787832dab..f2b4f2290 100644 --- a/SheepShaver/src/include/main.h +++ b/SheepShaver/src/include/main.h @@ -31,10 +31,6 @@ extern int64 CPUClockSpeed; // Processor clock speed (Hz) extern int64 BusClockSpeed; // Bus clock speed (Hz) extern int64 TimebaseSpeed; // Timebase clock speed (Hz) -#ifdef __BEOS__ -extern system_info SysInfo; // System information -#endif - // 68k register structure (for Execute68k()) struct M68kRegisters { uint32 d[8]; diff --git a/SheepShaver/src/include/prefs_editor.h b/SheepShaver/src/include/prefs_editor.h index 68b0326d8..689451691 100644 --- a/SheepShaver/src/include/prefs_editor.h +++ b/SheepShaver/src/include/prefs_editor.h @@ -21,10 +21,6 @@ #ifndef PREFS_EDITOR_H #define PREFS_EDITOR_H -#ifdef __BEOS__ -extern void PrefsEditor(uint32 msg); -#else extern bool PrefsEditor(void); -#endif #endif diff --git a/SheepShaver/src/rsrc_patches.cpp b/SheepShaver/src/rsrc_patches.cpp index 344b1bad5..ec6fcc2c4 100644 --- a/SheepShaver/src/rsrc_patches.cpp +++ b/SheepShaver/src/rsrc_patches.cpp @@ -626,7 +626,7 @@ void CheckLoad(uint32 type, const char *name, uint8 *p, uint32 size) if (type == FOURCC('D','R','V','R') && strncmp(&name[1], ".AFPTranslator", name[0]) == 0) { D(bug(" DRVR .AFPTranslator found\n")); - + // Don't access ROM85 as it it was a pointer to a ROM version number (8.0, 8.1) static const uint8 dat[] = {0x3a, 0x2e, 0x00, 0x0a, 0x55, 0x4f, 0x3e, 0xb8, 0x02, 0x8e, 0x30, 0x1f, 0x48, 0xc0, 0x24, 0x40, 0x20, 0x40}; base = find_rsrc_data(p, size, dat, sizeof(dat)); @@ -646,11 +646,7 @@ void CheckLoad(uint32 type, const char *name, uint8 *p, uint32 size) * Native Resource Manager patches */ -#ifdef __BEOS__ -static -#else extern "C" -#endif void check_load_invoc(uint32 type, int16 id, uint32 h) { if (h == 0) @@ -663,11 +659,7 @@ void check_load_invoc(uint32 type, int16 id, uint32 h) CheckLoad(type, id, (uint16 *)Mac2HostAddr(p), size); } -#ifdef __BEOS__ -static -#else extern "C" -#endif void named_check_load_invoc(uint32 type, uint32 name, uint32 h) { if (h == 0) @@ -680,238 +672,6 @@ void named_check_load_invoc(uint32 type, uint32 name, uint32 h) CheckLoad(type, (char *)Mac2HostAddr(name), Mac2HostAddr(p), size); } -#ifdef __BEOS__ -static asm void **get_resource(register uint32 type, register int16 id) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/ID - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_GET_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} - -static asm void **get_1_resource(register uint32 type, register int16 id) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/ID - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_GET_1_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} - -static asm void **get_ind_resource(register uint32 type, register int16 index) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/index - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_GET_IND_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} - -static asm void **get_1_ind_resource(register uint32 type, register int16 index) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/index - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_GET_1_IND_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} - -static asm void **r_get_resource(register uint32 type, register int16 id) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/ID - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_R_GET_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} - -static asm void **get_named_resource(register uint32 type, register uint32 name) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/ID - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_GET_NAMED_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl named_check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} - -static asm void **get_1_named_resource(register uint32 type, register uint32 name) -{ - // Create stack frame - mflr r0 - stw r0,8(r1) - stwu r1,-(56+12)(r1) - - // Save type/ID - stw r3,56(r1) - stw r4,56+4(r1) - - // Call old routine - lwz r0,XLM_GET_1_NAMED_RESOURCE - lwz r2,XLM_RES_LIB_TOC - mtctr r0 - bctrl - lwz r2,XLM_TOC // Get TOC - stw r3,56+8(r1) // Save handle - - // Call CheckLoad - lwz r3,56(r1) - lwz r4,56+4(r1) - lwz r5,56+8(r1) - bl named_check_load_invoc - lwz r3,56+8(r1) // Restore handle - - // Return to caller - lwz r0,56+12+8(r1) - mtlr r0 - addi r1,r1,56+12 - blr -} -#else // Routines in asm_linux.S extern "C" void get_resource(void); extern "C" void get_1_resource(void); @@ -920,7 +680,6 @@ extern "C" void get_1_ind_resource(void); extern "C" void r_get_resource(void); extern "C" void get_named_resource(void); extern "C" void get_1_named_resource(void); -#endif void PatchNativeResourceManager(void) { @@ -936,14 +695,8 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_GET_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_GET_RESOURCE)); -#else -#ifdef __BEOS__ - uint32 *tvec2 = (uint32 *)get_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)get_resource); -#endif #endif // Patch native Get1Resource() @@ -953,14 +706,8 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_GET_1_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_GET_1_RESOURCE)); -#else -#ifdef __BEOS__ - tvec2 = (uint32 *)get_1_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)get_1_resource); -#endif #endif // Patch native GetIndResource() @@ -970,14 +717,8 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_GET_IND_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_GET_IND_RESOURCE)); -#else -#ifdef __BEOS__ - tvec2 = (uint32 *)get_ind_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)get_ind_resource); -#endif #endif // Patch native Get1IndResource() @@ -987,14 +728,8 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_GET_1_IND_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_GET_1_IND_RESOURCE)); -#else -#ifdef __BEOS__ - tvec2 = (uint32 *)get_1_ind_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)get_1_ind_resource); -#endif #endif // Patch native RGetResource() @@ -1004,14 +739,8 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_R_GET_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_R_GET_RESOURCE)); -#else -#ifdef __BEOS__ - tvec2 = (uint32 *)r_get_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)r_get_resource); -#endif #endif // Patch native GetNamedResource() @@ -1021,14 +750,8 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_GET_NAMED_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_GET_NAMED_RESOURCE)); -#else -#ifdef __BEOS__ - tvec2 = (uint32 *)get_named_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)get_named_resource); -#endif #endif // Patch native Get1NamedResource() @@ -1038,13 +761,7 @@ void PatchNativeResourceManager(void) WriteMacInt32(XLM_GET_1_NAMED_RESOURCE, ReadMacInt32(tvec)); #if EMULATED_PPC WriteMacInt32(tvec, NativeFunction(NATIVE_GET_1_NAMED_RESOURCE)); -#else -#ifdef __BEOS__ - tvec2 = (uint32 *)get_1_named_resource; - WriteMacInt32(tvec, tvec2[0]); - WriteMacInt32(tvec + 4, tvec2[1]); #else WriteMacInt32(tvec, (uint32)get_1_named_resource); #endif -#endif } diff --git a/SheepShaver/src/thunks.cpp b/SheepShaver/src/thunks.cpp index f8a1b64a5..9deb7c8bb 100644 --- a/SheepShaver/src/thunks.cpp +++ b/SheepShaver/src/thunks.cpp @@ -289,12 +289,6 @@ bool ThunksInit(void) native_op[ID].tvect = base; \ native_op[ID].func = (uint32)FUNC; \ } while (0) -#elif defined(__BEOS__) -#define DEFINE_NATIVE_OP(ID, FUNC) do { \ - native_op[ID].tvect = FUNC; \ - native_op[ID].func = ((uint32 *)FUNC)[0]; \ - } while (0) -#else #error "FIXME: define NativeOp for your platform" #endif // FIXME: add GetResource() and friends for completeness diff --git a/SheepShaver/src/user_strings.cpp b/SheepShaver/src/user_strings.cpp index c29f7cffd..d88025cd0 100644 --- a/SheepShaver/src/user_strings.cpp +++ b/SheepShaver/src/user_strings.cpp @@ -33,11 +33,7 @@ #include "sysdeps.h" #include "user_strings.h" -#ifdef __BEOS__ -#define ELLIPSIS "\xE2\x80\xA6" -#else #define ELLIPSIS "..." -#endif // Common string definitions diff --git a/SheepShaver/src/video.cpp b/SheepShaver/src/video.cpp index 66fecb8dc..bcdeb3601 100644 --- a/SheepShaver/src/video.cpp +++ b/SheepShaver/src/video.cpp @@ -111,10 +111,10 @@ static int16 set_gamma(VidLocals *csSave, uint32 gamma); /* * Tell whether window/screen is activated or not (for mouse/keyboard polling) */ - + bool VideoActivated(void) { - return video_activated; + return video_activated; } @@ -126,7 +126,7 @@ bool VideoSnapshot(int xsize, int ysize, uint8 *p) { if (display_type == DIS_WINDOW) { uint8 *screen = (uint8 *)private_data->saveBaseAddr; - uint32 row_bytes = VModes[cur_mode].viRowBytes; + uint32 row_bytes = VModes[cur_mode].viRowBytes; uint32 y2size = VModes[cur_mode].viYsize; uint32 x2size = VModes[cur_mode].viXsize; for (int j=0;j APPLE_8_BIT) return controlErr; uint32 s_pal = ReadMacInt32(param + csTable); uint16 start = ReadMacInt16(param + csStart); @@ -338,12 +338,8 @@ static int16 VideoControl(uint32 pb, VidLocals *csSave) uint8 *blue_gamma = NULL; int gamma_data_width = 0; if (csSave->gammaTable) { -#ifdef __BEOS__ - // Windows are gamma-corrected by BeOS - const bool can_do_gamma = (display_type == DIS_SCREEN); -#else + // Leave open the possibility of OS-specific provision of gamma correction const bool can_do_gamma = true; -#endif if (can_do_gamma) { uint32 gamma_table = csSave->gammaTable; red_gamma = Mac2HostAddr(gamma_table + gFormulaData + ReadMacInt16(gamma_table + gFormulaSize)); @@ -675,7 +671,7 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave) return noErr; case cscGetEntries: { // GetEntries - D(bug("GetEntries\n")); + D(bug("GetEntries\n")); uint32 d_pal = ReadMacInt32(param + csTable); uint16 start = ReadMacInt16(param + csStart); uint16 count = ReadMacInt16(param + csCount); @@ -750,7 +746,7 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave) WriteMacInt32(param + csData, csSave->saveData); WriteMacInt16(param + csPage, csSave->savePage); WriteMacInt32(param + csBaseAddr, csSave->saveBaseAddr); - + D(bug("return: mode:%04x ID:%08lx page:%04x ", ReadMacInt16(param + csMode), ReadMacInt32(param + csData), ReadMacInt16(param + csPage))); D(bug("base adress %08lx\n", ReadMacInt32(param + csBaseAddr))); @@ -865,7 +861,7 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave) ReadMacInt32(param + csDisplayModeID), ReadMacInt16(param + csDepthMode))); - // find right video mode + // find right video mode for (int i=0; VModes[i].viType!=DIS_INVALID; i++) { if ((ReadMacInt16(param + csDepthMode) == VModes[i].viAppleMode) && (ReadMacInt32(param + csDisplayModeID) == VModes[i].viAppleID)) { @@ -884,42 +880,42 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave) WriteMacInt32(vpb + vpVRes, 0x00480000); // vert res of the device (ppi) switch (VModes[i].viAppleMode) { case APPLE_1_BIT: - WriteMacInt16(vpb + vpPixelType, 0); + WriteMacInt16(vpb + vpPixelType, 0); WriteMacInt16(vpb + vpPixelSize, 1); WriteMacInt16(vpb + vpCmpCount, 1); WriteMacInt16(vpb + vpCmpSize, 1); WriteMacInt32(param + csDeviceType, 0); // CLUT break; case APPLE_2_BIT: - WriteMacInt16(vpb + vpPixelType, 0); + WriteMacInt16(vpb + vpPixelType, 0); WriteMacInt16(vpb + vpPixelSize, 2); WriteMacInt16(vpb + vpCmpCount, 1); WriteMacInt16(vpb + vpCmpSize, 2); WriteMacInt32(param + csDeviceType, 0); // CLUT break; case APPLE_4_BIT: - WriteMacInt16(vpb + vpPixelType, 0); + WriteMacInt16(vpb + vpPixelType, 0); WriteMacInt16(vpb + vpPixelSize, 4); WriteMacInt16(vpb + vpCmpCount, 1); WriteMacInt16(vpb + vpCmpSize, 4); WriteMacInt32(param + csDeviceType, 0); // CLUT break; case APPLE_8_BIT: - WriteMacInt16(vpb + vpPixelType, 0); + WriteMacInt16(vpb + vpPixelType, 0); WriteMacInt16(vpb + vpPixelSize, 8); WriteMacInt16(vpb + vpCmpCount, 1); WriteMacInt16(vpb + vpCmpSize, 8); WriteMacInt32(param + csDeviceType, 0); // CLUT break; case APPLE_16_BIT: - WriteMacInt16(vpb + vpPixelType, 0x10); + WriteMacInt16(vpb + vpPixelType, 0x10); WriteMacInt16(vpb + vpPixelSize, 16); WriteMacInt16(vpb + vpCmpCount, 3); WriteMacInt16(vpb + vpCmpSize, 5); WriteMacInt32(param + csDeviceType, 2); // DIRECT break; case APPLE_32_BIT: - WriteMacInt16(vpb + vpPixelType, 0x10); + WriteMacInt16(vpb + vpPixelType, 0x10); WriteMacInt16(vpb + vpPixelSize, 32); WriteMacInt16(vpb + vpCmpCount, 3); WriteMacInt16(vpb + vpCmpSize, 8); From 7e845b6ea2569c18800b33c81eccb609087da8c3 Mon Sep 17 00:00:00 2001 From: Seg Date: Wed, 16 Dec 2020 18:14:25 -0800 Subject: [PATCH 08/24] Remove real 68k support --- BasiliskII/src/CrossPlatform/sigsegv.cpp | 4 - BasiliskII/src/CrossPlatform/video_blit.cpp | 5 +- BasiliskII/src/CrossPlatform/video_vosf.h | 8 +- BasiliskII/src/MacOSX/PrefsEditor.mm | 2 +- BasiliskII/src/MacOSX/config.h | 3 - BasiliskII/src/MacOSX/main_macosx.mm | 63 +- BasiliskII/src/MacOSX/video_macosx.mm | 2 +- BasiliskII/src/Unix/configure.ac | 92 +-- BasiliskII/src/Unix/main_unix.cpp | 536 +----------------- BasiliskII/src/Unix/prefs_editor_gtk.cpp | 2 - BasiliskII/src/Unix/sysdeps.h | 28 +- BasiliskII/src/Unix/video_x.cpp | 10 +- BasiliskII/src/Windows/main_windows.cpp | 5 - BasiliskII/src/Windows/prefs_editor_gtk.cpp | 2 - BasiliskII/src/Windows/sysdeps.h | 14 +- BasiliskII/src/ether.cpp | 2 - BasiliskII/src/include/ether.h | 8 +- BasiliskII/src/main.cpp | 4 - BasiliskII/src/native_cpu/cpu_emulation.h | 67 --- BasiliskII/src/rom_patches.cpp | 18 +- BasiliskII/src/uae_cpu/basilisk_glue.cpp | 17 +- .../src/uae_cpu/compiler/compemu_support.cpp | 10 +- BasiliskII/src/uae_cpu/cpu_emulation.h | 4 +- BasiliskII/src/uae_cpu/memory.cpp | 4 +- BasiliskII/src/uae_cpu/memory.h | 12 +- BasiliskII/src/uae_cpu/newcpu.cpp | 2 +- BasiliskII/src/uae_cpu/newcpu.h | 4 +- 27 files changed, 47 insertions(+), 881 deletions(-) delete mode 100644 BasiliskII/src/native_cpu/cpu_emulation.h diff --git a/BasiliskII/src/CrossPlatform/sigsegv.cpp b/BasiliskII/src/CrossPlatform/sigsegv.cpp index 10a781713..fd440c85f 100755 --- a/BasiliskII/src/CrossPlatform/sigsegv.cpp +++ b/BasiliskII/src/CrossPlatform/sigsegv.cpp @@ -2924,10 +2924,6 @@ static bool sigsegv_do_install_handler(int sig) sigemptyset(&sigsegv_sa.sa_mask); sigsegv_sa.sa_handler = (signal_handler)sigsegv_handler; sigsegv_sa.sa_flags = 0; -#if !EMULATED_68K && defined(__NetBSD__) - sigaddset(&sigsegv_sa.sa_mask, SIGALRM); - sigsegv_sa.sa_flags |= SA_ONSTACK; -#endif return (sigaction(sig, &sigsegv_sa, 0) == 0); #else return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR); diff --git a/BasiliskII/src/CrossPlatform/video_blit.cpp b/BasiliskII/src/CrossPlatform/video_blit.cpp index 2d7e534d9..eab372241 100755 --- a/BasiliskII/src/CrossPlatform/video_blit.cpp +++ b/BasiliskII/src/CrossPlatform/video_blit.cpp @@ -516,14 +516,13 @@ static Screen_blit_func_info Screen_blitters[] = { // Initialize the framebuffer update function // Returns FALSE, if the function was to be reduced to a simple memcpy() // --> In that case, VOSF is not necessary -bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_order, int mac_depth) -{ +bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_order, int mac_depth){ #if USE_SDL_VIDEO const bool use_sdl_video = true; #else const bool use_sdl_video = false; #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING || USE_SDL_VIDEO +#if DIRECT_ADDRESSING || USE_SDL_VIDEO if (mac_depth == 1 && !use_sdl_video && !visual_format.fullscreen) { // Windowed 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines diff --git a/BasiliskII/src/CrossPlatform/video_vosf.h b/BasiliskII/src/CrossPlatform/video_vosf.h index f1d2f3add..0c182925c 100644 --- a/BasiliskII/src/CrossPlatform/video_vosf.h +++ b/BasiliskII/src/CrossPlatform/video_vosf.h @@ -535,14 +535,12 @@ static void update_display_window_vosf(VIDEO_DRV_WIN_INIT) /* * Update display for DGA mode and VOSF - * (only in Real or Direct Addressing mode) + * (only in Direct Addressing mode) */ #ifndef TEST_VOSF_PERFORMANCE -#if REAL_ADDRESSING || DIRECT_ADDRESSING - -static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) -{ +#if DIRECT_ADDRESSING +static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT){ VIDEO_MODE_INIT; // Compute number of bytes per row, take care to virtual screens diff --git a/BasiliskII/src/MacOSX/PrefsEditor.mm b/BasiliskII/src/MacOSX/PrefsEditor.mm index 1b9cd13a6..06af5382f 100644 --- a/BasiliskII/src/MacOSX/PrefsEditor.mm +++ b/BasiliskII/src/MacOSX/PrefsEditor.mm @@ -763,7 +763,7 @@ - (IBAction) ShowPrefs: (id)sender cpu = PrefsFindInt32("cpu"); val = PrefsFindInt32("modelid"); -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING puts("Current memory model does not support 24bit addressing"); if ( val == [classic tag] ) { diff --git a/BasiliskII/src/MacOSX/config.h b/BasiliskII/src/MacOSX/config.h index e0b4671a1..a6dde88ce 100644 --- a/BasiliskII/src/MacOSX/config.h +++ b/BasiliskII/src/MacOSX/config.h @@ -31,9 +31,6 @@ /* Define if using "mon". */ /* #undef ENABLE_MON */ -/* Define if using native 68k mode. */ -/* #undef ENABLE_NATIVE_M68K */ - /* Define to 1 if translation of program messages to the user's native language is requested. */ /* #undef ENABLE_NLS */ diff --git a/BasiliskII/src/MacOSX/main_macosx.mm b/BasiliskII/src/MacOSX/main_macosx.mm index b14a2ede4..b226e93bd 100644 --- a/BasiliskII/src/MacOSX/main_macosx.mm +++ b/BasiliskII/src/MacOSX/main_macosx.mm @@ -32,7 +32,7 @@ # include #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # include #endif @@ -107,11 +107,6 @@ static void sigint_handler(...); #endif -#if REAL_ADDRESSING -static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped -#endif - - /* * Helpers to map memory that can be accessed from the Mac side */ @@ -334,58 +329,14 @@ bool InitEmulator (void) if (RAMSize > 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) RAMSize = 1023*1024*1024; -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING RAMSize = RAMSize & -getpagesize(); // Round down to page boundary #endif // Initialize VM system vm_init(); -#if REAL_ADDRESSING - // Flag: RAM and ROM are contigously allocated from address 0 - bool memory_mapped_from_zero = false; - - // Make sure to map RAM & ROM at address 0 only on platforms that - // supports linker scripts to relocate the Basilisk II executable - // above 0x70000000 -#if HAVE_LINKER_SCRIPT - const bool can_map_all_memory = true; -#else - const bool can_map_all_memory = false; -#endif - - // Try to allocate all memory from 0x0000, if it is not known to crash - if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) { - D(bug("Could allocate RAM and ROM from 0x0000\n")); - memory_mapped_from_zero = true; - } - -#ifndef PAGEZERO_HACK - // Otherwise, just create the Low Memory area (0x0000..0x2000) - else if (vm_acquire_mac_fixed(0, 0x2000) == 0) { - D(bug("Could allocate the Low Memory globals\n")); - lm_area_mapped = true; - } - - // Exit on failure - else { - sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } -#endif -#else - *str = 0; // Eliminate unused variable warning -#endif /* REAL_ADDRESSING */ - // Create areas for Mac RAM and ROM -#if REAL_ADDRESSING - if (memory_mapped_from_zero) { - RAMBaseHost = (uint8 *)0; - ROMBaseHost = RAMBaseHost + RAMSize; - } - else -#endif { uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); if (ram_rom_area == VM_MAP_FAILED) { @@ -411,10 +362,6 @@ bool InitEmulator (void) MEMBaseDiff = (uintptr)RAMBaseHost; RAMBaseMac = 0; ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif -#if REAL_ADDRESSING - RAMBaseMac = Host2MacAddr(RAMBaseHost); - ROMBaseMac = Host2MacAddr(ROMBaseHost); #endif D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); @@ -498,12 +445,6 @@ void QuitEmuNoExit() } #endif -#if REAL_ADDRESSING - // Delete Low Memory area - if (lm_area_mapped) - vm_release(0, 0x2000); -#endif - // Exit VM wrappers vm_exit(); diff --git a/BasiliskII/src/MacOSX/video_macosx.mm b/BasiliskII/src/MacOSX/video_macosx.mm index 026ae2c85..991483367 100644 --- a/BasiliskII/src/MacOSX/video_macosx.mm +++ b/BasiliskII/src/MacOSX/video_macosx.mm @@ -409,7 +409,7 @@ static void mask_buffer (void *buffer, size_t width, size_t size) void OSX_monitor::set_mac_frame_buffer(const video_mode mode) { -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING +#if !DIRECT_ADDRESSING set_mac_frame_base(MacFrameBaseMac); // Set variables used by UAE memory banking diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 1e8b2c2f8..3b834bb92 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -61,11 +61,10 @@ dnl Addressing modes. AC_ARG_ENABLE(addressing, [ --enable-addressing=AM specify the addressing mode to use [default=fastest]], [ case "$enableval" in - real) ADDRESSING_TEST_ORDER="real";; direct) ADDRESSING_TEST_ORDER="direct";; banks) ADDRESSING_TEST_ORDER="banks";; fastest)ADDRESSING_TEST_ORDER="direct banks";; - *) AC_MSG_ERROR([--enable-addressing takes only one of the following values: fastest, real, direct, banks]);; + *) AC_MSG_ERROR([--enable-addressing takes only one of the following values: fastest, direct, banks]);; esac ], [ ADDRESSING_TEST_ORDER="direct banks" @@ -127,11 +126,6 @@ if [[ "x$BII_CROSS_MPROTECT_WORKS" = "x" ]]; then BII_CROSS_MPROTECT_WORKS="guessing no" fi -AC_ARG_VAR(BII_CROSS_MAP_LOW_AREA, [ Whether the target system can map 0x2000 bytes from 0x0000 [default=guessing no]]) -if [[ "x$BII_CROSS_MAP_LOW_AREA" = "x" ]]; then - BII_CROSS_MAP_LOW_AREA="guessing no" -fi - AC_ARG_VAR(BII_CROSS_SIGNAL_NEED_REINSTALL, [ Whether the target system needs signal handlers to be reinstalled [default=guessing yes]]) if [[ "x$BII_CROSS_SIGNAL_NEED_REINSTALL" = "x" ]]; then BII_CROSS_SIGNAL_NEED_REINSTALL="guessing yes" @@ -189,13 +183,11 @@ DEFINES="$DEFINES -DOS_$OS_TYPE" dnl Target CPU type. HAVE_I386=no -HAVE_M68K=no HAVE_SPARC=no HAVE_POWERPC=no HAVE_X86_64=no case "$target_cpu" in i386* | i486* | i586* | i686* | i786* ) HAVE_I386=yes;; - m68k* ) HAVE_M68K=yes;; sparc* ) HAVE_SPARC=yes;; powerpc* ) HAVE_POWERPC=yes;; x86_64* | amd64* ) HAVE_X86_64=yes;; @@ -735,7 +727,6 @@ SCSISRC=../dummy/scsi_dummy.cpp AUDIOSRC=../dummy/audio_dummy.cpp EXTFSSRC=extfs_unix.cpp EXTRASYSSRCS= -CAN_NATIVE_M68K=no case "$target_os" in linux*) ETHERSRC=ether_unix.cpp @@ -766,7 +757,6 @@ freebsd*) fi ;; netbsd*) - CAN_NATIVE_M68K=yes ETHERSRC=ether_unix.cpp ;; solaris*) @@ -916,14 +906,6 @@ if [[ "x$have_libvhd" = "xyes" ]]; then EXTRASYSSRCS="$EXTRASYSSRCS vhd_unix.cpp" fi - -dnl Use 68k CPU natively? -WANT_NATIVE_M68K=no -if [[ "x$HAVE_M68K" = "xyes" -a "x$CAN_NATIVE_M68K" = "xyes" ]]; then - AC_DEFINE(ENABLE_NATIVE_M68K, 1, [Define if using native 68k mode.]) - WANT_NATIVE_M68K=yes -fi - if [[ "x$HAVE_PTHREADS" = "xno" ]]; then dnl Serial, ethernet and audio support needs pthreads AC_MSG_WARN([You don't have pthreads, disabling serial, ethernet and audio support.]) @@ -1116,42 +1098,6 @@ AC_TRANSLATE_DEFINE(HAVE_MMAP_VM, "$have_mmap_vm", fi dnl HAVE_MMAP_VM -dnl Check if we can modify the __PAGEZERO segment for use as Low Memory -AC_CACHE_CHECK([whether __PAGEZERO can be Low Memory area 0x0000-0x2000], - ac_cv_pagezero_hack, [ - ac_cv_pagezero_hack=no - if AC_TRY_COMMAND([Darwin/testlmem.sh 0x2000]); then - ac_cv_pagezero_hack=yes - dnl might as well skip the test for mmap-able low memory - ac_cv_can_map_lm=no - fi -]) -AC_TRANSLATE_DEFINE(PAGEZERO_HACK, "$ac_cv_pagezero_hack", - [Define if the __PAGEZERO Mach-O Low Memory Globals hack works on this system.]) - -dnl Check if we can mmap 0x2000 bytes from 0x0000 -AC_CACHE_CHECK([whether we can map Low Memory area 0x0000-0x2000], - ac_cv_can_map_lm, [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_RUN([ - #include "../CrossPlatform/vm_alloc.cpp" - int main(void) { /* returns 0 if we could map the lowmem globals */ - volatile char * lm = 0; - if (vm_init() < 0) exit(1); - if (vm_acquire_fixed(0, 0x2000) < 0) exit(1); - lm[0] = 'z'; - if (vm_release((char *)lm, 0x2000) < 0) exit(1); - vm_exit(); exit(0); - } - ], ac_cv_can_map_lm=yes, ac_cv_can_map_lm=no, - dnl When cross-compiling, do not assume anything. - ac_cv_can_map_lm="$BII_CROSS_MAP_LOW_AREA" - ) - AC_LANG_RESTORE - ] -) - dnl Check signal handlers need to be reinstalled AC_CACHE_CHECK([whether signal handlers need to be reinstalled], ac_cv_signal_need_reinstall, [ @@ -1417,32 +1363,10 @@ AC_TRANSLATE_DEFINE(HAVE_LINKER_SCRIPT, "$ac_cv_linker_script_works", [Define if there is a linker script to relocate the executable above 0x70000000.]) dnl Determine the addressing mode to use -if [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then - ADDRESSING_MODE="real" -else ADDRESSING_MODE="" AC_MSG_CHECKING([for the addressing mode to use]) for am in $ADDRESSING_TEST_ORDER; do case $am in - real) - dnl Requires ability to mmap() Low Memory globals - if [[ "x$ac_cv_can_map_lm$ac_cv_pagezero_hack" = "xnono" ]]; then - continue - fi - dnl Requires VOSF screen updates - if [[ "x$CAN_VOSF" = "xno" ]]; then - continue - fi - dnl Real addressing will probably work. - ADDRESSING_MODE="real" - WANT_VOSF=yes dnl we can use VOSF and we need it actually - DEFINES="$DEFINES -DREAL_ADDRESSING" - if [[ "x$ac_cv_pagezero_hack" = "xyes" ]]; then - BLESS=Darwin/lowmem - LDFLAGS="$LDFLAGS -pagezero_size 0x2000" - fi - break - ;; direct) dnl Requires VOSF screen updates if [[ "x$CAN_VOSF" = "xyes" ]]; then @@ -1466,7 +1390,6 @@ else AC_MSG_WARN([Sorry, no suitable addressing mode in $ADDRESSING_TEST_ORDER]) ADDRESSING_MODE="memory banks" fi -fi dnl Banked Memory Addressing mode is not supported by the JIT compiler if [[ "x$WANT_JIT" = "xyes" -a "x$ADDRESSING_MODE" = "xmemory banks" ]]; then @@ -1645,10 +1568,6 @@ elif [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_SPARC" = "xyes" -a "x$HAVE_GAS" = "xy esac ;; esac -elif [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then - dnl Native m68k, no emulation - CPUINCLUDES="-I../native_cpu" - CPUSRCS="asm_support.s" fi dnl Enable JIT compiler, if possible. @@ -1866,11 +1785,9 @@ dnl Check for certain math functions AC_CHECK_FUNCS(atanh) AC_CHECK_FUNCS(isnan isinf finite isnormal signbit) -dnl UAE CPU sources for all non-m68k-native architectures. -if [[ "x$WANT_NATIVE_M68K" = "xno" ]]; then - CPUINCLUDES="-I../uae_cpu" - CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS" -fi +dnl UAE CPU sources for all architectures. +CPUINCLUDES="-I../uae_cpu" +CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS" dnl Or if we have -IPA (MIPSPro compilers) if [[ "x$HAVE_IPA" = "xyes" ]]; then @@ -1908,7 +1825,6 @@ echo Enable video on SEGV signals ........... : $WANT_VOSF echo ESD sound support ...................... : $WANT_ESD echo GTK user interface ..................... : $WANT_GTK echo mon debugger support ................... : $WANT_MON -echo Running m68k code natively ............. : $WANT_NATIVE_M68K echo Use JIT compiler ....................... : $WANT_JIT echo JIT debug mode ......................... : $WANT_JIT_DEBUG echo Floating-Point emulation core .......... : $FPE_CORE diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index b0a9c2c14..a1d9b7964 100755 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -39,24 +39,10 @@ # include #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # include #endif -#if !EMULATED_68K && defined(__NetBSD__) -# include -# include -# include -# include -struct sigstate { - int ss_flags; - struct frame ss_frame; - struct fpframe ss_fpstate; -}; -# define SS_FPSTATE 0x02 -# define SS_USERREGS 0x04 -#endif - #ifdef ENABLE_GTK # include # include @@ -109,26 +95,10 @@ extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_suppo #define DEBUG 0 #include "debug.h" - // Constants const char ROM_FILE_NAME[] = "ROM"; -#if !EMULATED_68K -const int SIG_STACK_SIZE = SIGSTKSZ; // Size of signal stack -#endif const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area - -#if !EMULATED_68K -// RAM and ROM pointers -uint32 RAMBaseMac; // RAM base (Mac address space) -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM -#endif - - // CPU and FPU type, addressing mode int CPUType; bool CPUIs68060; @@ -148,10 +118,6 @@ X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT; // X11 display lock static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes #ifdef HAVE_PTHREADS -#if !EMULATED_68K -static pthread_t emul_thread; // Handle of MacOS emulation thread (main thread) -#endif - static bool xpram_thread_active = false; // Flag: XPRAM watchdog installed static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread static pthread_t xpram_thread; // XPRAM watchdog @@ -172,14 +138,6 @@ static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to pro #endif -#if !EMULATED_68K -#define SIG_IRQ SIGUSR1 -static struct sigaction sigirq_sa; // Virtual 68k interrupt signal -static struct sigaction sigill_sa; // Illegal instruction -static void *sig_stack = NULL; // Stack for signal handlers -uint16 EmulatedSR; // Emulated bits of SR (supervisor bit and interrupt mask) -#endif - #if USE_SCRATCHMEM_SUBTERFUGE uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes #endif @@ -198,10 +156,6 @@ static struct sigaction sigint_sa; // sigaction for SIGINT handler static void sigint_handler(...); #endif -#if REAL_ADDRESSING -static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped -#endif - static rpc_connection_t *gui_connection = NULL; // RPC connection to the GUI static const char *gui_connection_path = NULL; // GUI connection identifier @@ -210,11 +164,6 @@ static const char *gui_connection_path = NULL; // GUI connection identifier static void *xpram_func(void *arg); static void *tick_func(void *arg); static void one_tick(...); -#if !EMULATED_68K -static void sigirq_handler(int sig, int code, struct sigcontext *scp); -static void sigill_handler(int sig, int code, struct sigcontext *scp); -extern "C" void EmulOpTrampoline(void); -#endif // vde switch variable char* vde_sock; @@ -292,7 +241,6 @@ static void sigsegv_dump_state(sigsegv_info_t *sip) if (fault_instruction != SIGSEGV_INVALID_ADDRESS) fprintf(stderr, " [IP=%p]", fault_instruction); fprintf(stderr, "\n"); -#if EMULATED_68K uaecptr nextpc; #ifdef UPDATE_UAE extern void m68k_dumpstate(FILE *, uaecptr *nextpc); @@ -301,7 +249,6 @@ static void sigsegv_dump_state(sigsegv_info_t *sip) extern void m68k_dumpstate(uaecptr *nextpc); m68k_dumpstate(&nextpc); #endif -#endif #if USE_JIT && JIT_DEBUG extern void compiler_dumpstate(void); compiler_dumpstate(); @@ -606,56 +553,14 @@ int main(int argc, char **argv) if (RAMSize > 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) RAMSize = 1023*1024*1024; -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING RAMSize = RAMSize & -getpagesize(); // Round down to page boundary #endif // Initialize VM system vm_init(); -#if REAL_ADDRESSING - // Flag: RAM and ROM are contigously allocated from address 0 - bool memory_mapped_from_zero = false; - - // Make sure to map RAM & ROM at address 0 only on platforms that - // supports linker scripts to relocate the Basilisk II executable - // above 0x70000000 -#if HAVE_LINKER_SCRIPT - const bool can_map_all_memory = true; -#else - const bool can_map_all_memory = false; -#endif - - // Try to allocate all memory from 0x0000, if it is not known to crash - if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) { - D(bug("Could allocate RAM and ROM from 0x0000\n")); - memory_mapped_from_zero = true; - } - -#ifndef PAGEZERO_HACK - // Otherwise, just create the Low Memory area (0x0000..0x2000) - else if (vm_acquire_mac_fixed(0, 0x2000) == 0) { - D(bug("Could allocate the Low Memory globals\n")); - lm_area_mapped = true; - } - - // Exit on failure - else { - sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } -#endif -#endif /* REAL_ADDRESSING */ - // Create areas for Mac RAM and ROM -#if REAL_ADDRESSING - if (memory_mapped_from_zero) { - RAMBaseHost = (uint8 *)0; - ROMBaseHost = RAMBaseHost + RAMSize; - } - else -#endif { uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); if (ram_rom_area == VM_MAP_FAILED) { @@ -682,10 +587,6 @@ int main(int argc, char **argv) RAMBaseMac = 0; ROMBaseMac = Host2MacAddr(ROMBaseHost); #endif -#if REAL_ADDRESSING - RAMBaseMac = Host2MacAddr(RAMBaseHost); - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif #if __MACOSX__ extern void set_current_directory(); @@ -715,35 +616,6 @@ int main(int argc, char **argv) QuitEmulator(); } -#if !EMULATED_68K - // Get CPU model - int mib[2] = {CTL_HW, HW_MODEL}; - char *model; - size_t model_len; - sysctl(mib, 2, NULL, &model_len, NULL, 0); - model = (char *)malloc(model_len); - sysctl(mib, 2, model, &model_len, NULL, 0); - D(bug("Model: %s\n", model)); - - // Set CPU and FPU type - CPUIs68060 = false; - if (strstr(model, "020")) - CPUType = 2; - else if (strstr(model, "030")) - CPUType = 3; - else if (strstr(model, "040")) - CPUType = 4; - else if (strstr(model, "060")) { - CPUType = 4; - CPUIs68060 = true; - } else { - printf("WARNING: Cannot detect CPU type, assuming 68020\n"); - CPUType = 2; - } - FPUType = 1; // NetBSD has an FPU emulation, so the FPU ought to be available at all times - TwentyFourBitAddressing = false; -#endif - // Initialize everything if (!InitAll(vmdir)) QuitEmulator(); @@ -752,57 +624,6 @@ int main(int argc, char **argv) D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); -#if !EMULATED_68K - // (Virtual) supervisor mode, disable interrupts - EmulatedSR = 0x2700; - -#ifdef HAVE_PTHREADS - // Get handle of main thread - emul_thread = pthread_self(); -#endif - - // Create and install stack for signal handlers - sig_stack = malloc(SIG_STACK_SIZE); - D(bug("Signal stack at %p\n", sig_stack)); - if (sig_stack == NULL) { - ErrorAlert(STR_NOT_ENOUGH_MEMORY_ERR); - QuitEmulator(); - } - stack_t new_stack; - new_stack.ss_sp = sig_stack; - new_stack.ss_flags = 0; - new_stack.ss_size = SIG_STACK_SIZE; - if (sigaltstack(&new_stack, NULL) < 0) { - sprintf(str, GetString(STR_SIGALTSTACK_ERR), strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } - - // Install SIGILL handler for emulating privileged instructions and - // executing A-Trap and EMUL_OP opcodes - sigemptyset(&sigill_sa.sa_mask); // Block virtual 68k interrupts during SIGILL handling - sigaddset(&sigill_sa.sa_mask, SIG_IRQ); - sigaddset(&sigill_sa.sa_mask, SIGALRM); - sigill_sa.sa_handler = (void (*)(int))sigill_handler; - sigill_sa.sa_flags = SA_ONSTACK; - if (sigaction(SIGILL, &sigill_sa, NULL) < 0) { - sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIGILL", strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } - - // Install virtual 68k interrupt signal handler - sigemptyset(&sigirq_sa.sa_mask); - sigaddset(&sigirq_sa.sa_mask, SIGALRM); - sigirq_sa.sa_handler = (void (*)(int))sigirq_handler; - sigirq_sa.sa_flags = SA_ONSTACK | SA_RESTART; - if (sigaction(SIG_IRQ, &sigirq_sa, NULL) < 0) { - sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIG_IRQ", strerror(errno)); - ErrorAlert(str); - QuitEmulator(); - } -#endif - #ifdef ENABLE_MON // Setup SIGINT handler to enter mon sigemptyset(&sigint_sa.sa_mask); @@ -859,9 +680,6 @@ int main(int argc, char **argv) // Start 60Hz timer sigemptyset(&timer_sa.sa_mask); // Block virtual 68k interrupts during SIGARLM handling -#if !EMULATED_68K - sigaddset(&timer_sa.sa_mask, SIG_IRQ); -#endif timer_sa.sa_handler = one_tick; timer_sa.sa_flags = SA_ONSTACK | SA_RESTART; if (sigaction(SIGALRM, &timer_sa, NULL) < 0) { @@ -901,10 +719,8 @@ void QuitEmulator(void) { D(bug("QuitEmulator\n")); -#if EMULATED_68K // Exit 680x0 emulation Exit680x0(); -#endif #if defined(USE_CPU_EMUL_SERVICES) // Show statistics @@ -960,12 +776,6 @@ void QuitEmulator(void) } #endif -#if REAL_ADDRESSING - // Delete Low Memory area - if (lm_area_mapped) - vm_release(0, 0x2000); -#endif - // Exit VM wrappers vm_exit(); @@ -996,8 +806,7 @@ void QuitEmulator(void) * or a dynamically recompiling emulator) */ -void FlushCodeCache(void *start, uint32 size) -{ +void FlushCodeCache(void *start, uint32 size){ #if USE_JIT if (UseJIT) #ifdef UPDATE_UAE @@ -1006,9 +815,6 @@ void FlushCodeCache(void *start, uint32 size) flush_icache_range((uint8 *)start, size); #endif #endif -#if !EMULATED_68K && defined(__NetBSD__) - m68k_sync_icache(start, size); -#endif } @@ -1017,9 +823,7 @@ void FlushCodeCache(void *start, uint32 size) */ #ifdef ENABLE_MON -static void sigint_handler(...) -{ -#if EMULATED_68K +static void sigint_handler(...){ uaecptr nextpc; #ifdef UPDATE_UAE extern void m68k_dumpstate(FILE *, uaecptr *nextpc); @@ -1027,7 +831,6 @@ static void sigint_handler(...) #else extern void m68k_dumpstate(uaecptr *nextpc); m68k_dumpstate(&nextpc); -#endif #endif VideoQuitFullScreen(); const char *arg[4] = {"mon", "-m", "-r", NULL}; @@ -1155,38 +958,17 @@ void B2_delete_mutex(B2_mutex *mutex) uint32 InterruptFlags = 0; -#if EMULATED_68K -void SetInterruptFlag(uint32 flag) -{ +void SetInterruptFlag(uint32 flag){ LOCK_INTFLAGS; InterruptFlags |= flag; UNLOCK_INTFLAGS; } -void ClearInterruptFlag(uint32 flag) -{ +void ClearInterruptFlag(uint32 flag){ LOCK_INTFLAGS; InterruptFlags &= ~flag; UNLOCK_INTFLAGS; } -#endif - -#if !EMULATED_68K -void TriggerInterrupt(void) -{ -#if defined(HAVE_PTHREADS) - pthread_kill(emul_thread, SIG_IRQ); -#else - raise(SIG_IRQ); -#endif -} - -void TriggerNMI(void) -{ - // not yet supported -} -#endif - /* * XPRAM watchdog thread (saves XPRAM every minute) @@ -1281,312 +1063,6 @@ static void *tick_func(void *arg) } #endif - -#if !EMULATED_68K -/* - * Virtual 68k interrupt handler - */ - -static void sigirq_handler(int sig, int code, struct sigcontext *scp) -{ - // Interrupts disabled? Then do nothing - if (EmulatedSR & 0x0700) - return; - - struct sigstate *state = (struct sigstate *)scp->sc_ap; - M68kRegisters *regs = (M68kRegisters *)&state->ss_frame; - - // Set up interrupt frame on stack - uint32 a7 = regs->a[7]; - a7 -= 2; - WriteMacInt16(a7, 0x64); - a7 -= 4; - WriteMacInt32(a7, scp->sc_pc); - a7 -= 2; - WriteMacInt16(a7, scp->sc_ps | EmulatedSR); - scp->sc_sp = regs->a[7] = a7; - - // Set interrupt level - EmulatedSR |= 0x2100; - - // Jump to MacOS interrupt handler on return - scp->sc_pc = ReadMacInt32(0x64); -} - - -/* - * SIGILL handler, for emulation of privileged instructions and executing - * A-Trap and EMUL_OP opcodes - */ - -static void sigill_handler(int sig, int code, struct sigcontext *scp) -{ - struct sigstate *state = (struct sigstate *)scp->sc_ap; - uint16 *pc = (uint16 *)scp->sc_pc; - uint16 opcode = *pc; - M68kRegisters *regs = (M68kRegisters *)&state->ss_frame; - -#define INC_PC(n) scp->sc_pc += (n) - -#define GET_SR (scp->sc_ps | EmulatedSR) - -#define STORE_SR(v) \ - scp->sc_ps = (v) & 0xff; \ - EmulatedSR = (v) & 0xe700; \ - if (((v) & 0x0700) == 0 && InterruptFlags) \ - TriggerInterrupt(); - -//printf("opcode %04x at %p, sr %04x, emul_sr %04x\n", opcode, pc, scp->sc_ps, EmulatedSR); - - if ((opcode & 0xf000) == 0xa000) { - - // A-Line instruction, set up A-Line trap frame on stack - uint32 a7 = regs->a[7]; - a7 -= 2; - WriteMacInt16(a7, 0x28); - a7 -= 4; - WriteMacInt32(a7, (uint32)pc); - a7 -= 2; - WriteMacInt16(a7, GET_SR); - scp->sc_sp = regs->a[7] = a7; - - // Jump to MacOS A-Line handler on return - scp->sc_pc = ReadMacInt32(0x28); - - } else if ((opcode & 0xff00) == 0x7100) { - - // Extended opcode, push registers on user stack - uint32 a7 = regs->a[7]; - a7 -= 4; - WriteMacInt32(a7, (uint32)pc); - a7 -= 2; - WriteMacInt16(a7, scp->sc_ps); - for (int i=7; i>=0; i--) { - a7 -= 4; - WriteMacInt32(a7, regs->a[i]); - } - for (int i=7; i>=0; i--) { - a7 -= 4; - WriteMacInt32(a7, regs->d[i]); - } - scp->sc_sp = regs->a[7] = a7; - - // Jump to EmulOp trampoline code on return - scp->sc_pc = (uint32)EmulOpTrampoline; - - } else switch (opcode) { // Emulate privileged instructions - - case 0x40e7: // move sr,-(sp) - regs->a[7] -= 2; - WriteMacInt16(regs->a[7], GET_SR); - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - - case 0x46df: { // move (sp)+,sr - uint16 sr = ReadMacInt16(regs->a[7]); - STORE_SR(sr); - regs->a[7] += 2; - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - } - - case 0x007c: { // ori #xxxx,sr - uint16 sr = GET_SR | pc[1]; - scp->sc_ps = sr & 0xff; // oring bits into the sr can't enable interrupts, so we don't need to call STORE_SR - EmulatedSR = sr & 0xe700; - INC_PC(4); - break; - } - - case 0x027c: { // andi #xxxx,sr - uint16 sr = GET_SR & pc[1]; - STORE_SR(sr); - INC_PC(4); - break; - } - - case 0x46fc: // move #xxxx,sr - STORE_SR(pc[1]); - INC_PC(4); - break; - - case 0x46ef: { // move (xxxx,sp),sr - uint16 sr = ReadMacInt16(regs->a[7] + (int32)(int16)pc[1]); - STORE_SR(sr); - INC_PC(4); - break; - } - - case 0x46d8: // move (a0)+,sr - case 0x46d9: { // move (a1)+,sr - uint16 sr = ReadMacInt16(regs->a[opcode & 7]); - STORE_SR(sr); - regs->a[opcode & 7] += 2; - INC_PC(2); - break; - } - - case 0x40f8: // move sr,xxxx.w - WriteMacInt16(pc[1], GET_SR); - INC_PC(4); - break; - - case 0x40d0: // move sr,(a0) - case 0x40d1: // move sr,(a1) - case 0x40d2: // move sr,(a2) - case 0x40d3: // move sr,(a3) - case 0x40d4: // move sr,(a4) - case 0x40d5: // move sr,(a5) - case 0x40d6: // move sr,(a6) - case 0x40d7: // move sr,(sp) - WriteMacInt16(regs->a[opcode & 7], GET_SR); - INC_PC(2); - break; - - case 0x40c0: // move sr,d0 - case 0x40c1: // move sr,d1 - case 0x40c2: // move sr,d2 - case 0x40c3: // move sr,d3 - case 0x40c4: // move sr,d4 - case 0x40c5: // move sr,d5 - case 0x40c6: // move sr,d6 - case 0x40c7: // move sr,d7 - regs->d[opcode & 7] = GET_SR; - INC_PC(2); - break; - - case 0x46c0: // move d0,sr - case 0x46c1: // move d1,sr - case 0x46c2: // move d2,sr - case 0x46c3: // move d3,sr - case 0x46c4: // move d4,sr - case 0x46c5: // move d5,sr - case 0x46c6: // move d6,sr - case 0x46c7: { // move d7,sr - uint16 sr = regs->d[opcode & 7]; - STORE_SR(sr); - INC_PC(2); - break; - } - - case 0xf327: // fsave -(sp) - regs->a[7] -= 4; - WriteMacInt32(regs->a[7], 0x41000000); // Idle frame - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - - case 0xf35f: // frestore (sp)+ - regs->a[7] += 4; - scp->sc_sp = regs->a[7]; - INC_PC(2); - break; - - case 0x4e73: { // rte - uint32 a7 = regs->a[7]; - uint16 sr = ReadMacInt16(a7); - a7 += 2; - scp->sc_ps = sr & 0xff; - EmulatedSR = sr & 0xe700; - scp->sc_pc = ReadMacInt32(a7); - a7 += 4; - uint16 format = ReadMacInt16(a7) >> 12; - a7 += 2; - static const int frame_adj[16] = { - 0, 0, 4, 4, 8, 0, 0, 52, 50, 12, 24, 84, 16, 0, 0, 0 - }; - scp->sc_sp = regs->a[7] = a7 + frame_adj[format]; - break; - } - - case 0x4e7a: // movec cr,x - switch (pc[1]) { - case 0x0002: // movec cacr,d0 - regs->d[0] = 0x3111; - break; - case 0x1002: // movec cacr,d1 - regs->d[1] = 0x3111; - break; - case 0x0003: // movec tc,d0 - case 0x0004: // movec itt0,d0 - case 0x0005: // movec itt1,d0 - case 0x0006: // movec dtt0,d0 - case 0x0007: // movec dtt1,d0 - case 0x0806: // movec urp,d0 - case 0x0807: // movec srp,d0 - regs->d[0] = 0; - break; - case 0x1000: // movec sfc,d1 - case 0x1001: // movec dfc,d1 - case 0x1003: // movec tc,d1 - case 0x1801: // movec vbr,d1 - regs->d[1] = 0; - break; - case 0x8801: // movec vbr,a0 - regs->a[0] = 0; - break; - case 0x9801: // movec vbr,a1 - regs->a[1] = 0; - break; - default: - goto ill; - } - INC_PC(4); - break; - - case 0x4e7b: // movec x,cr - switch (pc[1]) { - case 0x1000: // movec d1,sfc - case 0x1001: // movec d1,dfc - case 0x0801: // movec d0,vbr - case 0x1801: // movec d1,vbr - break; - case 0x0002: // movec d0,cacr - case 0x1002: // movec d1,cacr - FlushCodeCache(NULL, 0); - break; - default: - goto ill; - } - INC_PC(4); - break; - - case 0xf478: // cpusha dc - case 0xf4f8: // cpusha dc/ic - FlushCodeCache(NULL, 0); - INC_PC(2); - break; - - default: -ill: printf("SIGILL num %d, code %d\n", sig, code); - printf(" context %p:\n", scp); - printf(" onstack %08x\n", scp->sc_onstack); - printf(" sp %08x\n", scp->sc_sp); - printf(" fp %08x\n", scp->sc_fp); - printf(" pc %08x\n", scp->sc_pc); - printf(" opcode %04x\n", opcode); - printf(" sr %08x\n", scp->sc_ps); - printf(" state %p:\n", state); - printf(" flags %d\n", state->ss_flags); - for (int i=0; i<8; i++) - printf(" d%d %08x\n", i, state->ss_frame.f_regs[i]); - for (int i=0; i<8; i++) - printf(" a%d %08x\n", i, state->ss_frame.f_regs[i+8]); - - VideoQuitFullScreen(); -#ifdef ENABLE_MON - const char *arg[4] = {"mon", "-m", "-r", NULL}; - mon(3, arg); -#endif - QuitEmulator(); - break; - } -} -#endif - - /* * Display alert */ diff --git a/BasiliskII/src/Unix/prefs_editor_gtk.cpp b/BasiliskII/src/Unix/prefs_editor_gtk.cpp index 637e1e672..5f994ad8c 100644 --- a/BasiliskII/src/Unix/prefs_editor_gtk.cpp +++ b/BasiliskII/src/Unix/prefs_editor_gtk.cpp @@ -1506,7 +1506,6 @@ static void create_memory_pane(GtkWidget *top) } table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active); -#if EMULATED_68K static const opt_desc cpu_options[] = { {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)}, {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)}, @@ -1524,7 +1523,6 @@ static void create_memory_pane(GtkWidget *top) case 4: active = 4; } table_make_option_menu(table, 3, STR_CPU_CTRL, cpu_options, active); -#endif w_rom_file = table_make_file_entry(table, 4, STR_ROM_FILE_CTRL, "rom"); diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index 6f91115ea..4e330ad53 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -62,41 +62,17 @@ #include #endif -#ifdef ENABLE_NATIVE_M68K - -/* Mac and host address space are the same */ -#define REAL_ADDRESSING 1 - -/* Using 68k natively */ -#define EMULATED_68K 0 - -/* Mac ROM is not write protected */ -#define ROM_IS_WRITE_PROTECTED 0 -#define USE_SCRATCHMEM_SUBTERFUGE 1 - -#else - -/* Mac and host address space are distinct */ -#ifndef REAL_ADDRESSING -#define REAL_ADDRESSING 0 -#endif - -/* Using 68k emulator */ -#define EMULATED_68K 1 - /* The m68k emulator uses a prefetch buffer ? */ #define USE_PREFETCH_BUFFER 0 /* Mac ROM is write protected when banked memory is used */ -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # define ROM_IS_WRITE_PROTECTED 0 # define USE_SCRATCHMEM_SUBTERFUGE 1 #else # define ROM_IS_WRITE_PROTECTED 1 #endif -#endif - /* Direct Addressing requires Video on SEGV signals in plain X11 mode */ #if DIRECT_ADDRESSING && (!ENABLE_VOSF && !USE_SDL_VIDEO) # undef ENABLE_VOSF @@ -113,11 +89,9 @@ #ifdef HAVE_PTHREADS #define USE_PTHREADS_SERVICES #endif -#if EMULATED_68K #if defined(__NetBSD__) #define USE_CPU_EMUL_SERVICES #endif -#endif #ifdef USE_CPU_EMUL_SERVICES #undef USE_PTHREADS_SERVICES #endif diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index 00e5437d2..df6e55aad 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -406,7 +406,7 @@ static void add_window_modes(video_depth depth) // Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) static void set_mac_frame_buffer(X11_monitor_desc &monitor, video_depth depth, bool native_byte_order) { -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING +#if !DIRECT_ADDRESSING int layout = FLAYOUT_DIRECT; if (depth == VDEPTH_16BIT) layout = (xdepth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; @@ -1184,7 +1184,7 @@ driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m) } #if ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING // Screen_blitter_init() returns TRUE if VOSF is mandatory // i.e. the framebuffer update function is not Blit_Copy_Raw use_vosf = Screen_blitter_init(visualFormat, true, mode.depth); @@ -1321,7 +1321,7 @@ driver_xf86dga::driver_xf86dga(X11_monitor_desc &m) // Init blitting routines int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, mode.depth); #if ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING // Screen_blitter_init() returns TRUE if VOSF is mandatory // i.e. the framebuffer update function is not Blit_Copy_Raw use_vosf = Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); @@ -2527,7 +2527,7 @@ static void video_refresh_dga(void) } #ifdef ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING static void video_refresh_dga_vosf(void) { // Quit DGA mode if requested @@ -2600,7 +2600,7 @@ static void VideoRefreshInit(void) { // TODO: set up specialised 8bpp VideoRefresh handlers ? if (display_type == DISPLAY_DGA) { -#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) +#if ENABLE_VOSF && DIRECT_ADDRESSING if (use_vosf) video_refresh = video_refresh_dga_vosf; else diff --git a/BasiliskII/src/Windows/main_windows.cpp b/BasiliskII/src/Windows/main_windows.cpp index e8d390950..bceef52b8 100755 --- a/BasiliskII/src/Windows/main_windows.cpp +++ b/BasiliskII/src/Windows/main_windows.cpp @@ -94,11 +94,6 @@ static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes #endif -#if REAL_ADDRESSING -static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped -#endif - - // Prototypes static int xpram_func(void *arg); static int tick_func(void *arg); diff --git a/BasiliskII/src/Windows/prefs_editor_gtk.cpp b/BasiliskII/src/Windows/prefs_editor_gtk.cpp index 50e8d9f83..193c4240e 100644 --- a/BasiliskII/src/Windows/prefs_editor_gtk.cpp +++ b/BasiliskII/src/Windows/prefs_editor_gtk.cpp @@ -1767,9 +1767,7 @@ static void create_memory_pane(GtkWidget *top) case 14: active = 1; break; } table_make_option_menu(table, 2, STR_MODELID_CTRL, model_options, active); -#endif -#if EMULATED_68K static const opt_desc cpu_options[] = { {STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)}, {STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)}, diff --git a/BasiliskII/src/Windows/sysdeps.h b/BasiliskII/src/Windows/sysdeps.h index b729451c0..d1d8f59b8 100755 --- a/BasiliskII/src/Windows/sysdeps.h +++ b/BasiliskII/src/Windows/sysdeps.h @@ -43,23 +43,11 @@ #include #include - -/* Mac and host address space are distinct */ -#ifndef REAL_ADDRESSING -#define REAL_ADDRESSING 0 -#endif -#if REAL_ADDRESSING -#error "Real Addressing mode can't work without proper kernel support" -#endif - -/* Using 68k emulator */ -#define EMULATED_68K 1 - /* The m68k emulator uses a prefetch buffer ? */ #define USE_PREFETCH_BUFFER 0 /* Mac ROM is write protected when banked memory is used */ -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # define ROM_IS_WRITE_PROTECTED 0 # define USE_SCRATCHMEM_SUBTERFUGE 1 #else diff --git a/BasiliskII/src/ether.cpp b/BasiliskII/src/ether.cpp index 8df8c86bd..132217890 100644 --- a/BasiliskII/src/ether.cpp +++ b/BasiliskII/src/ether.cpp @@ -444,7 +444,6 @@ void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from) * Ethernet packet allocator */ -#if SIZEOF_VOID_P != 4 || REAL_ADDRESSING == 0 static uint32 ether_packet = 0; // Ethernet packet (cached allocation) static uint32 n_ether_packets = 0; // Number of ethernet packets allocated so far (should be at most 1) @@ -476,4 +475,3 @@ EthernetPacket::~EthernetPacket() bug("WARNING: Nested allocation of ethernet packets!\n"); } } -#endif diff --git a/BasiliskII/src/include/ether.h b/BasiliskII/src/include/ether.h index e1e988d08..a497cb975 100644 --- a/BasiliskII/src/include/ether.h +++ b/BasiliskII/src/include/ether.h @@ -61,19 +61,13 @@ enum { extern uint32 ether_data; // Mac address of driver data in MacOS RAM -// Ethernet packet allocator (optimized for 32-bit platforms in real addressing mode) +// Ethernet packet allocator class EthernetPacket { -#if SIZEOF_VOID_P == 4 && REAL_ADDRESSING - uint8 packet[1516]; - public: - uint32 addr(void) const { return (uint32)packet; } -#else uint32 packet; public: EthernetPacket(); ~EthernetPacket(); uint32 addr(void) const { return packet; } -#endif }; // Copy packet data from WDS to linear buffer (must hold at least 1514 bytes), diff --git a/BasiliskII/src/main.cpp b/BasiliskII/src/main.cpp index e010a19ce..148fb581c 100644 --- a/BasiliskII/src/main.cpp +++ b/BasiliskII/src/main.cpp @@ -69,7 +69,6 @@ bool InitAll(const char *vmdir) return false; } -#if EMULATED_68K // Set CPU and FPU type (UAE emulation) switch (ROMVersion) { case ROM_VERSION_64K: @@ -97,7 +96,6 @@ bool InitAll(const char *vmdir) break; } CPUIs68060 = false; -#endif // Load XPRAM XPRAMInit(vmdir); @@ -180,11 +178,9 @@ bool InitAll(const char *vmdir) XPRAM[0x58] = uint8(main_monitor.depth_to_apple_mode(main_monitor.get_current_mode().depth)); XPRAM[0x59] = 0; -#if EMULATED_68K // Init 680x0 emulation (this also activates the memory system which is needed for PatchROM()) if (!Init680x0()) return false; -#endif // Install ROM patches if (!PatchROM()) { diff --git a/BasiliskII/src/native_cpu/cpu_emulation.h b/BasiliskII/src/native_cpu/cpu_emulation.h deleted file mode 100644 index 822ee0478..000000000 --- a/BasiliskII/src/native_cpu/cpu_emulation.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * cpu_emulation.h - Definitions for Basilisk II CPU emulation module (native 68k version) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef CPU_EMULATION_H -#define CPU_EMULATION_H - - -/* - * Memory system - */ - -// RAM and ROM pointers (allocated and set by main_*.cpp) -extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0 -extern uint8 *RAMBaseHost; // RAM base (host address space) -extern uint32 RAMSize; // Size of RAM - -extern uint32 ROMBaseMac; // ROM base (Mac address space) -extern uint8 *ROMBaseHost; // ROM base (host address space) -extern uint32 ROMSize; // Size of ROM - -// Mac memory access functions -static inline uint32 ReadMacInt32(uint32 addr) {return *(uint32 *)addr;} -static inline uint32 ReadMacInt16(uint32 addr) {return *(uint16 *)addr;} -static inline uint32 ReadMacInt8(uint32 addr) {return *(uint8 *)addr;} -static inline void WriteMacInt32(uint32 addr, uint32 l) {*(uint32 *)addr = l;} -static inline void WriteMacInt16(uint32 addr, uint32 w) {*(uint16 *)addr = w;} -static inline void WriteMacInt8(uint32 addr, uint32 b) {*(uint8 *)addr = b;} -static inline uint8 *Mac2HostAddr(uint32 addr) {return (uint8 *)addr;} -static inline uint32 Host2MacAddr(uint8 *addr) {return (uint32)addr;} -static inline void *Mac_memset(uint32 addr, int c, size_t n) {return memset(Mac2HostAddr(addr), c, n);} -static inline void *Mac2Host_memcpy(void *dest, uint32 src, size_t n) {return memcpy(dest, Mac2HostAddr(src), n);} -static inline void *Host2Mac_memcpy(uint32 dest, const void *src, size_t n) {return memcpy(Mac2HostAddr(dest), src, n);} -static inline void *Mac2Mac_memcpy(uint32 dest, uint32 src, size_t n) {return memcpy(Mac2HostAddr(dest), Mac2HostAddr(src), n);} - - -/* - * 680x0 emulation - */ - -// 680x0 emulation functions -struct M68kRegisters; -extern void Start680x0(void); // Reset and start 680x0 -extern "C" void Execute68k(uint32 addr, M68kRegisters *r); // Execute 68k code from EMUL_OP routine -extern "C" void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute MacOS 68k trap from EMUL_OP routine - -// Interrupt functions -extern void TriggerInterrupt(void); // Trigger interrupt (InterruptFlag must be set first) -extern void TriggerNMI(void); // Trigger interrupt level 7 - -#endif diff --git a/BasiliskII/src/rom_patches.cpp b/BasiliskII/src/rom_patches.cpp index 5cfb13e20..1fb85e59b 100644 --- a/BasiliskII/src/rom_patches.cpp +++ b/BasiliskII/src/rom_patches.cpp @@ -832,7 +832,7 @@ bool CheckROM(void) // Read version ROMVersion = ntohs(*(uint16 *)(ROMBaseHost + 8)); -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING // Real and direct addressing modes require a 32-bit clean ROM return ROMVersion == ROM_VERSION_32; #else @@ -1257,15 +1257,6 @@ static bool patch_rom_32(void) *wp++ = htons(0x0cea); *wp = htons(M68K_RTS); -#if REAL_ADDRESSING - // Move system zone to start of Mac RAM - wp = (uint16 *)(ROMBaseHost + 0x50a); - *wp++ = htons(HiWord(RAMBaseMac + 0x2000)); - *wp++ = htons(LoWord(RAMBaseMac + 0x2000)); - *wp++ = htons(HiWord(RAMBaseMac + 0x3800)); - *wp = htons(LoWord(RAMBaseMac + 0x3800)); -#endif - #if !ROM_IS_WRITE_PROTECTED #if defined(USE_SCRATCHMEM_SUBTERFUGE) // Set fake handle at 0x0000 to scratch memory area (so broken Mac programs won't write into Mac ROM) @@ -1280,13 +1271,6 @@ static bool patch_rom_32(void) #endif #endif -#if REAL_ADDRESSING - // gb-- Temporary hack to get rid of crashes in Speedometer - wp = (uint16 *)(ROMBaseHost + 0xdba2); - if (ntohs(*wp) == 0x662c) // bne.b #$2c - *wp = htons(0x602c); // bra.b #$2c -#endif - // Don't write to VIA in InitTimeMgr wp = (uint16 *)(ROMBaseHost + 0xb0e2); *wp++ = htons(0x4cdf); // movem.l (sp)+,d0-d5/a0-a4 diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index b29c77026..d6c6d3b17 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -41,12 +41,10 @@ uint32 ROMBaseMac; // ROM base (Mac address space) uint8 *ROMBaseHost; // ROM base (host address space) uint32 ROMSize; // Size of ROM -#if !REAL_ADDRESSING // Mac frame buffer uint8 *MacFrameBaseHost; // Frame buffer base (host address space) uint32 MacFrameSize; // Size of frame buffer int MacFrameLayout; // Frame buffer layout -#endif #if DIRECT_ADDRESSING uintptr MEMBaseDiff; // Global offset between a Mac address and its Host equivalent @@ -64,13 +62,8 @@ extern bool quit_program; * Initialize 680x0 emulation, CheckROM() must have been called first */ -bool Init680x0(void) -{ -#if REAL_ADDRESSING - // Mac address space = host address space - RAMBaseMac = (uintptr)RAMBaseHost; - ROMBaseMac = (uintptr)ROMBaseHost; -#elif DIRECT_ADDRESSING +bool Init680x0(void){ +#if DIRECT_ADDRESSING // Mac address space = host address space minus constant offset (MEMBaseDiff) // NOTE: MEMBaseDiff is set up in main_unix.cpp/main() RAMBaseMac = 0; @@ -119,14 +112,12 @@ void Exit680x0(void) exit_m68k(); } - /* * Initialize memory mapping of frame buffer (called upon video mode change) */ -void InitFrameBufferMapping(void) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING +void InitFrameBufferMapping(void){ +#if !DIRECT_ADDRESSING memory_init(); #endif } diff --git a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp index 608f4e55b..1186d8dda 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp +++ b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp @@ -27,8 +27,8 @@ #if USE_JIT -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING -#error "Only Real or Direct Addressing is supported with the JIT Compiler" +#if !DIRECT_ADDRESSING +#error "Only Direct Addressing is supported with the JIT Compiler" #endif #if X86_ASSEMBLY && !SAHF_SETO_PROFITABLE @@ -5565,9 +5565,7 @@ void get_n_addr(int address, int dest, int tmp) f=dest; } -#if REAL_ADDRESSING - mov_l_rr(dest, address); -#elif DIRECT_ADDRESSING +#if DIRECT_ADDRESSING lea_l_brr(dest,address,MEMBaseDiff); #endif forget_about(tmp); @@ -7080,7 +7078,7 @@ void execute_normal(void) if (!check_for_cache_miss()) { cpu_history pc_hist[MAXRUN]; int blocklen = 0; -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING start_pc_p = regs.pc_p; start_pc = get_virtual_address(regs.pc_p); #else diff --git a/BasiliskII/src/uae_cpu/cpu_emulation.h b/BasiliskII/src/uae_cpu/cpu_emulation.h index cd588ec10..6acf0ab9f 100644 --- a/BasiliskII/src/uae_cpu/cpu_emulation.h +++ b/BasiliskII/src/uae_cpu/cpu_emulation.h @@ -37,8 +37,8 @@ extern uint32 ROMBaseMac; // ROM base (Mac address space) extern uint8 *ROMBaseHost; // ROM base (host address space) extern uint32 ROMSize; // Size of ROM -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING -// If we are not using real or direct addressing, the Mac frame buffer gets +#if !DIRECT_ADDRESSING +// If we are not using direct addressing, the Mac frame buffer gets // mapped to this location. The memory must be allocated by VideoInit(). // If multiple monitors are used, they must share the frame buffer const uint32 MacFrameBaseMac = 0xa0000000; diff --git a/BasiliskII/src/uae_cpu/memory.cpp b/BasiliskII/src/uae_cpu/memory.cpp index 7483f5064..aa0b22b4b 100644 --- a/BasiliskII/src/uae_cpu/memory.cpp +++ b/BasiliskII/src/uae_cpu/memory.cpp @@ -34,7 +34,7 @@ #include "readcpu.h" #include "newcpu.h" -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING +#if !DIRECT_ADDRESSING static bool illegal_mem = false; @@ -638,5 +638,5 @@ void map_banks(addrbank *bank, int start, int size) put_mem_bank((bnr + hioffs) << 16, bank); } -#endif /* !REAL_ADDRESSING && !DIRECT_ADDRESSING */ +#endif /* !DIRECT_ADDRESSING */ diff --git a/BasiliskII/src/uae_cpu/memory.h b/BasiliskII/src/uae_cpu/memory.h index 75a6303ba..d78981660 100644 --- a/BasiliskII/src/uae_cpu/memory.h +++ b/BasiliskII/src/uae_cpu/memory.h @@ -23,7 +23,7 @@ #ifndef UAE_MEMORY_H #define UAE_MEMORY_H -#if !DIRECT_ADDRESSING && !REAL_ADDRESSING +#if !DIRECT_ADDRESSING /* Enabling this adds one additional native memory reference per 68k memory * access, but saves one shift (on the x86). Enabling this is probably @@ -115,15 +115,11 @@ extern void byteput(uaecptr addr, uae_u32 b); #endif -#endif /* !DIRECT_ADDRESSING && !REAL_ADDRESSING */ +#endif /* !DIRECT_ADDRESSING */ -#if REAL_ADDRESSING -const uintptr MEMBaseDiff = 0; -#elif DIRECT_ADDRESSING +#if DIRECT_ADDRESSING extern uintptr MEMBaseDiff; -#endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING static __inline__ uae_u8 *do_get_real_address(uaecptr addr) { return (uae_u8 *)MEMBaseDiff + addr; @@ -201,7 +197,7 @@ static __inline__ uae_u8 *get_real_address(uaecptr addr) } /* gb-- deliberately not implemented since it shall not be used... */ extern uae_u32 get_virtual_address(uae_u8 *addr); -#endif /* DIRECT_ADDRESSING || REAL_ADDRESSING */ +#endif /* DIRECT_ADDRESSING */ #endif /* MEMORY_H */ diff --git a/BasiliskII/src/uae_cpu/newcpu.cpp b/BasiliskII/src/uae_cpu/newcpu.cpp index d13a60785..1bdfa1551 100644 --- a/BasiliskII/src/uae_cpu/newcpu.cpp +++ b/BasiliskII/src/uae_cpu/newcpu.cpp @@ -303,7 +303,7 @@ static int backup_pointer = 0; static long int m68kpc_offset; int lastint_no; -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING #define get_ibyte_1(o) get_byte(get_virtual_address(regs.pc_p) + (o) + 1) #define get_iword_1(o) get_word(get_virtual_address(regs.pc_p) + (o)) #define get_ilong_1(o) get_long(get_virtual_address(regs.pc_p) + (o)) diff --git a/BasiliskII/src/uae_cpu/newcpu.h b/BasiliskII/src/uae_cpu/newcpu.h index e2d5b5ed3..ccb36dc5d 100644 --- a/BasiliskII/src/uae_cpu/newcpu.h +++ b/BasiliskII/src/uae_cpu/newcpu.h @@ -182,7 +182,7 @@ static __inline__ void fill_prefetch_2 (void) static __inline__ uaecptr m68k_getpc (void) { -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING return get_virtual_address(regs.pc_p); #else return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); @@ -195,7 +195,7 @@ static __inline__ void m68k_setpc (uaecptr newpc) uae_u32 previous_pc = m68k_getpc(); #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING regs.pc_p = get_real_address(newpc); #else regs.pc_p = regs.pc_oldp = get_real_address(newpc); From 256f93b221f46ffa93d6da08e52f6b2298180075 Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 12 Dec 2020 13:32:05 -0800 Subject: [PATCH 09/24] Remove legacy X11/DGA/FBDEV/ESD etc support --- BasiliskII/src/Unix/Irix/README.networking | 110 - BasiliskII/src/Unix/Irix/audio_irix.cpp | 680 ----- BasiliskII/src/Unix/Irix/unaligned.c | 44 - BasiliskII/src/Unix/Solaris/audio_solaris.cpp | 320 -- BasiliskII/src/Unix/audio_oss_esd.cpp | 558 ---- BasiliskII/src/Unix/configure.ac | 71 +- BasiliskII/src/Unix/main_unix.cpp | 47 - BasiliskII/src/Unix/prefs_editor_gtk.cpp | 63 +- BasiliskII/src/Unix/video_x.cpp | 2690 ----------------- 9 files changed, 4 insertions(+), 4579 deletions(-) delete mode 100644 BasiliskII/src/Unix/Irix/README.networking delete mode 100644 BasiliskII/src/Unix/Irix/audio_irix.cpp delete mode 100644 BasiliskII/src/Unix/Irix/unaligned.c delete mode 100644 BasiliskII/src/Unix/Solaris/audio_solaris.cpp delete mode 100644 BasiliskII/src/Unix/audio_oss_esd.cpp delete mode 100644 BasiliskII/src/Unix/video_x.cpp diff --git a/BasiliskII/src/Unix/Irix/README.networking b/BasiliskII/src/Unix/Irix/README.networking deleted file mode 100644 index f6145a71b..000000000 --- a/BasiliskII/src/Unix/Irix/README.networking +++ /dev/null @@ -1,110 +0,0 @@ -README file for networking under IRIX -by Brian J. Johnson 7/23/2002 -version 1.0 -================================================== - -BasiliskII does not currently support networking natively on IRIX. -That is, the emulated Ethernet card does not do anything. There's no -reason one couldn't use raw domain sockets and the snoop(7p) facility -to do networking, but so far no one has written the required glue -code. - -However, it is possible to do TCP/IP networking with BasiliskII on -IRIX via PPP, by connecting an emulated serial port to the IRIX PPP -daemon. Here are the steps to set it up: - - -Set up PPP on IRIX ------------------- - -You need root privileges to do this. - -First, make sure you have eoe.sw.ppp and eoe.sw.uucp installed: - - IRIS# versions eoe.sw.ppp eoe.sw.uucp - I = Installed, R = Removed - - Name Date Description - - I eoe 07/22/2002 IRIX Execution Environment, 6.5.17m - I eoe.sw 07/22/2002 IRIX Execution Environment Software - I eoe.sw.ppp 07/22/2002 Point-to-Point Protocol Software - I eoe.sw.uucp 07/22/2002 UUCP Utilities - -If they aren't installed, install them from your distribution CDs. - -Next, pick IP addresses for the IRIX and MacOS sides of the PPP -connection. You may want to ask your local network administrator -about this, but any two unused addresses on your local subnet should -work. - -Edit /etc/ppp.conf and add these three lines: - -_NET_INCOMING - remotehost= - localhost= - -(Replace the angle brackets and the text in them with the appropriate -IP addresses.) - -Next, make a script to set up the environment properly when invoking -pppd from BasiliskII. You can name this whatever you want; I chose -/usr/etc/ppp-b2: - -IRIS# whoami -root -IRIS# cat < /usr/etc/ppp-b2 -#!/bin/sh -export USER=_NET_INCOMING -exec /usr/etc/ppp "$@" -IRIS# chmod 4775 /usr/etc/ppp-b2 - -Rewrite this in perl or python or C or whatever if you don't like -setuid shell scripts. The alternative is to run BasiliskII as root: -pppd _must_ be run as root. - - -Configure BasiliskII to start the PPP daemon --------------------------------------------- - -Start up BasiliskII, and in the serial devices tab, enter: - - |exec /usr/etc/ppp-b2 - -Supply the name you used for the script you created. Be sure to -include the leading pipe symbol ("|"). - -The "exec" causes your PPP startup script to replace the shell -BasiliskII runs to interpret the command. It's not strictly -necessary, but cuts down on the number of extra processes hanging -about. - - -Install a PPP client on MacOS ------------------------------ - -The details of this step will vary depending on your PPP client -software. Set it up for a "direct" connection, with no modem chatting -or login scripting. For instance, with FreePPP I set the "Connect:" -item on the "Edit..." screen under the "Accounts" tab to "Directly". -Be sure to select the correct serial port. The serial port speed -shouldn't matter (BasiliskII ignores it), but I set it to 115200 bps. - -Next, configure MacOS's TCP/IP stack. If you're using Open Transport, -Open the TCP/IP control panel and select "Using PPP Server" under the -"Configure" item. Copy IRIX's DNS client info. from /etc/resolv.conf -to the control panel: the addresses from the "nameserver" lines go in -the "Name server addr.:" box, and the domains from the "search" lines -go in the "Search domains:" box. The steps should be similar for -MacTCP. - -Now fire up PPP. Your PPP client should establish communication with -the IRIX PPP daemon, and you're off and running. - - -Disclaimer ----------- - -I haven't tried this procedure from scratch on a freshly installed -system, so I might have missed a step somewhere. But it should get -you close.... diff --git a/BasiliskII/src/Unix/Irix/audio_irix.cpp b/BasiliskII/src/Unix/Irix/audio_irix.cpp deleted file mode 100644 index 8b61a2819..000000000 --- a/BasiliskII/src/Unix/Irix/audio_irix.cpp +++ /dev/null @@ -1,680 +0,0 @@ -/* - * audio_irix.cpp - Audio support, SGI Irix implementation - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// The currently selected audio parameters (indices in audio_sample_rates[] -// etc. vectors) -static int audio_sample_rate_index = 0; -static int audio_sample_size_index = 0; -static int audio_channel_count_index = 0; - -// Global variables -static int audio_fd = -1; // fd from audio library -static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read -static bool sem_inited = false; // Flag: audio_irq_done_sem initialized -static int sound_buffer_size; // Size of sound buffer in bytes -static int sound_buffer_fill_point; // Fill buffer when this many frames are empty -static uint8 silence_byte = 0; // Byte value to use to fill sound buffers with silence -static pthread_t stream_thread; // Audio streaming thread -static pthread_attr_t stream_thread_attr; // Streaming thread attributes -static bool stream_thread_active = false; // Flag: streaming thread installed -static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread - -static bool current_main_mute = false; // Flag: output muted -static bool current_speaker_mute = false; // Flag: speaker muted -static uint32 current_main_volume = 0; // Output volume -static uint32 current_speaker_volume = 0; // Speaker volume - -// IRIX libaudio control structures -static ALconfig config; -static ALport port; - - -// Prototypes -static void *stream_func(void *arg); -static uint32 read_volume(void); -static bool read_mute(void); -static void set_mute(bool mute); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index]; - AudioStatus.channels = audio_channel_counts[audio_channel_count_index]; -} - -bool open_audio(void) -{ - ALpv pv[2]; - - printf("Using libaudio audio output\n"); - - // Get supported sample formats - - if (audio_sample_sizes.empty()) { - // All sample sizes are supported - audio_sample_sizes.push_back(8); - audio_sample_sizes.push_back(16); - - // Assume at least two channels are supported. Some IRIX boxes - // can do 4 or more... MacOS only handles up to 2. - audio_channel_counts.push_back(1); - audio_channel_counts.push_back(2); - - if (audio_sample_sizes.empty() || audio_channel_counts.empty()) { - WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); - alClosePort(port); - audio_fd = -1; - return false; - } - - audio_sample_rates.push_back( 8000 << 16); - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - audio_sample_rates.push_back(44100 << 16); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - } - - // Set the sample format - - D(bug("Size %d, channels %d, rate %d\n", - audio_sample_sizes[audio_sample_size_index], - audio_channel_counts[audio_channel_count_index], - audio_sample_rates[audio_sample_rate_index] >> 16)); - config = alNewConfig(); - alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP); - if (audio_sample_sizes[audio_sample_size_index] == 8) { - alSetWidth(config, AL_SAMPLE_8); - } - else { - alSetWidth(config, AL_SAMPLE_16); - } - alSetChannels(config, audio_channel_counts[audio_channel_count_index]); - alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs? - - // Try to open the audio library - - port = alOpenPort("BasiliskII", "w", config); - if (port == NULL) { - fprintf(stderr, "ERROR: Cannot open audio port: %s\n", - alGetErrorString(oserror())); - WarningAlert(GetString(STR_NO_AUDIO_WARN)); - return false; - } - - // Set the sample rate - - pv[0].param = AL_RATE; - pv[0].value.ll = alDoubleToFixed(audio_sample_rates[audio_sample_rate_index] >> 16); - pv[1].param = AL_MASTER_CLOCK; - pv[1].value.i = AL_CRYSTAL_MCLK_TYPE; - if (alSetParams(AL_DEFAULT_OUTPUT, pv, 2) < 0) { - fprintf(stderr, "ERROR: libaudio setparams failed: %s\n", - alGetErrorString(oserror())); - alClosePort(port); - return false; - } - - // Compute sound buffer size and libaudio refill point - - config = alGetConfig(port); - audio_frames_per_block = alGetQueueSize(config); - if (audio_frames_per_block < 0) { - fprintf(stderr, "ERROR: couldn't get queue size: %s\n", - alGetErrorString(oserror())); - alClosePort(port); - return false; - } - D(bug("alGetQueueSize %d, width %d, channels %d\n", - audio_frames_per_block, - alGetWidth(config), - alGetChannels(config))); - - // Put a limit on the Mac sound buffer size, to decrease delay -#define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer - int target_frames_per_block = - (audio_sample_rates[audio_sample_rate_index] >> 16) * - AUDIO_BUFFER_MSEC / 1000; - if (audio_frames_per_block > target_frames_per_block) - audio_frames_per_block = target_frames_per_block; - D(bug("frames per block %d\n", audio_frames_per_block)); - - alZeroFrames(port, audio_frames_per_block); // so we don't underflow - - // Try to keep the buffer pretty full - sound_buffer_fill_point = alGetQueueSize(config) - - 2 * audio_frames_per_block; - if (sound_buffer_fill_point < 0) - sound_buffer_fill_point = alGetQueueSize(config) / 3; - D(bug("fill point %d\n", sound_buffer_fill_point)); - - sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * - audio_channel_counts[audio_channel_count_index] * - audio_frames_per_block; - set_audio_status_format(); - - // Get a file descriptor we can select() on - - audio_fd = alGetFD(port); - if (audio_fd < 0) { - fprintf(stderr, "ERROR: couldn't get libaudio file descriptor: %s\n", - alGetErrorString(oserror())); - alClosePort(port); - return false; - } - - // Initialize volume, mute settings - current_main_volume = current_speaker_volume = read_volume(); - current_main_mute = current_speaker_mute = read_mute(); - - - // Start streaming thread - Set_pthread_attr(&stream_thread_attr, 0); - stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); - - // Everything went fine - audio_open = true; - return true; -} - -void AudioInit(void) -{ - // Init audio status (reasonable defaults) and feature flags - AudioStatus.sample_rate = 44100 << 16; - AudioStatus.sample_size = 16; - AudioStatus.channels = 2; - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphore - if (sem_init(&audio_irq_done_sem, 0, 0) < 0) - return; - sem_inited = true; - - // Open and initialize audio device - open_audio(); -} - - -/* - * Deinitialization - */ - -static void close_audio(void) -{ - // Stop stream and delete semaphore - if (stream_thread_active) { - stream_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(stream_thread); -#endif - pthread_join(stream_thread, NULL); - stream_thread_active = false; - stream_thread_cancel = false; - } - - // Close audio library - alClosePort(port); - - audio_open = false; -} - -void AudioExit(void) -{ - // Close audio device - close_audio(); - - // Delete semaphore - if (sem_inited) { - sem_destroy(&audio_irq_done_sem); - sem_inited = false; - } -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Streaming function - */ - -static void *stream_func(void *arg) -{ - int32 *last_buffer = new int32[sound_buffer_size / 4]; - fd_set audio_fdset; - int numfds, was_error; - - numfds = audio_fd + 1; - FD_ZERO(&audio_fdset); - - while (!stream_thread_cancel) { - if (AudioStatus.num_sources) { - - // Trigger audio interrupt to get new buffer - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - D(bug("stream: waiting for ack\n")); - sem_wait(&audio_irq_done_sem); - D(bug("stream: ack received\n")); - - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (!current_main_mute && - !current_speaker_mute && - apple_stream_info) { - int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: work_size %d\n", work_size)); - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - if (work_size == 0) - goto silence; - - // Send data to audio library. Convert 8-bit data - // unsigned->signed - // It works fine for 8-bit mono, but not stereo. - if (AudioStatus.sample_size == 8) { - uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - uint32 *q = (uint32 *)last_buffer; - int r = work_size >> 2; - // XXX not quite right.... - while (r--) - *q++ = *p++ ^ 0x80808080; - if (work_size != sound_buffer_size) - memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size); - alWriteFrames(port, last_buffer, audio_frames_per_block); - } - else if (work_size == sound_buffer_size) - alWriteFrames(port, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), audio_frames_per_block); - else { - // Last buffer - Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size); - alWriteFrames(port, last_buffer, audio_frames_per_block); - } - D(bug("stream: data written\n")); - } else - goto silence; - - } else { - - // Audio not active, play silence - silence: // D(bug("stream: silence\n")); - alZeroFrames(port, audio_frames_per_block); - } - - // Wait for fill point to be reached (may be immediate) - - if (alSetFillPoint(port, sound_buffer_fill_point) < 0) { - fprintf(stderr, "ERROR: alSetFillPoint failed: %s\n", - alGetErrorString(oserror())); - // Should stop the audio here.... - } - - do { - errno = 0; - FD_SET(audio_fd, &audio_fdset); - was_error = select(numfds, NULL, &audio_fdset, NULL, NULL); - } while(was_error < 0 && (errno == EINTR)); - if (was_error < 0) { - fprintf(stderr, "ERROR: select returned %d, errno %d\n", - was_error, errno); - // Should stop audio here.... - } - } - delete[] last_buffer; - return NULL; -} - - -/* - * Read or set the current output volume using the audio library - */ - -static uint32 read_volume(void) -{ - ALpv x[2]; - ALfixed gain[8]; - double maxgain, mingain; - ALparamInfo pi; - uint32 ret = 0x01000100; // default, maximum value - int dev = alGetDevice(config); - - // Fetch the maximum and minimum gain settings - - alGetParamInfo(dev, AL_GAIN, &pi); - maxgain = alFixedToDouble(pi.max.ll); - mingain = alFixedToDouble(pi.min.ll); -// printf("maxgain = %lf dB, mingain = %lf dB\n", maxgain, mingain); - - // Get the current gain values - - x[0].param = AL_GAIN; - x[0].value.ptr = gain; - x[0].sizeIn = sizeof(gain) / sizeof(gain[0]); - x[1].param = AL_CHANNELS; - if (alGetParams(dev, x, 2) < 0) { - printf("alGetParams failed: %s\n", alGetErrorString(oserror())); - } - else { - if (x[0].sizeOut < 0) { - printf("AL_GAIN was an unrecognized parameter\n"); - } - else { - double v; - uint32 left, right; - - // Left - v = alFixedToDouble(gain[0]); - if (v < mingain) - v = mingain; // handle gain == -inf - v = (v - mingain) / (maxgain - mingain); // scale to 0..1 - left = (uint32)(v * (double)256); // convert to 8.8 fixed point - - // Right - if (x[0].sizeOut <= 1) { // handle a mono interface - right = left; - } - else { - v = alFixedToDouble(gain[1]); - if (v < mingain) - v = mingain; // handle gain == -inf - v = (v - mingain) / (maxgain - mingain); // scale to 0..1 - right = (uint32)(v * (double)256); // convert to 8.8 fixed point - } - - ret = (left << 16) | right; - } - } - - return ret; -} - -static void set_volume(uint32 vol) -{ - ALpv x[1]; - ALfixed gain[2]; // left and right - double maxgain, mingain; - ALparamInfo pi; - int dev = alGetDevice(config); - - // Fetch the maximum and minimum gain settings - - alGetParamInfo(dev, AL_GAIN, &pi); - maxgain = alFixedToDouble(pi.max.ll); - mingain = alFixedToDouble(pi.min.ll); - - // Set the new gain values - - x[0].param = AL_GAIN; - x[0].value.ptr = gain; - x[0].sizeIn = sizeof(gain) / sizeof(gain[0]); - - uint32 left = vol >> 16; - uint32 right = vol & 0xffff; - double lv, rv; - - if (left == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) { - lv = AL_NEG_INFINITY; - } - else { - lv = ((double)left / 256) * (maxgain - mingain) + mingain; - } - - if (right == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) { - rv = AL_NEG_INFINITY; - } - else { - rv = ((double)right / 256) * (maxgain - mingain) + mingain; - } - - D(bug("set_volume: left=%lf dB, right=%lf dB\n", lv, rv)); - - gain[0] = alDoubleToFixed(lv); - gain[1] = alDoubleToFixed(rv); - - if (alSetParams(dev, x, 1) < 0) { - printf("alSetParams failed: %s\n", alGetErrorString(oserror())); - } -} - - -/* - * Read or set the mute setting using the audio library - */ - -static bool read_mute(void) -{ - bool ret; - int dev = alGetDevice(config); - ALpv x; - x.param = AL_MUTE; - - if (alGetParams(dev, &x, 1) < 0) { - printf("alSetParams failed: %s\n", alGetErrorString(oserror())); - return current_main_mute; // Or just return false? - } - - ret = x.value.i; - - D(bug("read_mute: mute=%d\n", ret)); - return ret; -} - -static void set_mute(bool mute) -{ - D(bug("set_mute: mute=%ld\n", mute)); - - int dev = alGetDevice(config); - ALpv x; - x.param = AL_MUTE; - x.value.i = mute; - - if (alSetParams(dev, &x, 1) < 0) { - printf("alSetParams failed: %s\n", alGetErrorString(oserror())); - } -} - - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - sem_post(&audio_irq_done_sem); - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. vectors - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - close_audio(); - audio_sample_rate_index = index; - return open_audio(); -} - -bool audio_set_sample_size(int index) -{ - close_audio(); - audio_sample_size_index = index; - return open_audio(); -} - -bool audio_set_channels(int index) -{ - close_audio(); - audio_channel_count_index = index; - return open_audio(); -} - - -/* - * Get/set volume controls (volume values received/returned have the left channel - * volume in the upper 16 bits and the right channel volume in the lower 16 bits; - * both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume")) - */ - -bool audio_get_main_mute(void) -{ - D(bug("audio_get_main_mute: mute=%ld\n", current_main_mute)); - - return current_main_mute; -} - -uint32 audio_get_main_volume(void) -{ - uint32 ret = current_main_volume; - - D(bug("audio_get_main_volume: vol=0x%x\n", ret)); - - return ret; -} - -bool audio_get_speaker_mute(void) -{ - D(bug("audio_get_speaker_mute: mute=%ld\n", current_speaker_mute)); - - return current_speaker_mute; -} - -uint32 audio_get_speaker_volume(void) -{ - uint32 ret = current_speaker_volume; - - D(bug("audio_get_speaker_volume: vol=0x%x\n", ret)); - - return ret; -} - -void audio_set_main_mute(bool mute) -{ - D(bug("audio_set_main_mute: mute=%ld\n", mute)); - - if (mute != current_main_mute) { - current_main_mute = mute; - } - - set_mute(current_main_mute); -} - -void audio_set_main_volume(uint32 vol) -{ - - D(bug("audio_set_main_volume: vol=%x\n", vol)); - - current_main_volume = vol; - - set_volume(vol); -} - -void audio_set_speaker_mute(bool mute) -{ - D(bug("audio_set_speaker_mute: mute=%ld\n", mute)); - - if (mute != current_speaker_mute) { - current_speaker_mute = mute; - } - - set_mute(current_speaker_mute); -} - -void audio_set_speaker_volume(uint32 vol) -{ - D(bug("audio_set_speaker_volume: vol=%x\n", vol)); - - current_speaker_volume = vol; - - set_volume(vol); -} diff --git a/BasiliskII/src/Unix/Irix/unaligned.c b/BasiliskII/src/Unix/Irix/unaligned.c deleted file mode 100644 index 9f4befb8f..000000000 --- a/BasiliskII/src/Unix/Irix/unaligned.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Irix/unaligned.c - Optimized unaligned access for Irix - * - * Basilisk II (C) 1997-2005 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef sgi -#include "sysdeps.h" - -/* Tell the compiler to pack data on 1-byte boundaries - * (i.e. arbitrary alignment). Requires SGI MIPSPro compilers. */ -#pragma pack(1) - -typedef struct _ual32 { - uae_u32 v; -} ual32_t; - -typedef struct _ual16 { - uae_u16 v; -} ual16_t; - -#pragma pack(0) - -/* The compiler is smart enough to inline these when you build with "-ipa" */ -uae_u32 do_get_mem_long(uae_u32 *a) {return ((ual32_t *)a)->v;} -uae_u32 do_get_mem_word(uae_u16 *a) {return ((ual16_t *)a)->v;} -void do_put_mem_long(uae_u32 *a, uae_u32 v) {((ual32_t *)a)->v = v;} -void do_put_mem_word(uae_u16 *a, uae_u32 v) {((ual16_t *)a)->v = v;} - -#endif /* sgi */ diff --git a/BasiliskII/src/Unix/Solaris/audio_solaris.cpp b/BasiliskII/src/Unix/Solaris/audio_solaris.cpp deleted file mode 100644 index d4b7e0dfa..000000000 --- a/BasiliskII/src/Unix/Solaris/audio_solaris.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - * audio_solaris.cpp - Audio support, Solaris implementation - * - * Adapted from Frodo's Solaris sound routines by Marc Chabanas - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#define DEBUG 0 -#include "debug.h" - - -// Global variables -static int fd = -1; // fd of /dev/audio -static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read -static pthread_t stream_thread; // Audio streaming thread -static pthread_attr_t stream_thread_attr; // Streaming thread attributes -static bool stream_thread_active = false; -static int sound_buffer_size; // Size of sound buffer in bytes - -// Prototypes -static void *stream_func(void *arg); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[0]; - AudioStatus.sample_size = audio_sample_sizes[0]; - AudioStatus.channels = audio_channel_counts[0]; -} - -void AudioInit(void) -{ - char str[256]; - - // Init audio status and feature flags - audio_sample_rates.push_back(44100 << 16); - audio_sample_sizes.push_back(16); - audio_channel_counts.push_back(2); - set_audio_status_format(); - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphore - if (sem_init(&audio_irq_done_sem, 0, 0) < 0) - return; - - // Open /dev/audio - fd = open("/dev/audio", O_WRONLY | O_NDELAY); - if (fd < 0) { - sprintf(str, GetString(STR_NO_AUDIO_DEV_WARN), "/dev/audio", strerror(errno)); - WarningAlert(str); - sem_destroy(&audio_irq_done_sem); - return; - } - - // Set audio parameters - struct audio_info info; - AUDIO_INITINFO(&info); - info.play.sample_rate = AudioStatus.sample_rate >> 16; - info.play.channels = AudioStatus.channels; - info.play.precision = AudioStatus.sample_size; - info.play.encoding = AUDIO_ENCODING_LINEAR; - info.play.port = AUDIO_SPEAKER; - if (ioctl(fd, AUDIO_SETINFO, &info)) { - WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); - close(fd); - fd = -1; - sem_destroy(&audio_irq_done_sem); - return; - } - - // 2048 frames per buffer - audio_frames_per_block = 2048; - sound_buffer_size = (AudioStatus.sample_size>>3) * AudioStatus.channels * audio_frames_per_block; - - // Start audio thread - Set_pthread_attr(&stream_thread_attr, 0); - stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); - - // Everything OK - audio_open = true; -} - - -/* - * Deinitialization - */ - -void AudioExit(void) -{ - // Stop audio thread - if (stream_thread_active) { - pthread_cancel(stream_thread); - pthread_join(stream_thread, NULL); - sem_destroy(&audio_irq_done_sem); - stream_thread_active = false; - } - - // Close /dev/audio - if (fd > 0) { - ioctl(fd, AUDIO_DRAIN); - close(fd); - } -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ -} - - -/* - * Streaming function - */ - -static uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer - -static void *stream_func(void *arg) -{ - int16 *silent_buffer = new int16[sound_buffer_size / 2]; - int16 *last_buffer = new int16[sound_buffer_size / 2]; - memset(silent_buffer, 0, sound_buffer_size); - - uint_t sent = 0, delta; - struct audio_info status; - - for (;;) { - if (AudioStatus.num_sources) { - - // Trigger audio interrupt to get new buffer - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - D(bug("stream: waiting for ack\n")); - sem_wait(&audio_irq_done_sem); - D(bug("stream: ack received\n")); - - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: work_size %d\n", work_size)); - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - if (work_size == 0) - goto silence; - - // Send data to audio port - if (work_size == sound_buffer_size) - write(fd, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), sound_buffer_size); - else { - // Last buffer - Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - memset((uint8 *)last_buffer + work_size, 0, sound_buffer_size - work_size); - write(fd, last_buffer, sound_buffer_size); - } - D(bug("stream: data written\n")); - } else - goto silence; - - } else { - - // Audio not active, play silence -silence: write(fd, silent_buffer, sound_buffer_size); - } - - // We allow a maximum of three buffers to be sent - sent += audio_frames_per_block; - ioctl(fd, AUDIO_GETINFO, &status); - while ((delta = sent - status.play.samples) > (audio_frames_per_block * 3)) { - unsigned int sl = 1000000 * (delta - audio_frames_per_block * 3) / (AudioStatus.sample_rate >> 16); - usleep(sl); - ioctl(fd, AUDIO_GETINFO, &status); - } - } - return NULL; -} - - -/* - * MacOS audio interrupt, read next data block - */ - -void AudioInterrupt(void) -{ - D(bug("AudioInterrupt\n")); - - // Get data from apple mixer - if (AudioStatus.mixer) { - M68kRegisters r; - r.a[0] = audio_data + adatStreamInfo; - r.a[1] = AudioStatus.mixer; - Execute68k(audio_data + adatGetSourceData, &r); - D(bug(" GetSourceData() returns %08lx\n", r.d[0])); - } else - WriteMacInt32(audio_data + adatStreamInfo, 0); - - // Signal stream function - sem_post(&audio_irq_done_sem); - D(bug("AudioInterrupt done\n")); -} - - -/* - * Set sampling parameters - * "index" is an index into the audio_sample_rates[] etc. arrays - * It is guaranteed that AudioStatus.num_sources == 0 - */ - -bool audio_set_sample_rate(int index) -{ - return true; -} - -bool audio_set_sample_size(int index) -{ - return true; -} - -bool audio_set_channels(int index) -{ - return true; -} - - -/* - * Get/set volume controls (volume values received/returned have the left channel - * volume in the upper 16 bits and the right channel volume in the lower 16 bits; - * both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume")) - */ - -bool audio_get_main_mute(void) -{ - return false; -} - -uint32 audio_get_main_volume(void) -{ - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return false; -} - -uint32 audio_get_speaker_volume(void) -{ - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ -} - -void audio_set_main_volume(uint32 vol) -{ -} - -void audio_set_speaker_mute(bool mute) -{ -} - -void audio_set_speaker_volume(uint32 vol) -{ -} diff --git a/BasiliskII/src/Unix/audio_oss_esd.cpp b/BasiliskII/src/Unix/audio_oss_esd.cpp deleted file mode 100644 index 203a5ac75..000000000 --- a/BasiliskII/src/Unix/audio_oss_esd.cpp +++ /dev/null @@ -1,558 +0,0 @@ -/* - * audio_oss_esd.cpp - Audio support, implementation for OSS and ESD (Linux and FreeBSD) - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include -#endif - -#ifdef __FreeBSD__ -#include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "prefs.h" -#include "user_strings.h" -#include "audio.h" -#include "audio_defs.h" - -#ifdef ENABLE_ESD -#include -#endif - -#define DEBUG 0 -#include "debug.h" - - -// The currently selected audio parameters (indices in audio_sample_rates[] etc. vectors) -static int audio_sample_rate_index = 0; -static int audio_sample_size_index = 0; -static int audio_channel_count_index = 0; - -// Global variables -static bool is_dsp_audio = false; // Flag: is DSP audio -static int audio_fd = -1; // fd of dsp or ESD -static int mixer_fd = -1; // fd of mixer -static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read -static bool sem_inited = false; // Flag: audio_irq_done_sem initialized -static int sound_buffer_size; // Size of sound buffer in bytes -static bool little_endian = false; // Flag: DSP accepts only little-endian 16-bit sound data -static uint8 silence_byte; // Byte value to use to fill sound buffers with silence -static pthread_t stream_thread; // Audio streaming thread -static pthread_attr_t stream_thread_attr; // Streaming thread attributes -static bool stream_thread_active = false; // Flag: streaming thread installed -static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread - -// Prototypes -static void *stream_func(void *arg); - - -/* - * Initialization - */ - -// Set AudioStatus to reflect current audio stream format -static void set_audio_status_format(void) -{ - AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index]; - AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index]; - AudioStatus.channels = audio_channel_counts[audio_channel_count_index]; -} - -// Init using the dsp device, returns false on error -static bool open_dsp(void) -{ - // Open the device - const char *dsp = PrefsFindString("dsp"); - audio_fd = open(dsp, O_WRONLY); - if (audio_fd < 0) { - fprintf(stderr, "WARNING: Cannot open %s (%s)\n", dsp, strerror(errno)); - return false; - } - - printf("Using %s audio output\n", dsp); - is_dsp_audio = true; - - // Get supported sample formats - if (audio_sample_sizes.empty()) { - unsigned long format; - ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format); - if (format & AFMT_U8) - audio_sample_sizes.push_back(8); - if (format & (AFMT_S16_BE | AFMT_S16_LE)) - audio_sample_sizes.push_back(16); - - int stereo = 0; - if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 0) - audio_channel_counts.push_back(1); - stereo = 1; - if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 1) - audio_channel_counts.push_back(2); - - if (audio_sample_sizes.empty() || audio_channel_counts.empty()) { - WarningAlert(GetString(STR_AUDIO_FORMAT_WARN)); - close(audio_fd); - audio_fd = -1; - return false; - } - - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - int rate = 44100; - ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); - if (rate > 22050) - audio_sample_rates.push_back(rate << 16); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - } - - // Set DSP parameters - unsigned long format; - if (audio_sample_sizes[audio_sample_size_index] == 8) { - format = AFMT_U8; - little_endian = false; - silence_byte = 0x80; - } else { - unsigned long sup_format; - ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &sup_format); - if (sup_format & AFMT_S16_BE) { - little_endian = false; - format = AFMT_S16_BE; - } else { - little_endian = true; - format = AFMT_S16_LE; - } - silence_byte = 0; - } - ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); - int frag = 0x0004000c; // Block size: 4096 frames - ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag); - int stereo = (audio_channel_counts[audio_channel_count_index] == 2); - ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo); - int rate = audio_sample_rates[audio_sample_rate_index] >> 16; - ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); - - // Get sound buffer size - ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &audio_frames_per_block); - D(bug("DSP_GETBLKSIZE %d\n", audio_frames_per_block)); - return true; -} - -// Init using ESD, returns false on error -static bool open_esd(void) -{ -#ifdef ENABLE_ESD - int rate; - esd_format_t format = ESD_STREAM | ESD_PLAY; - - if (audio_sample_sizes.empty()) { - - // Default values - rate = 44100; - format |= (ESD_BITS16 | ESD_STEREO); - - } else { - - rate = audio_sample_rates[audio_sample_rate_index] >> 16; - if (audio_sample_sizes[audio_sample_size_index] == 8) - format |= ESD_BITS8; - else - format |= ESD_BITS16; - if (audio_channel_counts[audio_channel_count_index] == 1) - format |= ESD_MONO; - else - format |= ESD_STEREO; - } - -#if WORDS_BIGENDIAN - little_endian = false; -#else - little_endian = true; -#endif - silence_byte = 0; // Is this correct for 8-bit mode? - - // Open connection to ESD server - audio_fd = esd_play_stream(format, rate, NULL, NULL); - if (audio_fd < 0) { - fprintf(stderr, "WARNING: Cannot open ESD connection\n"); - return false; - } - - printf("Using ESD audio output\n"); - - // ESD supports a variety of twisted little audio formats, all different - if (audio_sample_sizes.empty()) { - - // The reason we do this here is that we don't want to add sample - // rates etc. unless the ESD server connection could be opened - // (if ESD fails, dsp might be tried next) - audio_sample_rates.push_back(11025 << 16); - audio_sample_rates.push_back(22050 << 16); - audio_sample_rates.push_back(44100 << 16); - audio_sample_sizes.push_back(8); - audio_sample_sizes.push_back(16); - audio_channel_counts.push_back(1); - audio_channel_counts.push_back(2); - - // Default to highest supported values - audio_sample_rate_index = audio_sample_rates.size() - 1; - audio_sample_size_index = audio_sample_sizes.size() - 1; - audio_channel_count_index = audio_channel_counts.size() - 1; - } - - // Sound buffer size = 4096 frames - audio_frames_per_block = 4096; - return true; -#else - // ESD is not enabled, shut up the compiler - return false; -#endif -} - -static bool open_audio(void) -{ -#ifdef ENABLE_ESD - // If ESPEAKER is set, the user probably wants to use ESD, so try that first - if (getenv("ESPEAKER")) - if (open_esd()) - goto dev_opened; -#endif - - // Try to open dsp - if (open_dsp()) - goto dev_opened; - -#ifdef ENABLE_ESD - // Hm, dsp failed so we try ESD again if ESPEAKER wasn't set - if (!getenv("ESPEAKER")) - if (open_esd()) - goto dev_opened; -#endif - - // No audio device succeeded - WarningAlert(GetString(STR_NO_AUDIO_WARN)); - return false; - - // Device opened, set AudioStatus -dev_opened: - sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * audio_channel_counts[audio_channel_count_index] * audio_frames_per_block; - set_audio_status_format(); - - // Start streaming thread - Set_pthread_attr(&stream_thread_attr, 0); - stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); - - // Everything went fine - audio_open = true; - return true; -} - -void AudioInit(void) -{ - // Init audio status (reasonable defaults) and feature flags - AudioStatus.sample_rate = 44100 << 16; - AudioStatus.sample_size = 16; - AudioStatus.channels = 2; - AudioStatus.mixer = 0; - AudioStatus.num_sources = 0; - audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut; - - // Sound disabled in prefs? Then do nothing - if (PrefsFindBool("nosound")) - return; - - // Init semaphore - if (sem_init(&audio_irq_done_sem, 0, 0) < 0) - return; - sem_inited = true; - - // Try to open the mixer device - const char *mixer = PrefsFindString("mixer"); - mixer_fd = open(mixer, O_RDWR); - if (mixer_fd < 0) - printf("WARNING: Cannot open %s (%s)\n", mixer, strerror(errno)); - - // Open and initialize audio device - open_audio(); -} - - -/* - * Deinitialization - */ - -static void close_audio(void) -{ - // Stop stream and delete semaphore - if (stream_thread_active) { - stream_thread_cancel = true; -#ifdef HAVE_PTHREAD_CANCEL - pthread_cancel(stream_thread); -#endif - pthread_join(stream_thread, NULL); - stream_thread_active = false; - } - - // Close dsp or ESD socket - if (audio_fd >= 0) { - close(audio_fd); - audio_fd = -1; - } - - audio_open = false; -} - -void AudioExit(void) -{ - // Stop the device immediately. Otherwise, close() sends - // SNDCTL_DSP_SYNC, which may hang - if (is_dsp_audio) - ioctl(audio_fd, SNDCTL_DSP_RESET, 0); - - // Close audio device - close_audio(); - - // Delete semaphore - if (sem_inited) { - sem_destroy(&audio_irq_done_sem); - sem_inited = false; - } - - // Close mixer device - if (mixer_fd >= 0) { - close(mixer_fd); - mixer_fd = -1; - } -} - - -/* - * First source added, start audio stream - */ - -void audio_enter_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Last source removed, stop audio stream - */ - -void audio_exit_stream() -{ - // Streaming thread is always running to avoid clicking noises -} - - -/* - * Streaming function - */ - -static void *stream_func(void *arg) -{ - int16 *silent_buffer = new int16[sound_buffer_size / 2]; - int16 *last_buffer = new int16[sound_buffer_size / 2]; - memset(silent_buffer, silence_byte, sound_buffer_size); - - while (!stream_thread_cancel) { - if (AudioStatus.num_sources) { - - // Trigger audio interrupt to get new buffer - D(bug("stream: triggering irq\n")); - SetInterruptFlag(INTFLAG_AUDIO); - TriggerInterrupt(); - D(bug("stream: waiting for ack\n")); - sem_wait(&audio_irq_done_sem); - D(bug("stream: ack received\n")); - - // Get size of audio data - uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { - int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; - D(bug("stream: work_size %d\n", work_size)); - if (work_size > sound_buffer_size) - work_size = sound_buffer_size; - if (work_size == 0) - goto silence; - - // Send data to DSP - if (work_size == sound_buffer_size && !little_endian) - write(audio_fd, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), sound_buffer_size); - else { - // Last buffer or little-endian DSP - if (little_endian) { - int16 *p = (int16 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)); - for (int i=0; i= 0) { - int vol; - if (ioctl(mixer_fd, SOUND_MIXER_READ_PCM, &vol) == 0) { - int left = vol >> 8; - int right = vol & 0xff; - return ((left * 256 / 100) << 16) | (right * 256 / 100); - } - } - return 0x01000100; -} - -bool audio_get_speaker_mute(void) -{ - return false; -} - -uint32 audio_get_speaker_volume(void) -{ - if (mixer_fd >= 0) { - int vol; - if (ioctl(mixer_fd, SOUND_MIXER_READ_VOLUME, &vol) == 0) { - int left = vol >> 8; - int right = vol & 0xff; - return ((left * 256 / 100) << 16) | (right * 256 / 100); - } - } - return 0x01000100; -} - -void audio_set_main_mute(bool mute) -{ -} - -void audio_set_main_volume(uint32 vol) -{ - if (mixer_fd >= 0) { - int left = vol >> 16; - int right = vol & 0xffff; - int p = ((left * 100 / 256) << 8) | (right * 100 / 256); - ioctl(mixer_fd, SOUND_MIXER_WRITE_PCM, &p); - } -} - -void audio_set_speaker_mute(bool mute) -{ -} - -void audio_set_speaker_volume(uint32 vol) -{ - if (mixer_fd >= 0) { - int left = vol >> 16; - int right = vol & 0xffff; - int p = ((left * 100 / 256) << 8) | (right * 100 / 256); - ioctl(mixer_fd, SOUND_MIXER_WRITE_VOLUME, &p); - } -} diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 3b834bb92..505e6b0de 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -25,9 +25,6 @@ dnl Mac OS X Sound AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no]) dnl Video options. -AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) -AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) -AC_ARG_ENABLE(fbdev-dga, [ --enable-fbdev-dga use direct frame buffer access via /dev/fb [default=yes]], [WANT_FBDEV_DGA=$enableval], [WANT_FBDEV_DGA=yes]) AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=yes]) dnl SDL options. @@ -71,7 +68,6 @@ AC_ARG_ENABLE(addressing, ]) dnl External packages. -AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes]) AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [case "$withval" in gtk1) WANT_GTK="gtk";; @@ -280,9 +276,6 @@ dnl Do we need SDL? WANT_SDL=no if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then WANT_SDL=yes - WANT_XF86_DGA=no - WANT_XF86_VIDMODE=no - WANT_FBDEV_DGA=no SDL_SUPPORT="$SDL_SUPPORT video" fi if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then @@ -350,15 +343,10 @@ else SDL_SUPPORT="none" fi -dnl We need X11, if not using SDL or Mac GUI. +dnl We need SDL or Mac GUI. if [[ "x$WANT_SDL_VIDEO" = "xno" -a "x$WANT_MACOSX_GUI" = "xno" ]]; then AC_PATH_XTRA - if [[ "x$no_x" = "xyes" ]]; then - AC_MSG_ERROR([You need X11 to run Basilisk II.]) - fi - CFLAGS="$CFLAGS $X_CFLAGS" - CXXFLAGS="$CXXFLAGS $X_CFLAGS" - LIBS="$LIBS $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS" + AC_MSG_ERROR([You need SDL or macOS to run Basilisk II.]) fi dnl BINCUE @@ -413,35 +401,6 @@ AC_CHECK_FUNCS(sem_init, , [ fi ]) -dnl We use DGA (XFree86 or fbdev) if possible. -if [[ "x$WANT_XF86_DGA" = "xyes" ]]; then - AC_CHECK_LIB(Xxf86dga, XF86DGAQueryExtension, [ - AC_DEFINE(ENABLE_XF86_DGA, 1, [Define if using XFree86 DGA extension.]) - LIBS="$LIBS -lXxf86dga" - if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then - AC_MSG_WARN([Cannot have both --enable-xf86-dga and --enable-fbdev-dga, ignoring --enable-fbdev-dga.]) - WANT_FBDEV_DGA=no - fi - ], [ - AC_MSG_WARN([Could not find XFree86 DGA extension, ignoring --enable-xf86-dga.]) - WANT_XF86_DGA=no - ]) -fi -if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then - AC_DEFINE(ENABLE_FBDEV_DGA, 1, [Define if using DGA with framebuffer device.]) -fi - -dnl We use XFree86 VidMode if possible. -if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then - AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, [ - AC_DEFINE(ENABLE_XF86_VIDMODE, 1, [Define if using XFree86 DGA extension.]) - LIBS="$LIBS -lXxf86vm" - ], [ - AC_MSG_WARN([Could not find XFree86 VidMode extension, ignoring --enable-xf86-vidmode.]) - WANT_XF86_VIDMODE=no - ]) -fi - dnl We use GTK+ if possible. UISRCS=../dummy/prefs_editor_dummy.cpp case "x$WANT_GTK" in @@ -494,19 +453,6 @@ if [[ "$WANT_GTK" = "no" ]]; then fi AC_SUBST(STANDALONE_GUI, [$WANT_STANDALONE_GUI]) -dnl We use ESD if possible. -if [[ "x$WANT_ESD" = "xyes" ]]; then - AM_PATH_ESD(0.2.8, [ - AC_DEFINE(ENABLE_ESD, 1, [Define is using ESD.]) - CFLAGS="$CFLAGS $ESD_CFLAGS" - CXXFLAGS="$CXXFLAGS $ESD_CFLAGS" - LIBS="$LIBS $ESD_LIBS" - ], [ - AC_MSG_WARN([Could not find ESD, disabling ESD support.]) - WANT_ESD=no - ]) -fi - dnl We use 64-bit file size support if possible. AC_SYS_LARGEFILE @@ -730,12 +676,10 @@ EXTRASYSSRCS= case "$target_os" in linux*) ETHERSRC=ether_unix.cpp - AUDIOSRC=audio_oss_esd.cpp SCSISRC=Linux/scsi_linux.cpp ;; freebsd*) ETHERSRC=ether_unix.cpp - AUDIOSRC=audio_oss_esd.cpp DEFINES="$DEFINES -DBSD_COMP" CXXFLAGS="$CXXFLAGS -fpermissive" dnl Check for the CAM library @@ -760,15 +704,9 @@ netbsd*) ETHERSRC=ether_unix.cpp ;; solaris*) - AUDIOSRC=Solaris/audio_solaris.cpp DEFINES="$DEFINES -DBSD_COMP -D_POSIX_PTHREAD_SEMANTICS" ;; irix*) - AUDIOSRC=Irix/audio_irix.cpp - EXTRASYSSRCS=Irix/unaligned.c - LIBS="$LIBS -laudio" - WANT_ESD=no - dnl Check if our compiler supports -IPA (MIPSPro) HAVE_IPA=no ocflags="$CFLAGS" @@ -885,7 +823,6 @@ if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then fi fi elif [[ "x$WANT_MACOSX_GUI" != "xyes" ]]; then - VIDEOSRCS="video_x.cpp" KEYCODES="keycodes" EXTRASYSSRCS="$EXTRASYSSRCS clip_unix.cpp" fi @@ -1818,11 +1755,7 @@ echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR echo BINCUE support ......................... : $have_bincue echo LIBVHD support ......................... : $have_libvhd echo VDE support ............................ : $have_vdeplug -echo XFree86 DGA support .................... : $WANT_XF86_DGA -echo XFree86 VidMode support ................ : $WANT_XF86_VIDMODE -echo fbdev DGA support ...................... : $WANT_FBDEV_DGA echo Enable video on SEGV signals ........... : $WANT_VOSF -echo ESD sound support ...................... : $WANT_ESD echo GTK user interface ..................... : $WANT_GTK echo mon debugger support ................... : $WANT_MON echo Use JIT compiler ....................... : $WANT_JIT diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index a1d9b7964..5df70a9d1 100755 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -31,10 +31,6 @@ # include #endif -#ifndef USE_SDL_VIDEO -# include -#endif - #ifdef HAVE_PTHREADS # include #endif @@ -54,11 +50,6 @@ # endif #endif -#ifdef ENABLE_XF86_DGA -# include -# include -#endif - #include using std::string; @@ -105,16 +96,6 @@ bool CPUIs68060; int FPUType; bool TwentyFourBitAddressing; - -// Global variables -#ifndef USE_SDL_VIDEO -extern char *x_display_name; // X11 display name -extern Display *x_display; // X11 display handle -#ifdef X11_LOCK_TYPE -X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT; // X11 display lock -#endif -#endif - static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes #ifdef HAVE_PTHREADS @@ -367,12 +348,6 @@ int main(int argc, char **argv) for (int i=1; ientry; -#ifdef ENABLE_FBDEV_DGA - l_fbdev_name = gtk_label_new(GetString(STR_FBDEV_NAME_CTRL)); - gtk_widget_show(l_fbdev_name); - gtk_table_attach(GTK_TABLE(table), l_fbdev_name, 0, 1, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - w_fbdev_name = gtk_entry_new(); - gtk_widget_show(w_fbdev_name); - gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name); - gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); - - w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile"); -#endif - make_separator(box); make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound)); - w_dspdevice_file = make_file_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp"); - w_mixerdevice_file = make_file_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer"); set_graphics_sensitive(); hide_show_graphics_widgets(); } - /* * "Input" pane */ diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp deleted file mode 100644 index df6e55aad..000000000 --- a/BasiliskII/src/Unix/video_x.cpp +++ /dev/null @@ -1,2690 +0,0 @@ -/* - * video_x.cpp - Video/graphics emulation, X11 specific stuff - * - * Basilisk II (C) Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * The Ctrl key works like a qualifier for special actions: - * Ctrl-Tab = suspend DGA mode - * Ctrl-Esc = emergency quit - * Ctrl-F1 = mount floppy - * Ctrl-F5 = grab mouse (in windowed mode) - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_PTHREADS -# include -#endif - -#ifdef ENABLE_XF86_DGA -# include -#endif - -#ifdef ENABLE_XF86_VIDMODE -# include -#endif - -#ifdef ENABLE_FBDEV_DGA -# include -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "adb.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" -#include "video_blit.h" - -#define DEBUG 0 -#include "debug.h" - - -// Supported video modes -static vector VideoModes; - -// Display types -enum { - DISPLAY_WINDOW, // X11 window, using MIT SHM extensions if possible - DISPLAY_DGA // DGA fullscreen display -}; - -// Constants -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; - -static const int win_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | ExposureMask | StructureNotifyMask; -static const int dga_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask; - - -// Global variables -static int32 frame_skip; // Prefs items -static int16 mouse_wheel_mode; -static int16 mouse_wheel_lines; - -static int display_type = DISPLAY_WINDOW; // See enum above -static bool local_X11; // Flag: X server running on local machine? -static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) -static uint32 the_buffer_size; // Size of allocated the_buffer - -static bool redraw_thread_active = false; // Flag: Redraw thread installed -#ifdef HAVE_PTHREADS -static pthread_attr_t redraw_thread_attr; // Redraw thread attributes -static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread -static volatile bool redraw_thread_cancel_ack; // Flag: Acknowledge for redraw thread cancellation -static pthread_t redraw_thread; // Redraw thread -#endif - -static bool has_dga = false; // Flag: Video DGA capable -static bool has_vidmode = false; // Flag: VidMode extension available - -#ifdef ENABLE_VOSF -static bool use_vosf = true; // Flag: VOSF enabled -#else -static const bool use_vosf = false; // VOSF not possible -#endif - -static bool ctrl_down = false; // Flag: Ctrl key pressed -static bool caps_on = false; // Flag: Caps Lock on -static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread -static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread -static bool emul_suspended = false; // Flag: Emulator suspended - -static bool classic_mode = false; // Flag: Classic Mac video mode - -static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms -static int keycode_table[256]; // X keycode -> Mac keycode translation table - -// X11 variables -char *x_display_name = NULL; // X11 display name -Display *x_display = NULL; // X11 display handle -static int screen; // Screen number -static Window rootwin; // Root window and our window -static int num_depths = 0; // Number of available X depths -static int *avail_depths = NULL; // List of available X depths -static XColor black, white; -static unsigned long black_pixel, white_pixel; -static int eventmask; - -static int xdepth; // Depth of X screen -static VisualFormat visualFormat; -static XVisualInfo visualInfo; -static Visual *vis; -static int color_class; - -static bool x_native_byte_order; // XImage has native byte order? -static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of DirectColor/TrueColor modes - -static Colormap cmap[2] = {0, 0}; // Colormaps for indexed modes (DGA needs two of them) - -static XColor x_palette[256]; // Color palette to be used as CLUT and gamma table -static bool x_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors - -#ifdef ENABLE_FBDEV_DGA -static int fbdev_fd = -1; -#endif - -#ifdef ENABLE_XF86_VIDMODE -static XF86VidModeModeInfo **x_video_modes = NULL; // Array of all available modes -static int num_x_video_modes; -#endif - -// Mutex to protect palette -#ifdef HAVE_PTHREADS -static pthread_mutex_t x_palette_lock = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_PALETTE pthread_mutex_lock(&x_palette_lock) -#define UNLOCK_PALETTE pthread_mutex_unlock(&x_palette_lock) -#else -#define LOCK_PALETTE -#define UNLOCK_PALETTE -#endif - -// Mutex to protect frame buffer -#ifdef HAVE_PTHREADS -static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_FRAME_BUFFER pthread_mutex_lock(&frame_buffer_lock); -#define UNLOCK_FRAME_BUFFER pthread_mutex_unlock(&frame_buffer_lock); -#else -#define LOCK_FRAME_BUFFER -#define UNLOCK_FRAME_BUFFER -#endif - -// Variables for non-VOSF incremental refresh -static const int sm_uptd[] = {4,1,6,3,0,5,2,7}; -static int sm_no_boxes[] = {1,8,32,64,128,300}; -static bool updt_box[17][17]; -static int nr_boxes; - -// Video refresh function -static void VideoRefreshInit(void); -static void (*video_refresh)(void); - - -// Prototypes -static void *redraw_func(void *arg); - -// From main_unix.cpp -extern char *x_display_name; -extern Display *x_display; - -// From sys_unix.cpp -extern void SysMountFirstFloppy(void); - -// From clip_unix.cpp -extern void ClipboardSelectionClear(XSelectionClearEvent *); -extern void ClipboardSelectionRequest(XSelectionRequestEvent *); - - -/* - * monitor_desc subclass for X11 display - */ - -class X11_monitor_desc : public monitor_desc { -public: - X11_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~X11_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * Utility functions - */ - -// Map video_mode depth ID to numerical depth value -static inline int depth_of_video_mode(video_mode const & mode) -{ - int depth = -1; - switch (mode.depth) { - case VDEPTH_1BIT: - depth = 1; - break; - case VDEPTH_2BIT: - depth = 2; - break; - case VDEPTH_4BIT: - depth = 4; - break; - case VDEPTH_8BIT: - depth = 8; - break; - case VDEPTH_16BIT: - depth = 16; - break; - case VDEPTH_32BIT: - depth = 32; - break; - default: - abort(); - } - return depth; -} - -// Map RGB color to pixel value (this only works in TrueColor/DirectColor visuals) -static inline uint32 map_rgb(uint8 red, uint8 green, uint8 blue, bool fix_byte_order = false) -{ - uint32 val = ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift); - if (fix_byte_order && !x_native_byte_order) { - // We have to fix byte order in the ExpandMap[] - // NOTE: this is only an optimization since Screen_blitter_init() - // could be arranged to choose an NBO or OBO (with - // byteswapping) Blit_Expand_X_To_Y() function - switch (visualFormat.depth) { - case 15: case 16: - val = do_byteswap_16(val); - break; - case 24: case 32: - val = do_byteswap_32(val); - break; - } - } - return val; -} - -// Do we have a visual for handling the specified Mac depth? If so, set the -// global variables "xdepth", "visualInfo", "vis" and "color_class". -static bool find_visual_for_depth(video_depth depth) -{ - D(bug("have_visual_for_depth(%d)\n", 1 << depth)); - - // 1-bit works always and uses default visual - if (depth == VDEPTH_1BIT) { - vis = DefaultVisual(x_display, screen); - visualInfo.visualid = XVisualIDFromVisual(vis); - int num = 0; - XVisualInfo *vi = XGetVisualInfo(x_display, VisualIDMask, &visualInfo, &num); - visualInfo = vi[0]; - XFree(vi); - xdepth = visualInfo.depth; - color_class = visualInfo.c_class; - D(bug(" found visual ID 0x%02x, depth %d\n", visualInfo.visualid, xdepth)); - return true; - } - - // Calculate minimum and maximum supported X depth - int min_depth = 1, max_depth = 32; - switch (depth) { -#ifdef ENABLE_VOSF - case VDEPTH_2BIT: - case VDEPTH_4BIT: // VOSF blitters can convert 2/4/8-bit -> 8/16/32-bit - case VDEPTH_8BIT: - min_depth = 8; - max_depth = 32; - break; -#else - case VDEPTH_2BIT: - case VDEPTH_4BIT: // 2/4-bit requires VOSF blitters - return false; - case VDEPTH_8BIT: // 8-bit without VOSF requires an 8-bit visual - min_depth = 8; - max_depth = 8; - break; -#endif - case VDEPTH_16BIT: // 16-bit requires a 15/16-bit visual - min_depth = 15; - max_depth = 16; - break; - case VDEPTH_32BIT: // 32-bit requires a 24/32-bit visual - min_depth = 24; - max_depth = 32; - break; - } - D(bug(" minimum required X depth is %d, maximum supported X depth is %d\n", min_depth, max_depth)); - - // Try to find a visual for one of the color depths - bool visual_found = false; - for (int i=0; i max_depth) - continue; - - // Determine best color class for this depth - switch (xdepth) { - case 1: // Try StaticGray or StaticColor - if (XMatchVisualInfo(x_display, screen, xdepth, StaticGray, &visualInfo) - || XMatchVisualInfo(x_display, screen, xdepth, StaticColor, &visualInfo)) - visual_found = true; - break; - case 8: // Need PseudoColor - if (XMatchVisualInfo(x_display, screen, xdepth, PseudoColor, &visualInfo)) - visual_found = true; - break; - case 15: - case 16: - case 24: - case 32: // Try DirectColor first, as this will allow gamma correction - if (XMatchVisualInfo(x_display, screen, xdepth, DirectColor, &visualInfo) - || XMatchVisualInfo(x_display, screen, xdepth, TrueColor, &visualInfo)) - visual_found = true; - break; - default: - D(bug(" not a supported depth\n")); - break; - } - } - if (!visual_found) - return false; - - // Visual was found - vis = visualInfo.visual; - color_class = visualInfo.c_class; - D(bug(" found visual ID 0x%02x, depth %d, class ", visualInfo.visualid, xdepth)); -#if DEBUG - switch (color_class) { - case StaticGray: D(bug("StaticGray\n")); break; - case GrayScale: D(bug("GrayScale\n")); break; - case StaticColor: D(bug("StaticColor\n")); break; - case PseudoColor: D(bug("PseudoColor\n")); break; - case TrueColor: D(bug("TrueColor\n")); break; - case DirectColor: D(bug("DirectColor\n")); break; - } -#endif - return true; -} - -// Add mode to list of supported modes -static void add_mode(uint32 width, uint32 height, uint32 resolution_id, uint32 bytes_per_row, video_depth depth) -{ - video_mode mode; - mode.x = width; - mode.y = height; - mode.resolution_id = resolution_id; - mode.bytes_per_row = bytes_per_row; - mode.depth = depth; - mode.user_data = 0; - VideoModes.push_back(mode); -} - -// Add standard list of windowed modes for given color depth -static void add_window_modes(video_depth depth) -{ - add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth); - add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth); - add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth); - add_mode(1024, 768, 0x83, TrivialBytesPerRow(1024, depth), depth); - add_mode(1152, 870, 0x84, TrivialBytesPerRow(1152, depth), depth); - add_mode(1280, 1024, 0x85, TrivialBytesPerRow(1280, depth), depth); - add_mode(1600, 1200, 0x86, TrivialBytesPerRow(1600, depth), depth); -} - -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -static void set_mac_frame_buffer(X11_monitor_desc &monitor, video_depth depth, bool native_byte_order) -{ -#if !DIRECT_ADDRESSING - int layout = FLAYOUT_DIRECT; - if (depth == VDEPTH_16BIT) - layout = (xdepth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; - else if (depth == VDEPTH_32BIT) - layout = (xdepth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; - if (native_byte_order) - MacFrameLayout = layout; - else - MacFrameLayout = FLAYOUT_DIRECT; - monitor.set_mac_frame_base(MacFrameBaseMac); - - // Set variables used by UAE memory banking - const video_mode &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; - MacFrameSize = mode.bytes_per_row * mode.y; - InitFrameBufferMapping(); -#else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); -#endif - D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); -} - -// Set window name and class -static void set_window_name(Window w, int name) -{ - const char *str = GetString(name); - XStoreName(x_display, w, str); - XSetIconName(x_display, w, str); - - XClassHint *hints; - hints = XAllocClassHint(); - if (hints) { - hints->res_name = "BasiliskII"; - hints->res_class = "BasiliskII"; - XSetClassHint(x_display, w, hints); - XFree(hints); - } -} - -// Set window input focus flag -static void set_window_focus(Window w) -{ - XWMHints *hints = XAllocWMHints(); - if (hints) { - hints->input = True; - hints->initial_state = NormalState; - hints->flags = InputHint | StateHint; - XSetWMHints(x_display, w, hints); - XFree(hints); - } -} - -// Set WM_DELETE_WINDOW protocol on window (preventing it from being destroyed by the WM when clicking on the "close" widget) -static Atom WM_DELETE_WINDOW = (Atom)0; -static void set_window_delete_protocol(Window w) -{ - WM_DELETE_WINDOW = XInternAtom(x_display, "WM_DELETE_WINDOW", false); - XSetWMProtocols(x_display, w, &WM_DELETE_WINDOW, 1); -} - -// Wait until window is mapped/unmapped -void wait_mapped(Window w) -{ - XEvent e; - do { - XMaskEvent(x_display, StructureNotifyMask, &e); - } while ((e.type != MapNotify) || (e.xmap.event != w)); -} - -void wait_unmapped(Window w) -{ - XEvent e; - do { - XMaskEvent(x_display, StructureNotifyMask, &e); - } while ((e.type != UnmapNotify) || (e.xmap.event != w)); -} - -// Trap SHM errors -static bool shm_error = false; -static int (*old_error_handler)(Display *, XErrorEvent *); - -static int error_handler(Display *d, XErrorEvent *e) -{ - if (e->error_code == BadAccess) { - shm_error = true; - return 0; - } else - return old_error_handler(d, e); -} - - -/* - * Framebuffer allocation routines - */ - -#ifdef ENABLE_VOSF -#include "vm_alloc.h" - -static void *vm_acquire_framebuffer(uint32 size) -{ - // always try to allocate framebuffer at the same address - static void *fb = VM_MAP_FAILED; - if (fb != VM_MAP_FAILED) { - if (vm_acquire_fixed(fb, size) < 0) - fb = VM_MAP_FAILED; - } - if (fb == VM_MAP_FAILED) - fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return fb; -} - -static inline void vm_release_framebuffer(void *fb, uint32 size) -{ - vm_release(fb, size); -} -#endif - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(X11_monitor_desc &m); - virtual ~driver_base(); - - virtual void update_palette(void); - virtual void suspend(void) {} - virtual void resume(void) {} - virtual void toggle_mouse_grab(void) {} - virtual void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } - - void disable_mouse_accel(void); - void restore_mouse_accel(void); - - virtual void grab_mouse(void) {} - virtual void ungrab_mouse(void) {} - -public: - X11_monitor_desc &monitor; // Associated video monitor - const video_mode &mode; // Video mode handled by the driver - - bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - Window w; // The window we draw into - - int orig_accel_numer, orig_accel_denom, orig_threshold; // Original mouse acceleration -}; - -class driver_window; -static void update_display_window_vosf(driver_window *drv); -static void update_display_dynamic(int ticker, driver_window *drv); -static void update_display_static(driver_window *drv); - -class driver_window : public driver_base { - friend void update_display_window_vosf(driver_window *drv); - friend void update_display_dynamic(int ticker, driver_window *drv); - friend void update_display_static(driver_window *drv); - -public: - driver_window(X11_monitor_desc &monitor); - ~driver_window(); - - void toggle_mouse_grab(void); - void mouse_moved(int x, int y); - - void grab_mouse(void); - void ungrab_mouse(void); - -private: - GC gc; - XImage *img; - bool have_shm; // Flag: SHM extensions available - XShmSegmentInfo shminfo; - Cursor mac_cursor; - bool mouse_grabbed; // Flag: mouse pointer grabbed, using relative mouse mode - int mouse_last_x, mouse_last_y; // Last mouse position (for relative mode) -}; - -class driver_dga; -static void update_display_dga_vosf(driver_dga *drv); - -class driver_dga : public driver_base { - friend void update_display_dga_vosf(driver_dga *drv); - -public: - driver_dga(X11_monitor_desc &monitor); - ~driver_dga(); - - void suspend(void); - void resume(void); - -protected: - struct FakeXImage { - int width, height; // size of image - int depth; // depth of image - int bytes_per_line; // accelerator to next line - - FakeXImage(int w, int h, int d) - : width(w), height(h), depth(d) - { bytes_per_line = TrivialBytesPerRow(width, DepthModeForPixelDepth(depth)); } - }; - FakeXImage *img; - -private: - Window suspend_win; // "Suspend" information window - void *fb_save; // Saved frame buffer for suspend/resume -}; - -static driver_base *drv = NULL; // Pointer to currently used driver object - -#ifdef ENABLE_VOSF -# include "video_vosf.h" -#endif - -driver_base::driver_base(X11_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false), w(0) -{ - the_buffer = NULL; - the_buffer_copy = NULL; - XGetPointerControl(x_display, &orig_accel_numer, &orig_accel_denom, &orig_threshold); -} - -driver_base::~driver_base() -{ - ungrab_mouse(); - restore_mouse_accel(); - - if (w) { - XUnmapWindow(x_display, w); - wait_unmapped(w); - XDestroyWindow(x_display, w); - } - - XFlush(x_display); - XSync(x_display, false); - - // Free frame buffer(s) - if (!use_vosf) { - if (the_buffer) { - free(the_buffer); - the_buffer = NULL; - } - if (the_buffer_copy) { - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#ifdef ENABLE_VOSF - else { - // the_buffer shall always be mapped through vm_acquire() so that we can vm_protect() it at will - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release_framebuffer(the_buffer, the_buffer_size); - the_buffer = NULL; - } - if (the_host_buffer) { - D(bug(" freeing the_host_buffer at %p\n", the_host_buffer)); - free(the_host_buffer); - the_host_buffer = NULL; - } - if (the_buffer_copy) { - D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#endif -} - -// Palette has changed -void driver_base::update_palette(void) -{ - if (color_class == PseudoColor || color_class == DirectColor) { - int num = vis->map_entries; - if (!IsDirectMode(monitor.get_current_mode()) && color_class == DirectColor) - return; // Indexed mode on true color screen, don't set CLUT - XStoreColors(x_display, cmap[0], x_palette, num); - XStoreColors(x_display, cmap[1], x_palette, num); - } - XSync(x_display, false); -} - -// Disable mouse acceleration -void driver_base::disable_mouse_accel(void) -{ - XChangePointerControl(x_display, True, False, 1, 1, 0); -} - -// Restore mouse acceleration to original value -void driver_base::restore_mouse_accel(void) -{ - XChangePointerControl(x_display, True, True, orig_accel_numer, orig_accel_denom, orig_threshold); -} - - -/* - * Windowed display driver - */ - -// Open display -driver_window::driver_window(X11_monitor_desc &m) - : driver_base(m), gc(0), img(NULL), have_shm(false), mac_cursor(0), - mouse_grabbed(false), mouse_last_x(0), mouse_last_y(0) -{ - int width = mode.x, height = mode.y; - int aligned_width = (width + 15) & ~15; - int aligned_height = (height + 15) & ~15; - - // Set absolute mouse mode - ADBSetRelMouseMode(mouse_grabbed); - - // Create window (setting background_pixel, border_pixel and colormap is - // mandatory when using a non-default visual; in 1-bit mode we use the - // default visual, so we can also use the default colormap) - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = win_eventmask; - wattr.background_pixel = (vis == DefaultVisual(x_display, screen) ? black_pixel : 0); - wattr.border_pixel = 0; - wattr.colormap = (mode.depth == VDEPTH_1BIT ? DefaultColormap(x_display, screen) : cmap[0]); - w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel | CWColormap, &wattr); - D(bug(" window created\n")); - - // Set window name/class - set_window_name(w, STR_WINDOW_TITLE); - - // Set window icons - set_window_icons(w); - - // Indicate that we want keyboard input - set_window_focus(w); - - // Set delete protocol property - set_window_delete_protocol(w); - - // Make window unresizable - { - XSizeHints *hints = XAllocSizeHints(); - if (hints) { - hints->min_width = width; - hints->max_width = width; - hints->min_height = height; - hints->max_height = height; - hints->flags = PMinSize | PMaxSize; - XSetWMNormalHints(x_display, w, hints); - XFree(hints); - } - } - D(bug(" window attributes set\n")); - - // Show window - XMapWindow(x_display, w); - wait_mapped(w); - D(bug(" window mapped\n")); - - // 1-bit mode is big-endian; if the X server is little-endian, we can't - // use SHM because that doesn't allow changing the image byte order - bool need_msb_image = (mode.depth == VDEPTH_1BIT && XImageByteOrder(x_display) == LSBFirst); - - // Try to create and attach SHM image - if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) { - - // Create SHM image ("height + 2" for safety) - img = XShmCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, &shminfo, width, height); - D(bug(" shm image created\n")); - shminfo.shmid = shmget(IPC_PRIVATE, (aligned_height + 2) * img->bytes_per_line, IPC_CREAT | 0777); - the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0); - shminfo.shmaddr = img->data = (char *)the_buffer_copy; - shminfo.readOnly = False; - - // Try to attach SHM image, catching errors - shm_error = false; - old_error_handler = XSetErrorHandler(error_handler); - XShmAttach(x_display, &shminfo); - XSync(x_display, false); - XSetErrorHandler(old_error_handler); - if (shm_error) { - shmdt(shminfo.shmaddr); - XDestroyImage(img); - img = NULL; - shminfo.shmid = -1; - } else { - have_shm = true; - shmctl(shminfo.shmid, IPC_RMID, 0); - } - D(bug(" shm image attached\n")); - } - - // Create normal X image if SHM doesn't work ("height + 2" for safety) - if (!have_shm) { - int bytes_per_row = (mode.depth == VDEPTH_1BIT ? aligned_width/8 : TrivialBytesPerRow(aligned_width, DepthModeForPixelDepth(xdepth))); - the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row); - img = XCreateImage(x_display, vis, mode.depth == VDEPTH_1BIT ? 1 : xdepth, mode.depth == VDEPTH_1BIT ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row); - D(bug(" X image created\n")); - } - - if (need_msb_image) { - img->byte_order = MSBFirst; - img->bitmap_bit_order = MSBFirst; - } - -#ifdef ENABLE_VOSF - use_vosf = true; - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer_copy; - the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); -#else - // Allocate memory for frame buffer - the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); -#endif - - // Create GC - gc = XCreateGC(x_display, w, 0, 0); - XSetState(x_display, gc, black_pixel, white_pixel, GXcopy, AllPlanes); - - // Create no_cursor - mac_cursor = XCreatePixmapCursor(x_display, - XCreatePixmap(x_display, w, 1, 1, 1), - XCreatePixmap(x_display, w, 1, 1, 1), - &black, &white, 0, 0); - XDefineCursor(x_display, w, mac_cursor); - - // Init blitting routines -#ifdef ENABLE_VOSF - Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); -#endif - - // Set frame buffer base - set_mac_frame_buffer(monitor, mode.depth, x_native_byte_order); - - // Everything went well - init_ok = true; -} - -// Close display -driver_window::~driver_window() -{ - if (have_shm) { - XShmDetach(x_display, &shminfo); -#ifdef ENABLE_VOSF - the_host_buffer = NULL; // don't free() in driver_base dtor -#else - the_buffer_copy = NULL; // don't free() in driver_base dtor -#endif - } - if (img) { - if (!have_shm) - img->data = NULL; - XDestroyImage(img); - } - if (have_shm) { - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - } - if (gc) - XFreeGC(x_display, gc); -} - -// Toggle mouse grab -void driver_window::toggle_mouse_grab(void) -{ - if (mouse_grabbed) - ungrab_mouse(); - else - grab_mouse(); -} - -// Grab mouse, switch to relative mouse mode -void driver_window::grab_mouse(void) -{ - int result; - for (int i=0; i<10; i++) { - result = XGrabPointer(x_display, w, True, 0, - GrabModeAsync, GrabModeAsync, w, None, CurrentTime); - if (result != AlreadyGrabbed) - break; - Delay_usec(100000); - } - if (result == GrabSuccess) { - XStoreName(x_display, w, GetString(STR_WINDOW_TITLE_GRABBED)); - ADBSetRelMouseMode(mouse_grabbed = true); - disable_mouse_accel(); - } -} - -// Ungrab mouse, switch to absolute mouse mode -void driver_window::ungrab_mouse(void) -{ - if (mouse_grabbed) { - XUngrabPointer(x_display, CurrentTime); - XStoreName(x_display, w, GetString(STR_WINDOW_TITLE)); - ADBSetRelMouseMode(mouse_grabbed = false); - restore_mouse_accel(); - } -} - -// Mouse moved -void driver_window::mouse_moved(int x, int y) -{ - if (!mouse_grabbed) { - mouse_last_x = x; mouse_last_y = y; - ADBMouseMoved(x, y); - return; - } - - // Warped mouse motion (this code is taken from SDL) - - // Post first mouse event - int width = monitor.get_current_mode().x, height = monitor.get_current_mode().y; - int delta_x = x - mouse_last_x, delta_y = y - mouse_last_y; - mouse_last_x = x; mouse_last_y = y; - ADBMouseMoved(delta_x, delta_y); - - // Only warp the pointer when it has reached the edge - const int MOUSE_FUDGE_FACTOR = 8; - if (x < MOUSE_FUDGE_FACTOR || x > (width - MOUSE_FUDGE_FACTOR) - || y < MOUSE_FUDGE_FACTOR || y > (height - MOUSE_FUDGE_FACTOR)) { - XEvent event; - while (XCheckTypedEvent(x_display, MotionNotify, &event)) { - delta_x = x - mouse_last_x; delta_y = y - mouse_last_y; - mouse_last_x = x; mouse_last_y = y; - ADBMouseMoved(delta_x, delta_y); - } - mouse_last_x = width/2; - mouse_last_y = height/2; - XWarpPointer(x_display, None, w, 0, 0, 0, 0, mouse_last_x, mouse_last_y); - for (int i=0; i<10; i++) { - XMaskEvent(x_display, PointerMotionMask, &event); - if (event.xmotion.x > (mouse_last_x - MOUSE_FUDGE_FACTOR) - && event.xmotion.x < (mouse_last_x + MOUSE_FUDGE_FACTOR) - && event.xmotion.y > (mouse_last_y - MOUSE_FUDGE_FACTOR) - && event.xmotion.y < (mouse_last_y + MOUSE_FUDGE_FACTOR)) - break; - } - } -} - - -#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA) -/* - * DGA display driver base class - */ - -driver_dga::driver_dga(X11_monitor_desc &m) - : driver_base(m), suspend_win(0), fb_save(NULL), img(NULL) -{ -} - -driver_dga::~driver_dga() -{ - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); - - if (img) - delete img; -} - -// Suspend emulation -void driver_dga::suspend(void) -{ - // Release ctrl key - ADBKeyUp(0x36); - ctrl_down = false; - - // Lock frame buffer (this will stop the MacOS thread) - LOCK_FRAME_BUFFER; - - // Save frame buffer - fb_save = malloc(mode.y * mode.bytes_per_row); - if (fb_save) - memcpy(fb_save, the_buffer, mode.y * mode.bytes_per_row); - - // Close full screen display -#ifdef ENABLE_XF86_DGA - XF86DGADirectVideo(x_display, screen, 0); -#endif - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); - restore_mouse_accel(); - XUnmapWindow(x_display, w); - wait_unmapped(w); - - // Open "suspend" window - XSetWindowAttributes wattr; - wattr.event_mask = KeyPressMask; - wattr.background_pixel = black_pixel; - - suspend_win = XCreateWindow(x_display, rootwin, 0, 0, 512, 1, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel, &wattr); - set_window_name(suspend_win, STR_SUSPEND_WINDOW_TITLE); - set_window_focus(suspend_win); - XMapWindow(x_display, suspend_win); - emul_suspended = true; -} - -// Resume emulation -void driver_dga::resume(void) -{ - // Close "suspend" window - XDestroyWindow(x_display, suspend_win); - XSync(x_display, false); - - // Reopen full screen display - XMapRaised(x_display, w); - wait_mapped(w); - XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0); - XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - disable_mouse_accel(); -#ifdef ENABLE_XF86_DGA - XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse); - XF86DGASetViewPort(x_display, screen, 0, 0); -#endif - XSync(x_display, false); - - // the_buffer already contains the data to restore. i.e. since a temporary - // frame buffer is used when VOSF is actually used, fb_save is therefore - // not necessary. -#ifdef ENABLE_VOSF - if (use_vosf) { - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } -#endif - - // Restore frame buffer - if (fb_save) { -#ifdef ENABLE_VOSF - // Don't copy fb_save to the temporary frame buffer in VOSF mode - if (!use_vosf) -#endif - memcpy(the_buffer, fb_save, mode.y * mode.bytes_per_row); - free(fb_save); - fb_save = NULL; - } - - // Unlock frame buffer (and continue MacOS thread) - UNLOCK_FRAME_BUFFER; - emul_suspended = false; -} -#endif - - -#ifdef ENABLE_FBDEV_DGA -/* - * fbdev DGA display driver - */ - -const char FBDEVICES_FILE_NAME[] = DATADIR "/fbdevices"; -const char FBDEVICE_FILE_NAME[] = "/dev/fb"; - -class driver_fbdev : public driver_dga { -public: - driver_fbdev(X11_monitor_desc &monitor); - ~driver_fbdev(); -}; - -// Open display -driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m) -{ - int width = mode.x, height = mode.y; - - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Find the maximum depth available - int ndepths, max_depth(0); - int *depths = XListDepths(x_display, screen, &ndepths); - if (depths == NULL) { - printf("FATAL: Could not determine the maximal depth available\n"); - return; - } else { - while (ndepths-- > 0) { - if (depths[ndepths] > max_depth) - max_depth = depths[ndepths]; - } - } - - // Get fbdevices file path from preferences - const char *fbd_path = PrefsFindString("fbdevicefile"); - - // Open fbdevices file - FILE *fp = fopen(fbd_path ? fbd_path : FBDEVICES_FILE_NAME, "r"); - if (fp == NULL) { - char str[256]; - sprintf(str, GetString(STR_NO_FBDEVICE_FILE_ERR), fbd_path ? fbd_path : FBDEVICES_FILE_NAME, strerror(errno)); - ErrorAlert(str); - return; - } - - int fb_depth; // supported depth - uint32 fb_offset; // offset used for mmap(2) - char fb_name[20]; - char line[256]; - bool device_found = false; - while (fgets(line, 255, fp)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len - 1] = '\0'; - - // Comments begin with "#" or ";" - if ((line[0] == '#') || (line[0] == ';') || (line[0] == '\0')) - continue; - - if ((sscanf(line, "%19s %d %x", fb_name, &fb_depth, &fb_offset) == 3) - && (strcmp(fb_name, fb_name) == 0) && (fb_depth == max_depth)) { - device_found = true; - break; - } - } - - // fbdevices file completely read - fclose(fp); - - // Frame buffer name not found ? Then, display warning - if (!device_found) { - char str[256]; - sprintf(str, GetString(STR_FBDEV_NAME_ERR), fb_name, max_depth); - ErrorAlert(str); - return; - } - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = dga_eventmask; - wattr.background_pixel = white_pixel; - wattr.override_redirect = True; - wattr.colormap = cmap[0]; - - w = XCreateWindow(x_display, rootwin, - 0, 0, width, height, - 0, xdepth, InputOutput, vis, - CWEventMask | CWBackPixel | CWOverrideRedirect | (fb_depth <= 8 ? CWColormap : 0), - &wattr); - - // Set window name/class - set_window_name(w, STR_WINDOW_TITLE); - - // Indicate that we want keyboard input - set_window_focus(w); - - // Show window - XMapRaised(x_display, w); - wait_mapped(w); - - // Grab mouse and keyboard - XGrabKeyboard(x_display, w, True, - GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, w, True, - PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, w, None, CurrentTime); - disable_mouse_accel(); - - // Calculate bytes per row - int bytes_per_row = TrivialBytesPerRow(mode.x, mode.depth); - - // Map frame buffer - the_buffer_size = height * bytes_per_row; - if ((the_buffer = (uint8 *) mmap(NULL, the_buffer_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fbdev_fd, fb_offset)) == MAP_FAILED) { - if ((the_buffer = (uint8 *) mmap(NULL, the_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbdev_fd, fb_offset)) == MAP_FAILED) { - char str[256]; - sprintf(str, GetString(STR_FBDEV_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - return; - } - } - -#if ENABLE_VOSF -#if DIRECT_ADDRESSING - // Screen_blitter_init() returns TRUE if VOSF is mandatory - // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(visualFormat, true, mode.depth); - - if (use_vosf) { - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer; - the_buffer_size = page_extend((height + 2) * bytes_per_row); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - - // Fake image for DGA/VOSF mode to know about display bounds - img = new FakeXImage(width, height, depth_of_video_mode(mode)); - } -#else - use_vosf = false; -#endif -#endif - - // Set frame buffer base - const_cast(&mode)->bytes_per_row = bytes_per_row; - const_cast(&mode)->depth = DepthModeForPixelDepth(fb_depth); - set_mac_frame_buffer(monitor, mode.depth, true); - - // Everything went well - init_ok = true; -} - -// Close display -driver_fbdev::~driver_fbdev() -{ - if (!use_vosf) { - if (the_buffer != MAP_FAILED) { - // don't free() the screen buffer in driver_base dtor - munmap(the_buffer, the_buffer_size); - the_buffer = NULL; - } - } -#ifdef ENABLE_VOSF - else { - if (the_host_buffer != MAP_FAILED) { - // don't free() the screen buffer in driver_base dtor - munmap(the_host_buffer, the_buffer_size); - the_host_buffer = NULL; - } - } -#endif -} -#endif - - -#ifdef ENABLE_XF86_DGA -/* - * XFree86 DGA display driver - */ - -class driver_xf86dga : public driver_dga { -public: - driver_xf86dga(X11_monitor_desc &monitor); - ~driver_xf86dga(); - - void update_palette(void); - void resume(void); - -private: - int current_dga_cmap; // Number (0 or 1) of currently installed DGA colormap -}; - -// Open display -driver_xf86dga::driver_xf86dga(X11_monitor_desc &m) - : driver_dga(m), current_dga_cmap(0) -{ - int width = mode.x, height = mode.y; - - // Set relative mouse mode - ADBSetRelMouseMode(true); - -#ifdef ENABLE_XF86_VIDMODE - // Switch to best mode - if (has_vidmode) { - int best = 0; - for (int i=1; ihdisplay >= width && x_video_modes[i]->vdisplay >= height && - x_video_modes[i]->hdisplay <= x_video_modes[best]->hdisplay && x_video_modes[i]->vdisplay <= x_video_modes[best]->vdisplay) { - best = i; - } - } - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[best]); - XF86VidModeSetViewPort(x_display, screen, 0, 0); - XSync(x_display, false); - } -#endif - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = dga_eventmask; - wattr.override_redirect = True; - wattr.colormap = (mode.depth == VDEPTH_1BIT ? DefaultColormap(x_display, screen) : cmap[0]); - - w = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWOverrideRedirect | - (color_class == DirectColor ? CWColormap : 0), &wattr); - - // Set window name/class - set_window_name(w, STR_WINDOW_TITLE); - - // Indicate that we want keyboard input - set_window_focus(w); - - // Show window - XMapRaised(x_display, w); - wait_mapped(w); - - // Establish direct screen connection - XMoveResizeWindow(x_display, w, 0, 0, width, height); - XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0); - XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - disable_mouse_accel(); - - int v_width, v_bank, v_size; - XF86DGAGetVideo(x_display, screen, (char **)&the_buffer, &v_width, &v_bank, &v_size); - XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse); - XF86DGASetViewPort(x_display, screen, 0, 0); - XF86DGASetVidPage(x_display, screen, 0); - - // Set colormap - if (!IsDirectMode(mode)) { - XSetWindowColormap(x_display, w, cmap[current_dga_cmap = 0]); - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); - } - XSync(x_display, false); - - // Init blitting routines - int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, mode.depth); -#if ENABLE_VOSF -#if DIRECT_ADDRESSING - // Screen_blitter_init() returns TRUE if VOSF is mandatory - // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(visualFormat, x_native_byte_order, depth_of_video_mode(mode)); - - if (use_vosf) { - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer; - the_buffer_size = page_extend((height + 2) * bytes_per_row); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - - // Fake image for DGA/VOSF mode to know about display bounds - img = new FakeXImage((v_width + 7) & ~7, height, depth_of_video_mode(mode)); - } -#else - use_vosf = false; -#endif -#endif - - // Set frame buffer base - const_cast(&mode)->bytes_per_row = bytes_per_row; - set_mac_frame_buffer(monitor, mode.depth, true); - - // Everything went well - init_ok = true; -} - -// Close display -driver_xf86dga::~driver_xf86dga() -{ - XF86DGADirectVideo(x_display, screen, 0); - if (!use_vosf) { - // don't free() the screen buffer in driver_base dtor - the_buffer = NULL; - } -#ifdef ENABLE_VOSF - else { - // don't free() the screen buffer in driver_base dtor - the_host_buffer = NULL; - } -#endif -#ifdef ENABLE_XF86_VIDMODE - if (has_vidmode) - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]); -#endif -} - -// Palette has changed -void driver_xf86dga::update_palette(void) -{ - driver_dga::update_palette(); - current_dga_cmap ^= 1; - if (!IsDirectMode(monitor.get_current_mode()) && cmap[current_dga_cmap]) - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); -} - -// Resume emulation -void driver_xf86dga::resume(void) -{ - driver_dga::resume(); - if (!IsDirectMode(monitor.get_current_mode())) - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); -} -#endif - - -/* - * Initialization - */ - -// Init keycode translation table -static void keycode_init(void) -{ - bool use_kc = PrefsFindBool("keycodes"); - if (use_kc) { - - // Get keycode file path from preferences - const char *kc_path = PrefsFindString("keycodefile"); - - // Open keycode table - FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); - if (f == NULL) { - char str[256]; - sprintf(str, GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); - WarningAlert(str); - return; - } - - // Default translation table - for (int i=0; i<256; i++) - keycode_table[i] = -1; - - // Search for server vendor string, then read keycodes - const char *vendor = ServerVendor(x_display); - // Force use of MacX mappings on MacOS X with Apple's X server - int dummy; - if (XQueryExtension(x_display, "Apple-DRI", &dummy, &dummy, &dummy)) - vendor = "MacX"; - bool vendor_found = false; - char line[256]; - while (fgets(line, 255, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - - // Comments begin with "#" or ";" - if (line[0] == '#' || line[0] == ';' || line[0] == 0) - continue; - - if (vendor_found) { - // Read keycode - int x_code, mac_code; - if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) - keycode_table[x_code & 0xff] = mac_code; - else - break; - } else { - // Search for vendor string - if (strstr(vendor, line) == vendor) - vendor_found = true; - } - } - - // Keycode file completely read - fclose(f); - use_keycodes = vendor_found; - - // Vendor not found? Then display warning - if (!vendor_found) { - char str[256]; - sprintf(str, GetString(STR_KEYCODE_VENDOR_WARN), vendor, kc_path ? kc_path : KEYCODE_FILE_NAME); - WarningAlert(str); - return; - } - } -} - -// Open display for current mode -bool X11_monitor_desc::video_open(void) -{ - D(bug("video_open()\n")); - const video_mode &mode = get_current_mode(); - - // Find best available X visual - if (!find_visual_for_depth(mode.depth)) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Determine the byte order of an XImage content -#ifdef WORDS_BIGENDIAN - x_native_byte_order = (XImageByteOrder(x_display) == MSBFirst); -#else - x_native_byte_order = (XImageByteOrder(x_display) == LSBFirst); -#endif - - // Build up visualFormat structure - visualFormat.fullscreen = (display_type == DISPLAY_DGA); - visualFormat.depth = visualInfo.depth; - visualFormat.Rmask = visualInfo.red_mask; - visualFormat.Gmask = visualInfo.green_mask; - visualFormat.Bmask = visualInfo.blue_mask; - - // Create color maps - if (color_class == PseudoColor || color_class == DirectColor) { - cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocAll); - cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocAll); - } else { - cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocNone); - cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocNone); - } - - // Find pixel format of direct modes - if (color_class == DirectColor || color_class == TrueColor) { - rshift = gshift = bshift = 0; - rloss = gloss = bloss = 8; - uint32 mask; - for (mask=vis->red_mask; !(mask&1); mask>>=1) - ++rshift; - for (; mask&1; mask>>=1) - --rloss; - for (mask=vis->green_mask; !(mask&1); mask>>=1) - ++gshift; - for (; mask&1; mask>>=1) - --gloss; - for (mask=vis->blue_mask; !(mask&1); mask>>=1) - ++bshift; - for (; mask&1; mask>>=1) - --bloss; - } - - // Preset palette pixel values for CLUT or gamma table - if (color_class == DirectColor) { - int num = vis->map_entries; - for (int i=0; imap_entries : 256); - for (int i=0; i16/32 expand map - if (!IsDirectMode(mode) && xdepth > 8) - for (int i=0; i<256; i++) - ExpandMap[i] = map_rgb(i, i, i, true); -#endif - - // Create display driver object of requested type - switch (display_type) { - case DISPLAY_WINDOW: - drv = new driver_window(*this); - break; -#ifdef ENABLE_FBDEV_DGA - case DISPLAY_DGA: - drv = new driver_fbdev(*this); - break; -#endif -#ifdef ENABLE_XF86_DGA - case DISPLAY_DGA: - drv = new driver_xf86dga(*this); - break; -#endif - } - if (drv == NULL) - return false; - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Initialize the VOSF system - if (!video_vosf_init(*this)) { - ErrorAlert(STR_VOSF_INIT_ERR); - return false; - } - } -#endif - - // Initialize VideoRefresh function - VideoRefreshInit(); - - // Lock down frame buffer - XSync(x_display, false); - LOCK_FRAME_BUFFER; - - // Start redraw/input thread -#ifdef USE_PTHREADS_SERVICES - redraw_thread_cancel = false; - Set_pthread_attr(&redraw_thread_attr, 0); - redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0); - if (!redraw_thread_active) { - printf("FATAL: cannot create redraw thread\n"); - return false; - } -#else - redraw_thread_active = true; -#endif - - return true; -} - -bool VideoInit(bool classic) -{ - classic_mode = classic; - -#ifdef ENABLE_VOSF - // Zero the mainBuffer structure - mainBuffer.dirtyPages = NULL; - mainBuffer.pageInfo = NULL; -#endif - - // Check if X server runs on local machine - local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0) - || (strncmp(XDisplayName(x_display_name), "/", 1) == 0) - || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0); - - // Init keycode translation - keycode_init(); - - // Read prefs - frame_skip = PrefsFindInt32("frameskip"); - mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); - mouse_wheel_lines = PrefsFindInt32("mousewheellines"); - - // Find screen and root window - screen = XDefaultScreen(x_display); - rootwin = XRootWindow(x_display, screen); - - // Get sorted list of available depths - avail_depths = XListDepths(x_display, screen, &num_depths); - if (avail_depths == NULL) { - ErrorAlert(STR_UNSUPP_DEPTH_ERR); - return false; - } - std::sort(avail_depths, avail_depths + num_depths); - -#ifdef ENABLE_FBDEV_DGA - // Frame buffer name - char fb_name[20]; - - // Could do fbdev DGA? - if ((fbdev_fd = open(FBDEVICE_FILE_NAME, O_RDWR)) != -1) - has_dga = true; - else - has_dga = false; -#endif - -#ifdef ENABLE_XF86_DGA - // DGA available? - int dga_event_base, dga_error_base; - if (local_X11 && XF86DGAQueryExtension(x_display, &dga_event_base, &dga_error_base)) { - int dga_flags = 0; - XF86DGAQueryDirectVideo(x_display, screen, &dga_flags); - has_dga = dga_flags & XF86DGADirectPresent; - } else - has_dga = false; -#endif - -#ifdef ENABLE_XF86_VIDMODE - // VidMode available? - int vm_event_base, vm_error_base; - has_vidmode = XF86VidModeQueryExtension(x_display, &vm_event_base, &vm_error_base); - if (has_vidmode) - XF86VidModeGetAllModeLines(x_display, screen, &num_x_video_modes, &x_video_modes); -#endif - - // Find black and white colors - XParseColor(x_display, DefaultColormap(x_display, screen), "rgb:00/00/00", &black); - XAllocColor(x_display, DefaultColormap(x_display, screen), &black); - XParseColor(x_display, DefaultColormap(x_display, screen), "rgb:ff/ff/ff", &white); - XAllocColor(x_display, DefaultColormap(x_display, screen), &white); - black_pixel = BlackPixel(x_display, screen); - white_pixel = WhitePixel(x_display, screen); - - // Get screen mode from preferences - const char *mode_str; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width = 512, default_height = 384; - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) { - display_type = DISPLAY_WINDOW; -#ifdef ENABLE_FBDEV_DGA - } else if (has_dga && sscanf(mode_str, "dga/%19s", fb_name) == 1) { - display_type = DISPLAY_DGA; - default_width = -1; default_height = -1; // use entire screen -#endif -#ifdef ENABLE_XF86_DGA - } else if (has_dga && sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) { - display_type = DISPLAY_DGA; -#endif - } - } - if (default_width <= 0) - default_width = DisplayWidth(x_display, screen); - else if (default_width > DisplayWidth(x_display, screen)) - default_width = DisplayWidth(x_display, screen); - if (default_height <= 0) - default_height = DisplayHeight(x_display, screen); - else if (default_height > DisplayHeight(x_display, screen)) - default_height = DisplayHeight(x_display, screen); - - // Mac screen depth follows X depth - video_depth default_depth = VDEPTH_1BIT; - switch (DefaultDepth(x_display, screen)) { - case 8: - default_depth = VDEPTH_8BIT; - break; - case 15: case 16: - default_depth = VDEPTH_16BIT; - break; - case 24: case 32: - default_depth = VDEPTH_32BIT; - break; - } - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); - else { - for (unsigned d=VDEPTH_1BIT; d<=VDEPTH_32BIT; d++) { - if (find_visual_for_depth(video_depth(d))) - add_window_modes(video_depth(d)); - } - } - } else - add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); - if (VideoModes.empty()) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - if (i->x == default_width && i->y == default_height && i->depth == default_depth) { - default_id = i->resolution_id; - break; - } - } - if (i == end) { // not found, use first available mode - default_depth = VideoModes[0].depth; - default_id = VideoModes[0].resolution_id; - } - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - int bits = 1 << i->depth; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits)); - } -#endif - - // Create X11_monitor_desc for this (the only) display - X11_monitor_desc *monitor = new X11_monitor_desc(VideoModes, default_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - - -/* - * Deinitialization - */ - -// Close display -void X11_monitor_desc::video_close(void) -{ - D(bug("video_close()\n")); - - // Stop redraw thread -#ifdef USE_PTHREADS_SERVICES - if (redraw_thread_active) { - redraw_thread_cancel = true; - redraw_thread_cancel_ack = false; - pthread_join(redraw_thread, NULL); - while (!redraw_thread_cancel_ack) ; - } -#endif - redraw_thread_active = false; - - // Unlock frame buffer - UNLOCK_FRAME_BUFFER; - XSync(x_display, false); - D(bug(" frame buffer unlocked\n")); - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - // Close display - delete drv; - drv = NULL; - - // Free colormaps - if (cmap[0]) { - XFreeColormap(x_display, cmap[0]); - cmap[0] = 0; - } - if (cmap[1]) { - XFreeColormap(x_display, cmap[1]); - cmap[1] = 0; - } -} - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); - -#ifdef ENABLE_XF86_VIDMODE - // Free video mode list - if (x_video_modes) { - XFree(x_video_modes); - x_video_modes = NULL; - } -#endif - -#ifdef ENABLE_FBDEV_DGA - // Close framebuffer device - if (fbdev_fd >= 0) { - close(fbdev_fd); - fbdev_fd = -1; - } -#endif - - // Free depth list - if (avail_depths) { - XFree(avail_depths); - avail_depths = NULL; - } -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - quit_full_screen = true; -} - - -/* - * Mac VBL interrupt - */ - -void VideoInterrupt(void) -{ - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; -} - - -/* - * Set palette - */ - -void X11_monitor_desc::set_palette(uint8 *pal, int num_in) -{ - const video_mode &mode = get_current_mode(); - - LOCK_PALETTE; - - // Convert colors to XColor array - int num_out = 256; - bool stretch = false; - if (IsDirectMode(mode)) { - // If X is in 565 mode we have to stretch the gamma table from 32 to 64 entries - num_out = vis->map_entries; - stretch = true; - } - XColor *p = x_palette; - for (int i=0; ired = pal[c*3 + 0] * 0x0101; - p->green = pal[c*3 + 1] * 0x0101; - p->blue = pal[c*3 + 2] * 0x0101; - p++; - } - -#ifdef ENABLE_VOSF - // Recalculate pixel color expansion map - if (!IsDirectMode(mode) && xdepth > 8) { - for (int i=0; i<256; i++) { - int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) - ExpandMap[i] = map_rgb(pal[c*3+0], pal[c*3+1], pal[c*3+2], true); - } - - // We have to redraw everything because the interpretation of pixel values changed - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } -#endif - - // Tell redraw thread to change palette - x_palette_changed = true; - - UNLOCK_PALETTE; -} - - -/* - * Switch video mode - */ - -void X11_monitor_desc::switch_to_current_mode(void) -{ - // Close and reopen display - video_close(); - video_open(); - - if (drv == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Translate key event to Mac keycode, returns -1 if no keycode was found - * and -2 if the key was recognized as a hotkey - */ - -static int kc_decode(KeySym ks, bool key_down) -{ - switch (ks) { - case XK_A: case XK_a: return 0x00; - case XK_B: case XK_b: return 0x0b; - case XK_C: case XK_c: return 0x08; - case XK_D: case XK_d: return 0x02; - case XK_E: case XK_e: return 0x0e; - case XK_F: case XK_f: return 0x03; - case XK_G: case XK_g: return 0x05; - case XK_H: case XK_h: return 0x04; - case XK_I: case XK_i: return 0x22; - case XK_J: case XK_j: return 0x26; - case XK_K: case XK_k: return 0x28; - case XK_L: case XK_l: return 0x25; - case XK_M: case XK_m: return 0x2e; - case XK_N: case XK_n: return 0x2d; - case XK_O: case XK_o: return 0x1f; - case XK_P: case XK_p: return 0x23; - case XK_Q: case XK_q: return 0x0c; - case XK_R: case XK_r: return 0x0f; - case XK_S: case XK_s: return 0x01; - case XK_T: case XK_t: return 0x11; - case XK_U: case XK_u: return 0x20; - case XK_V: case XK_v: return 0x09; - case XK_W: case XK_w: return 0x0d; - case XK_X: case XK_x: return 0x07; - case XK_Y: case XK_y: return 0x10; - case XK_Z: case XK_z: return 0x06; - - case XK_1: case XK_exclam: return 0x12; - case XK_2: case XK_at: return 0x13; - case XK_3: case XK_numbersign: return 0x14; - case XK_4: case XK_dollar: return 0x15; - case XK_5: case XK_percent: return 0x17; - case XK_6: return 0x16; - case XK_7: return 0x1a; - case XK_8: return 0x1c; - case XK_9: return 0x19; - case XK_0: return 0x1d; - - case XK_grave: case XK_asciitilde: return 0x0a; - case XK_minus: case XK_underscore: return 0x1b; - case XK_equal: case XK_plus: return 0x18; - case XK_bracketleft: case XK_braceleft: return 0x21; - case XK_bracketright: case XK_braceright: return 0x1e; - case XK_backslash: case XK_bar: return 0x2a; - case XK_semicolon: case XK_colon: return 0x29; - case XK_apostrophe: case XK_quotedbl: return 0x27; - case XK_comma: case XK_less: return 0x2b; - case XK_period: case XK_greater: return 0x2f; - case XK_slash: case XK_question: return 0x2c; - - case XK_Tab: if (ctrl_down) {if (key_down) drv->suspend(); return -2;} else return 0x30; - case XK_Return: return 0x24; - case XK_space: return 0x31; - case XK_BackSpace: return 0x33; - - case XK_Delete: return 0x75; - case XK_Insert: return 0x72; - case XK_Home: case XK_Help: return 0x73; - case XK_End: return 0x77; -#ifdef __hpux - case XK_Prior: return 0x74; - case XK_Next: return 0x79; -#else - case XK_Page_Up: return 0x74; - case XK_Page_Down: return 0x79; -#endif - - case XK_Control_L: return 0x36; - case XK_Control_R: return 0x36; - case XK_Shift_L: return 0x38; - case XK_Shift_R: return 0x38; - case XK_Alt_L: return 0x37; - case XK_Alt_R: return 0x37; - case XK_Meta_L: return 0x3a; - case XK_Meta_R: return 0x3a; - case XK_Menu: return 0x32; - case XK_Caps_Lock: return 0x39; - case XK_Num_Lock: return 0x47; - - case XK_Up: return 0x3e; - case XK_Down: return 0x3d; - case XK_Left: return 0x3b; - case XK_Right: return 0x3c; - - case XK_Escape: if (ctrl_down) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35; - - case XK_F1: if (ctrl_down) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a; - case XK_F2: return 0x78; - case XK_F3: return 0x63; - case XK_F4: return 0x76; - case XK_F5: if (ctrl_down) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60; - case XK_F6: return 0x61; - case XK_F7: return 0x62; - case XK_F8: return 0x64; - case XK_F9: return 0x65; - case XK_F10: return 0x6d; - case XK_F11: return 0x67; - case XK_F12: return 0x6f; - - case XK_Print: return 0x69; - case XK_Scroll_Lock: return 0x6b; - case XK_Pause: return 0x71; - -#if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End) - case XK_KP_0: case XK_KP_Insert: return 0x52; - case XK_KP_1: case XK_KP_End: return 0x53; - case XK_KP_2: case XK_KP_Down: return 0x54; - case XK_KP_3: case XK_KP_Next: return 0x55; - case XK_KP_4: case XK_KP_Left: return 0x56; - case XK_KP_5: case XK_KP_Begin: return 0x57; - case XK_KP_6: case XK_KP_Right: return 0x58; - case XK_KP_7: case XK_KP_Home: return 0x59; - case XK_KP_8: case XK_KP_Up: return 0x5b; - case XK_KP_9: case XK_KP_Prior: return 0x5c; - case XK_KP_Decimal: case XK_KP_Delete: return 0x41; -#else - case XK_KP_0: return 0x52; - case XK_KP_1: return 0x53; - case XK_KP_2: return 0x54; - case XK_KP_3: return 0x55; - case XK_KP_4: return 0x56; - case XK_KP_5: return 0x57; - case XK_KP_6: return 0x58; - case XK_KP_7: return 0x59; - case XK_KP_8: return 0x5b; - case XK_KP_9: return 0x5c; - case XK_KP_Decimal: return 0x41; -#endif - case XK_KP_Add: return 0x45; - case XK_KP_Subtract: return 0x4e; - case XK_KP_Multiply: return 0x43; - case XK_KP_Divide: return 0x4b; - case XK_KP_Enter: return 0x4c; - case XK_KP_Equal: return 0x51; - } - return -1; -} - -static int event2keycode(XKeyEvent &ev, bool key_down) -{ - KeySym ks; - int i = 0; - - do { - ks = XLookupKeysym(&ev, i++); - int as = kc_decode(ks, key_down); - if (as >= 0) - return as; - if (as == -2) - return as; - } while (ks != NoSymbol); - - return -1; -} - - -/* - * X event handling - */ - -static void handle_events(void) -{ - for (;;) { - XEvent event; - XDisplayLock(); - - if (!XCheckMaskEvent(x_display, eventmask, &event)) { - // Handle clipboard events - if (XCheckTypedEvent(x_display, SelectionRequest, &event)) - ClipboardSelectionRequest(&event.xselectionrequest); - else if (XCheckTypedEvent(x_display, SelectionClear, &event)) - ClipboardSelectionClear(&event.xselectionclear); - - // Window "close" widget clicked - else if (XCheckTypedEvent(x_display, ClientMessage, &event)) { - if (event.xclient.format == 32 && event.xclient.data.l[0] == WM_DELETE_WINDOW) { - ADBKeyDown(0x7f); // Power key - ADBKeyUp(0x7f); - } - } - XDisplayUnlock(); - break; - } - - switch (event.type) { - - // Mouse button - case ButtonPress: { - unsigned int button = event.xbutton.button; - if (button < 4) - ADBMouseDown(button - 1); - else if (button < 6) { // Wheel mouse - if (mouse_wheel_mode == 0) { - int key = (button == 5) ? 0x79 : 0x74; // Page up/down - ADBKeyDown(key); - ADBKeyUp(key); - } else { - int key = (button == 5) ? 0x3d : 0x3e; // Cursor up/down - for(int i=0; imouse_moved(event.xmotion.x, event.xmotion.y); - break; - - // Mouse entered window - case EnterNotify: - if (event.xcrossing.mode != NotifyGrab && event.xcrossing.mode != NotifyUngrab) - drv->mouse_moved(event.xmotion.x, event.xmotion.y); - break; - - // Keyboard - case KeyPress: { - int code = -1; - if (use_keycodes) { - if (event2keycode(event.xkey, true) != -2) // This is called to process the hotkeys - code = keycode_table[event.xkey.keycode & 0xff]; - } else - code = event2keycode(event.xkey, true); - if (code >= 0) { - if (!emul_suspended) { - if (code == 0x39) { // Caps Lock pressed - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyDown(code); - if (code == 0x36) - ctrl_down = true; - } else { - if (code == 0x31) - drv->resume(); // Space wakes us up - } - } - break; - } - case KeyRelease: { - int code = -1; - if (use_keycodes) { - if (event2keycode(event.xkey, false) != -2) // This is called to process the hotkeys - code = keycode_table[event.xkey.keycode & 0xff]; - } else - code = event2keycode(event.xkey, false); - if (code >= 0 && code != 0x39) { // Don't propagate Caps Lock releases - ADBKeyUp(code); - if (code == 0x36) - ctrl_down = false; - } - break; - } - - // Hidden parts exposed, force complete refresh of window - case Expose: - if (display_type == DISPLAY_WINDOW) { - const video_mode &mode = VideoMonitors[0]->get_current_mode(); -#ifdef ENABLE_VOSF - if (use_vosf) { // VOSF refresh - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } - else -#endif - if (frame_skip == 0) { // Dynamic refresh - int x1, y1; - for (y1=0; y1<16; y1++) - for (x1=0; x1<16; x1++) - updt_box[x1][y1] = true; - nr_boxes = 16 * 16; - } else // Static refresh - memset(the_buffer_copy, 0, mode.bytes_per_row * mode.y); - } - break; - } - - XDisplayUnlock(); - } -} - - -/* - * Window display update - */ - -// Dynamic display update (variable frame rate for each box) -static void update_display_dynamic(int ticker, driver_window *drv) -{ - int y1, y2, y2s, y2a, i, x1, xm, xmo, ymo, yo, yi, yil, xi; - int xil = 0; - int rxm = 0, rxmo = 0; - const video_mode &mode = drv->monitor.get_current_mode(); - int bytes_per_row = mode.bytes_per_row; - int bytes_per_pixel = mode.bytes_per_row / mode.x; - int rx = mode.bytes_per_row / 16; - int ry = mode.y / 16; - int max_box; - - y2s = sm_uptd[ticker % 8]; - y2a = 8; - for (i = 0; i < 6; i++) { - if (ticker % (2 << i)) - break; - } - max_box = sm_no_boxes[i]; - - if (y2a) { - for (y1=0; y1<16; y1++) { - for (y2=y2s; y2 < ry; y2 += y2a) { - i = ((y1 * ry) + y2) * bytes_per_row; - for (x1=0; x1<16; x1++, i += rx) { - if (updt_box[x1][y1] == false) { - if (memcmp(&the_buffer_copy[i], &the_buffer[i], rx)) { - updt_box[x1][y1] = true; - nr_boxes++; - } - } - } - } - } - } - - XDisplayLock(); - if ((nr_boxes <= max_box) && (nr_boxes)) { - for (y1=0; y1<16; y1++) { - for (x1=0; x1<16; x1++) { - if (updt_box[x1][y1] == true) { - if (rxm == 0) - xm = x1; - rxm += rx; - updt_box[x1][y1] = false; - } - if (((updt_box[x1+1][y1] == false) || (x1 == 15)) && (rxm)) { - if ((rxmo != rxm) || (xmo != xm) || (yo != y1 - 1)) { - if (rxmo) { - xi = xmo * rx; - yi = ymo * ry; - xil = rxmo; - yil = (yo - ymo +1) * ry; - } - rxmo = rxm; - xmo = xm; - ymo = y1; - } - rxm = 0; - yo = y1; - } - if (xil) { - i = (yi * bytes_per_row) + xi; - for (y2=0; y2 < yil; y2++, i += bytes_per_row) - memcpy(&the_buffer_copy[i], &the_buffer[i], xil); - if (mode.depth == VDEPTH_1BIT) { - if (drv->have_shm) - XShmPutImage(x_display, drv->w, drv->gc, drv->img, xi * 8, yi, xi * 8, yi, xil * 8, yil, 0); - else - XPutImage(x_display, drv->w, drv->gc, drv->img, xi * 8, yi, xi * 8, yi, xil * 8, yil); - } else { - if (drv->have_shm) - XShmPutImage(x_display, drv->w, drv->gc, drv->img, xi / bytes_per_pixel, yi, xi / bytes_per_pixel, yi, xil / bytes_per_pixel, yil, 0); - else - XPutImage(x_display, drv->w, drv->gc, drv->img, xi / bytes_per_pixel, yi, xi / bytes_per_pixel, yi, xil / bytes_per_pixel, yil); - } - xil = 0; - } - if ((x1 == 15) && (y1 == 15) && (rxmo)) { - x1--; - xi = xmo * rx; - yi = ymo * ry; - xil = rxmo; - yil = (yo - ymo +1) * ry; - rxmo = 0; - } - } - } - nr_boxes = 0; - } - XDisplayUnlock(); -} - -// Static display update (fixed frame rate, but incremental) -static void update_display_static(driver_window *drv) -{ - // Incremental update code - unsigned wide = 0, high = 0, x1, x2, y1, y2, i, j; - const video_mode &mode = drv->monitor.get_current_mode(); - int bytes_per_row = mode.bytes_per_row; - int bytes_per_pixel = mode.bytes_per_row / mode.x; - uint8 *p, *p2; - - // Check for first line from top and first line from bottom that have changed - y1 = 0; - for (j=0; j=y1; j--) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y2 = j; - break; - } - } - high = y2 - y1 + 1; - - // Check for first column from left and first column from right that have changed - if (high) { - if (mode.depth == VDEPTH_1BIT) { - x1 = mode.x - 1; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (i=0; i<(x1>>3); i++) { - if (*p != *p2) { - x1 = i << 3; - break; - } - p++; p2++; - } - } - x2 = x1; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (i=(mode.x>>3); i>(x2>>3); i--) { - p--; p2--; - if (*p != *p2) { - x2 = (i << 3) + 7; - break; - } - } - } - wide = x2 - x1 + 1; - - // Update copy of the_buffer - if (high && wide) { - for (j=y1; j<=y2; j++) { - i = j * bytes_per_row + (x1 >> 3); - memcpy(the_buffer_copy + i, the_buffer + i, wide >> 3); - } - } - - } else { - x1 = mode.x; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (i=0; ix2*bytes_per_pixel; i--) { - p--; - p2--; - if (*p != *p2) { - x2 = i / bytes_per_pixel; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - for (j=y1; j<=y2; j++) { - i = j * bytes_per_row + x1 * bytes_per_pixel; - memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); - } - } - } - } - - // Refresh display - XDisplayLock(); - if (high && wide) { - if (drv->have_shm) - XShmPutImage(x_display, drv->w, drv->gc, drv->img, x1, y1, x1, y1, wide, high, 0); - else - XPutImage(x_display, drv->w, drv->gc, drv->img, x1, y1, x1, y1, wide, high); - } - XDisplayUnlock(); -} - - -/* - * Screen refresh functions - */ - -// We suggest the compiler to inline the next two functions so that it -// may specialise the code according to the current screen depth and -// display type. A clever compiler would do that job by itself though... - -// NOTE: update_display_vosf is inlined too - -static inline void possibly_quit_dga_mode() -{ - // Quit DGA mode if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - delete drv; - drv = NULL; - } -} - -static inline void possibly_ungrab_mouse() -{ - // Ungrab mouse if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - if (drv) - drv->ungrab_mouse(); - } -} - -static inline void handle_palette_changes(void) -{ - LOCK_PALETTE; - - if (x_palette_changed) { - x_palette_changed = false; - XDisplayLock(); - drv->update_palette(); - XDisplayUnlock(); - } - - UNLOCK_PALETTE; -} - -static void video_refresh_dga(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); -} - -#ifdef ENABLE_VOSF -#if DIRECT_ADDRESSING -static void video_refresh_dga_vosf(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - - // Update display (VOSF variant) - static int tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_dga_vosf(static_cast(drv)); - UNLOCK_VOSF; - } - } -} -#endif - -static void video_refresh_window_vosf(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (VOSF variant) - static int tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - XDisplayLock(); - LOCK_VOSF; - update_display_window_vosf(static_cast(drv)); - UNLOCK_VOSF; - XSync(x_display, false); // Let the server catch up - XDisplayUnlock(); - } - } -} -#endif // def ENABLE_VOSF - -static void video_refresh_window_static(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (static variant) - static int tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - update_display_static(static_cast(drv)); - } -} - -static void video_refresh_window_dynamic(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (dynamic variant) - static int tick_counter = 0; - tick_counter++; - update_display_dynamic(tick_counter, static_cast(drv)); -} - - -/* - * Thread for screen refresh, input handling etc. - */ - -static void VideoRefreshInit(void) -{ - // TODO: set up specialised 8bpp VideoRefresh handlers ? - if (display_type == DISPLAY_DGA) { -#if ENABLE_VOSF && DIRECT_ADDRESSING - if (use_vosf) - video_refresh = video_refresh_dga_vosf; - else -#endif - video_refresh = video_refresh_dga; - } - else { -#ifdef ENABLE_VOSF - if (use_vosf) - video_refresh = video_refresh_window_vosf; - else -#endif - if (frame_skip == 0) - video_refresh = video_refresh_window_dynamic; - else - video_refresh = video_refresh_window_static; - } -} - -// This function is called on non-threaded platforms from a timer interrupt -void VideoRefresh(void) -{ - // We need to check redraw_thread_active to inhibit refreshed during - // mode changes on non-threaded platforms - if (!redraw_thread_active) - return; - - // Handle X events - handle_events(); - - // Handle palette changes - handle_palette_changes(); - - // Update display - video_refresh(); -} - -const int VIDEO_REFRESH_HZ = 60; -const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; - -#ifdef USE_PTHREADS_SERVICES -static void *redraw_func(void *arg) -{ - int fd = ConnectionNumber(x_display); - - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; - - while (!redraw_thread_cancel) { - - int64 delay = next - GetTicks_usec(); - if (delay < -VIDEO_REFRESH_DELAY) { - - // We are lagging far behind, so we reset the delay mechanism - next = GetTicks_usec(); - - } else if (delay <= 0) { - - // Delay expired, refresh display - handle_events(); - handle_palette_changes(); - video_refresh(); - next += VIDEO_REFRESH_DELAY; - ticks++; - - } else { - - // No display refresh pending, check for X events - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = delay; - if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) - handle_events(); - } - } - - uint64 end = GetTicks_usec(); - D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); - - redraw_thread_cancel_ack = true; - return NULL; -} -#endif From c756b743d58fadd489576600c8a530df4c285ad2 Mon Sep 17 00:00:00 2001 From: Seg Date: Mon, 14 Jun 2021 13:26:23 -0700 Subject: [PATCH 10/24] Fork SheepShaver vm_alloc/SDL --- SheepShaver/Makefile | 11 +- SheepShaver/src/CrossPlatform/video_vosf.h | 687 ++++- SheepShaver/src/CrossPlatform/vm_alloc.cpp | 620 ++++- SheepShaver/src/CrossPlatform/vm_alloc.h | 139 +- SheepShaver/src/SDL | 1 - SheepShaver/src/SDL/video_sdl.cpp | 2340 ++++++++++++++++ SheepShaver/src/SDL/video_sdl2.cpp | 2869 ++++++++++++++++++++ 7 files changed, 6658 insertions(+), 9 deletions(-) mode change 120000 => 100644 SheepShaver/src/CrossPlatform/video_vosf.h mode change 120000 => 100644 SheepShaver/src/CrossPlatform/vm_alloc.cpp mode change 120000 => 100644 SheepShaver/src/CrossPlatform/vm_alloc.h delete mode 120000 SheepShaver/src/SDL create mode 100644 SheepShaver/src/SDL/video_sdl.cpp create mode 100644 SheepShaver/src/SDL/video_sdl2.cpp diff --git a/SheepShaver/Makefile b/SheepShaver/Makefile index eaf2cab19..e5a036de3 100644 --- a/SheepShaver/Makefile +++ b/SheepShaver/Makefile @@ -59,22 +59,23 @@ links: include/prefs.h include/scsi.h include/serial.h \ include/serial_defs.h include/sony.h include/sys.h \ include/timer.h include/xpram.h \ - CrossPlatform/sigsegv.h CrossPlatform/vm_alloc.h CrossPlatform/vm_alloc.cpp \ - CrossPlatform/video_vosf.h CrossPlatform/video_blit.h CrossPlatform/video_blit.cpp \ - Unix/audio_oss_esd.cpp \ + CrossPlatform/sigsegv.h \ + CrossPlatform/video_blit.h CrossPlatform/video_blit.cpp \ + SDL/SDLMain.h SDL/SDLMain.m SDL/audio_sdl.cpp SDL/keycodes \ + SDL/prefs_sdl.cpp SDL/xpram_sdl.cpp \ Unix/vhd_unix.cpp \ Unix/extfs_unix.cpp Unix/serial_unix.cpp \ Unix/sshpty.h Unix/sshpty.c Unix/strlcpy.h Unix/strlcpy.c \ Unix/sys_unix.cpp Unix/timer_unix.cpp Unix/xpram_unix.cpp \ Unix/semaphore.h Unix/posix_sem.cpp Unix/config.sub Unix/config.guess Unix/m4 \ - Unix/keycodes Unix/tunconfig Unix/clip_unix.cpp Unix/Irix/audio_irix.cpp \ + Unix/keycodes Unix/tunconfig Unix/clip_unix.cpp \ Unix/Linux/scsi_linux.cpp Unix/Linux/NetDriver Unix/ether_unix.cpp \ Unix/rpc.h Unix/rpc_unix.cpp Unix/ldscripts \ Unix/tinyxml2.h Unix/tinyxml2.cpp Unix/disk_unix.h \ Unix/disk_sparsebundle.cpp Unix/Darwin/mkstandalone \ Unix/Darwin/pagezero.c Unix/Darwin/testlmem.sh \ dummy/audio_dummy.cpp dummy/clip_dummy.cpp dummy/serial_dummy.cpp \ - dummy/prefs_editor_dummy.cpp dummy/scsi_dummy.cpp SDL slirp \ + dummy/prefs_editor_dummy.cpp dummy/scsi_dummy.cpp slirp \ MacOSX/sys_darwin.cpp MacOSX/clip_macosx.cpp MacOSX/clip_macosx64.mm \ MacOSX/macos_util_macosx.h Unix/cpr.sh \ MacOSX/extfs_macosx.cpp Windows/clip_windows.cpp \ diff --git a/SheepShaver/src/CrossPlatform/video_vosf.h b/SheepShaver/src/CrossPlatform/video_vosf.h deleted file mode 120000 index 4c552311a..000000000 --- a/SheepShaver/src/CrossPlatform/video_vosf.h +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/CrossPlatform/video_vosf.h \ No newline at end of file diff --git a/SheepShaver/src/CrossPlatform/video_vosf.h b/SheepShaver/src/CrossPlatform/video_vosf.h new file mode 100644 index 000000000..f1d2f3add --- /dev/null +++ b/SheepShaver/src/CrossPlatform/video_vosf.h @@ -0,0 +1,686 @@ +/* + * video_vosf.h - Video/graphics emulation, video on SEGV signals support + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef VIDEO_VOSF_H +#define VIDEO_VOSF_H + +// Note: this file must be #include'd only in video_x.cpp +#ifdef ENABLE_VOSF + +#include "sigsegv.h" +#include "vm_alloc.h" +#ifdef _WIN32 +#include "util_windows.h" +#endif + +// Import SDL-backend-specific functions +#ifdef USE_SDL_VIDEO +extern void update_sdl_video(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h); +extern void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects); +#endif + +// Glue for SDL and X11 support +#ifdef TEST_VOSF_PERFORMANCE +#define MONITOR_INIT /* nothing */ +#else +#ifdef USE_SDL_VIDEO +#define MONITOR_INIT SDL_monitor_desc &monitor +#define VIDEO_DRV_WIN_INIT driver_base *drv +#define VIDEO_DRV_DGA_INIT driver_base *drv +#define VIDEO_DRV_LOCK_PIXELS SDL_VIDEO_LOCK_SURFACE(drv->s) +#define VIDEO_DRV_UNLOCK_PIXELS SDL_VIDEO_UNLOCK_SURFACE(drv->s) +#define VIDEO_DRV_DEPTH drv->s->format->BitsPerPixel +#define VIDEO_DRV_WIDTH drv->s->w +#define VIDEO_DRV_HEIGHT drv->s->h +#define VIDEO_DRV_ROW_BYTES drv->s->pitch +#else +#ifdef SHEEPSHAVER +#define MONITOR_INIT /* nothing */ +#define VIDEO_DRV_WIN_INIT /* nothing */ +#define VIDEO_DRV_DGA_INIT /* nothing */ +#define VIDEO_DRV_WINDOW the_win +#define VIDEO_DRV_GC the_gc +#define VIDEO_DRV_IMAGE img +#define VIDEO_DRV_HAVE_SHM have_shm +#else +#define MONITOR_INIT X11_monitor_desc &monitor +#define VIDEO_DRV_WIN_INIT driver_window *drv +#define VIDEO_DRV_DGA_INIT driver_dga *drv +#define VIDEO_DRV_WINDOW drv->w +#define VIDEO_DRV_GC drv->gc +#define VIDEO_DRV_IMAGE drv->img +#define VIDEO_DRV_HAVE_SHM drv->have_shm +#endif +#define VIDEO_DRV_LOCK_PIXELS /* nothing */ +#define VIDEO_DRV_UNLOCK_PIXELS /* nothing */ +#define VIDEO_DRV_DEPTH VIDEO_DRV_IMAGE->depth +#define VIDEO_DRV_WIDTH VIDEO_DRV_IMAGE->width +#define VIDEO_DRV_HEIGHT VIDEO_DRV_IMAGE->height +#define VIDEO_DRV_ROW_BYTES VIDEO_DRV_IMAGE->bytes_per_line +#endif +#endif + +// Prototypes +static void vosf_do_set_dirty_area(uintptr first, uintptr last); +static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_width, unsigned screen_height, unsigned bytes_per_row); + +// Variables for Video on SEGV support +static uint8 *the_host_buffer; // Host frame buffer in VOSF mode + +struct ScreenPageInfo { + unsigned top, bottom; // Mapping between this virtual page and Mac scanlines +}; + +struct ScreenInfo { + uintptr memStart; // Start address aligned to page boundary + uint32 memLength; // Length of the memory addressed by the screen pages + + uintptr pageSize; // Size of a page + int pageBits; // Shift count to get the page number + uint32 pageCount; // Number of pages allocated to the screen + + bool dirty; // Flag: set if the frame buffer was touched + bool very_dirty; // Flag: set if the frame buffer was completely modified (e.g. colormap changes) + char * dirtyPages; // Table of flags set if page was altered + ScreenPageInfo * pageInfo; // Table of mappings page -> Mac scanlines +}; + +static ScreenInfo mainBuffer; + +#define PFLAG_SET_VALUE 0x00 +#define PFLAG_CLEAR_VALUE 0x01 +#define PFLAG_SET_VALUE_4 0x00000000 +#define PFLAG_CLEAR_VALUE_4 0x01010101 +#define PFLAG_SET(page) mainBuffer.dirtyPages[page] = PFLAG_SET_VALUE +#define PFLAG_CLEAR(page) mainBuffer.dirtyPages[page] = PFLAG_CLEAR_VALUE +#define PFLAG_ISSET(page) (mainBuffer.dirtyPages[page] == PFLAG_SET_VALUE) +#define PFLAG_ISCLEAR(page) (mainBuffer.dirtyPages[page] != PFLAG_SET_VALUE) + +#ifdef UNALIGNED_PROFITABLE +# define PFLAG_ISSET_4(page) (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_SET_VALUE_4) +# define PFLAG_ISCLEAR_4(page) (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_CLEAR_VALUE_4) +#else +# define PFLAG_ISSET_4(page) \ + PFLAG_ISSET(page ) && PFLAG_ISSET(page+1) \ + && PFLAG_ISSET(page+2) && PFLAG_ISSET(page+3) +# define PFLAG_ISCLEAR_4(page) \ + PFLAG_ISCLEAR(page ) && PFLAG_ISCLEAR(page+1) \ + && PFLAG_ISCLEAR(page+2) && PFLAG_ISCLEAR(page+3) +#endif + +// Set the selected page range [ first_page, last_page [ into the SET state +#define PFLAG_SET_RANGE(first_page, last_page) \ + memset(mainBuffer.dirtyPages + (first_page), PFLAG_SET_VALUE, \ + (last_page) - (first_page)) + +// Set the selected page range [ first_page, last_page [ into the CLEAR state +#define PFLAG_CLEAR_RANGE(first_page, last_page) \ + memset(mainBuffer.dirtyPages + (first_page), PFLAG_CLEAR_VALUE, \ + (last_page) - (first_page)) + +#define PFLAG_SET_ALL do { \ + PFLAG_SET_RANGE(0, mainBuffer.pageCount); \ + mainBuffer.dirty = true; \ +} while (0) + +#define PFLAG_CLEAR_ALL do { \ + PFLAG_CLEAR_RANGE(0, mainBuffer.pageCount); \ + mainBuffer.dirty = false; \ + mainBuffer.very_dirty = false; \ +} while (0) + +#define PFLAG_SET_VERY_DIRTY do { \ + mainBuffer.very_dirty = true; \ +} while (0) + +// Set the following macro definition to 1 if your system +// provides a really fast strchr() implementation +//#define HAVE_FAST_STRCHR 0 + +static inline unsigned find_next_page_set(unsigned page) +{ +#if HAVE_FAST_STRCHR + char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_SET_VALUE); + return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount; +#else + while (PFLAG_ISCLEAR_4(page)) + page += 4; + while (PFLAG_ISCLEAR(page)) + page++; + return page; +#endif +} + +static inline unsigned find_next_page_clear(unsigned page) +{ +#if HAVE_FAST_STRCHR + char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_CLEAR_VALUE); + return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount; +#else + while (PFLAG_ISSET_4(page)) + page += 4; + while (PFLAG_ISSET(page)) + page++; + return page; +#endif +} + +#if defined(HAVE_PTHREADS) +static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect frame buffer (dirtyPages in fact) +#define LOCK_VOSF pthread_mutex_lock(&vosf_lock); +#define UNLOCK_VOSF pthread_mutex_unlock(&vosf_lock); +#elif defined(_WIN32) +static mutex_t vosf_lock; // Mutex to protect frame buffer (dirtyPages in fact) +#define LOCK_VOSF vosf_lock.lock(); +#define UNLOCK_VOSF vosf_lock.unlock(); +#elif defined(HAVE_SPINLOCKS) +static spinlock_t vosf_lock = SPIN_LOCK_UNLOCKED; // Mutex to protect frame buffer (dirtyPages in fact) +#define LOCK_VOSF spin_lock(&vosf_lock) +#define UNLOCK_VOSF spin_unlock(&vosf_lock) +#else +#define LOCK_VOSF +#define UNLOCK_VOSF +#endif + +static int log_base_2(uint32 x) +{ + uint32 mask = 0x80000000; + int l = 31; + while (l >= 0 && (x & mask) == 0) { + mask >>= 1; + l--; + } + return l; +} + +// Extend size to page boundary +static uint32 page_extend(uint32 size) +{ + const uint32 page_size = vm_get_page_size(); + const uint32 page_mask = page_size - 1; + return (size + page_mask) & ~page_mask; +} + + +/* + * Check if VOSF acceleration is profitable on this platform + */ + +#ifndef VOSF_PROFITABLE_TRIES +#define VOSF_PROFITABLE_TRIES VOSF_PROFITABLE_TRIES_DFL +#endif +const int VOSF_PROFITABLE_TRIES_DFL = 3; // Make 3 attempts for full screen update +const int VOSF_PROFITABLE_THRESHOLD = 16667/2; // 60 Hz (half of the quantum) + +static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faults_p = NULL) +{ + uint32 duration = 0; + uint32 n_tries = VOSF_PROFITABLE_TRIES; + const uint32 n_page_faults = mainBuffer.pageCount * n_tries; + +#ifdef SHEEPSHAVER + const bool accel = PrefsFindBool("gfxaccel"); +#else + const bool accel = false; +#endif + + for (uint32 i = 0; i < n_tries; i++) { + uint64 start = GetTicks_usec(); + for (uint32 p = 0; p < mainBuffer.pageCount; p++) { + uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize)); + if (accel) + vosf_do_set_dirty_area((uintptr)addr, (uintptr)addr + mainBuffer.pageSize - 1); + else + addr[0] = 0; // Trigger Screen_fault_handler() + } + duration += uint32(GetTicks_usec() - start); + + PFLAG_CLEAR_ALL; + mainBuffer.dirty = false; + if (vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ) != 0) + return false; + } + + if (duration_p) + *duration_p = duration; + if (n_page_faults_p) + *n_page_faults_p = n_page_faults; + + D(bug("Triggered %d page faults in %ld usec (%.1f usec per fault)\n", n_page_faults, duration, double(duration) / double(n_page_faults))); + return ((duration / n_tries) < (VOSF_PROFITABLE_THRESHOLD * (frame_skip ? frame_skip : 1))); +} + + +/* + * Initialize the VOSF system (mainBuffer structure, SIGSEGV handler) + */ + +static bool video_vosf_init(MONITOR_INIT) +{ + VIDEO_MODE_INIT_MONITOR; + + const uintptr page_size = vm_get_page_size(); + const uintptr page_mask = page_size - 1; + + // Round up frame buffer base to page boundary + mainBuffer.memStart = (((uintptr) the_buffer) + page_mask) & ~page_mask; + + // The frame buffer size shall already be aligned to page boundary (use page_extend) + mainBuffer.memLength = the_buffer_size; + + mainBuffer.pageSize = page_size; + mainBuffer.pageBits = log_base_2(mainBuffer.pageSize); + mainBuffer.pageCount = (mainBuffer.memLength + page_mask)/mainBuffer.pageSize; + + // The "2" more bytes requested are a safety net to insure the + // loops in the update routines will terminate. + // See "How can we deal with array overrun conditions ?" hereunder for further details. + mainBuffer.dirtyPages = (char *) malloc(mainBuffer.pageCount + 2); + if (mainBuffer.dirtyPages == NULL) + return false; + + PFLAG_CLEAR_ALL; + PFLAG_CLEAR(mainBuffer.pageCount); + PFLAG_SET(mainBuffer.pageCount+1); + + // Allocate and fill in pageInfo with start and end (inclusive) row in number of bytes + mainBuffer.pageInfo = (ScreenPageInfo *) malloc(mainBuffer.pageCount * sizeof(ScreenPageInfo)); + if (mainBuffer.pageInfo == NULL) + return false; + + uint32 a = 0; + for (unsigned i = 0; i < mainBuffer.pageCount; i++) { + unsigned y1 = a / VIDEO_MODE_ROW_BYTES; + if (y1 >= VIDEO_MODE_Y) + y1 = VIDEO_MODE_Y - 1; + + unsigned y2 = (a + mainBuffer.pageSize) / VIDEO_MODE_ROW_BYTES; + if (y2 >= VIDEO_MODE_Y) + y2 = VIDEO_MODE_Y - 1; + + mainBuffer.pageInfo[i].top = y1; + mainBuffer.pageInfo[i].bottom = y2; + + a += mainBuffer.pageSize; + if (a > mainBuffer.memLength) + a = mainBuffer.memLength; + } + + // We can now write-protect the frame buffer + if (vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ) != 0) + return false; + + // The frame buffer is sane, i.e. there is no write to it yet + mainBuffer.dirty = false; + return true; +} + + +/* + * Deinitialize VOSF system + */ + +static void video_vosf_exit(void) +{ + if (mainBuffer.pageInfo) { + free(mainBuffer.pageInfo); + mainBuffer.pageInfo = NULL; + } + if (mainBuffer.dirtyPages) { + free(mainBuffer.dirtyPages); + mainBuffer.dirtyPages = NULL; + } +} + + +/* + * Update VOSF state with specified dirty area + */ + +static void vosf_do_set_dirty_area(uintptr first, uintptr last) +{ + const int first_page = (first - mainBuffer.memStart) >> mainBuffer.pageBits; + const int last_page = (last - mainBuffer.memStart) >> mainBuffer.pageBits; + uint8 *addr = (uint8 *)(first & ~(mainBuffer.pageSize - 1)); + for (int i = first_page; i <= last_page; i++) { + if (PFLAG_ISCLEAR(i)) { + PFLAG_SET(i); + vm_protect(addr, mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); + } + addr += mainBuffer.pageSize; + } +} + +static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_width, unsigned screen_height, unsigned bytes_per_row) +{ + if (x < 0) { + w -= -x; + x = 0; + } + if (y < 0) { + h -= -y; + y = 0; + } + if (w <= 0 || h <= 0) + return; + if (unsigned(x + w) > screen_width) + w -= unsigned(x + w) - screen_width; + if (unsigned(y + h) > screen_height) + h -= unsigned(y + h) - screen_height; + LOCK_VOSF; + if (bytes_per_row >= screen_width) { + const int bytes_per_pixel = bytes_per_row / screen_width; + if (bytes_per_row <= mainBuffer.pageSize) { + const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel; + const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel; + vosf_do_set_dirty_area(a0, a1); + } else { + for (int j = y; j < y + h; j++) { + const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel; + const uintptr a1 = a0 + (w - 1) * bytes_per_pixel; + vosf_do_set_dirty_area(a0, a1); + } + } + } else { + const int pixels_per_byte = screen_width / bytes_per_row; + if (bytes_per_row <= mainBuffer.pageSize) { + const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte; + const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte; + vosf_do_set_dirty_area(a0, a1); + } else { + for (int j = y; j < y + h; j++) { + const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte; + const uintptr a1 = mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte; + vosf_do_set_dirty_area(a0, a1); + } + } + } + mainBuffer.dirty = true; + UNLOCK_VOSF; +} + + +/* + * Screen fault handler + */ + +bool Screen_fault_handler(sigsegv_info_t *sip) +{ + const uintptr addr = (uintptr)sigsegv_get_fault_address(sip); + + /* Someone attempted to write to the frame buffer. Make it writeable + * now so that the data could actually be written to. It will be made + * read-only back in one of the screen update_*() functions. + */ + if (((uintptr)addr - mainBuffer.memStart) < mainBuffer.memLength) { + const int page = ((uintptr)addr - mainBuffer.memStart) >> mainBuffer.pageBits; + LOCK_VOSF; + if (PFLAG_ISCLEAR(page)) { + PFLAG_SET(page); + vm_protect((char *)(addr & ~(mainBuffer.pageSize - 1)), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); + } + mainBuffer.dirty = true; + UNLOCK_VOSF; + return true; + } + + /* Otherwise, we don't know how to handle the fault, let it crash */ + return false; +} + + +/* + * Update display for Windowed mode and VOSF + */ + +/* How can we deal with array overrun conditions ? + + The state of the framebuffer pages that have been touched are maintained + in the dirtyPages[] table. That table is (pageCount + 2) bytes long. + +Terminology + + "Last Page" denotes the pageCount-nth page, i.e. dirtyPages[pageCount - 1]. + "CLEAR Page Guard" refers to the page following the Last Page but is always + in the CLEAR state. "SET Page Guard" refers to the page following the CLEAR + Page Guard but is always in the SET state. + +Rough process + + The update routines must determine which pages have to be blitted to the + screen. This job consists in finding the first_page that was touched. + i.e. find the next page that is SET. Then, finding how many pages were + touched starting from first_page. i.e. find the next page that is CLEAR. + +There are two cases to check: + + - Last Page is CLEAR: find_next_page_set() will reach the SET Page Guard + but it is beyond the valid pageCount value. Therefore, we exit from the + update routine. + + - Last Page is SET: first_page equals (pageCount - 1) and + find_next_page_clear() will reach the CLEAR Page Guard. We blit the last + page to the screen. On the next iteration, page equals pageCount and + find_next_page_set() will reach the SET Page Guard. We still safely exit + from the update routine because the SET Page Guard position is greater + than pageCount. +*/ + +#ifndef TEST_VOSF_PERFORMANCE +static void update_display_window_vosf(VIDEO_DRV_WIN_INIT) +{ + VIDEO_MODE_INIT; + + unsigned page = 0; + for (;;) { + const unsigned first_page = find_next_page_set(page); + if (first_page >= mainBuffer.pageCount) + break; + + page = find_next_page_clear(first_page); + PFLAG_CLEAR_RANGE(first_page, page); + + // Make the dirty pages read-only again + const int32 offset = first_page << mainBuffer.pageBits; + const uint32 length = (page - first_page) << mainBuffer.pageBits; + vm_protect((char *)mainBuffer.memStart + offset, length, VM_PAGE_READ); + + // There is at least one line to update + const int y1 = mainBuffer.pageInfo[first_page].top; + const int y2 = mainBuffer.pageInfo[page - 1].bottom; + const int height = y2 - y1 + 1; + + // Update the_host_buffer + VIDEO_DRV_LOCK_PIXELS; + const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; + const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES; + int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j; + for (j = y1; j <= y2; j++) { + Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); + i1 += src_bytes_per_row; + i2 += dst_bytes_per_row; + } + VIDEO_DRV_UNLOCK_PIXELS; + +#ifdef USE_SDL_VIDEO + update_sdl_video(drv->s, 0, y1, VIDEO_MODE_X, height); +#else + if (VIDEO_DRV_HAVE_SHM) + XShmPutImage(x_display, VIDEO_DRV_WINDOW, VIDEO_DRV_GC, VIDEO_DRV_IMAGE, 0, y1, 0, y1, VIDEO_MODE_X, height, 0); + else + XPutImage(x_display, VIDEO_DRV_WINDOW, VIDEO_DRV_GC, VIDEO_DRV_IMAGE, 0, y1, 0, y1, VIDEO_MODE_X, height); +#endif + } + mainBuffer.dirty = false; +} +#endif + + +/* + * Update display for DGA mode and VOSF + * (only in Real or Direct Addressing mode) + */ + +#ifndef TEST_VOSF_PERFORMANCE +#if REAL_ADDRESSING || DIRECT_ADDRESSING + +static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) +{ + VIDEO_MODE_INIT; + + // Compute number of bytes per row, take care to virtual screens + const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; + const int dst_bytes_per_row = TrivialBytesPerRow(VIDEO_MODE_X, DepthModeForPixelDepth(VIDEO_DRV_DEPTH)); + const int scr_bytes_per_row = VIDEO_DRV_ROW_BYTES; + assert(dst_bytes_per_row <= scr_bytes_per_row); + const int scr_bytes_left = scr_bytes_per_row - dst_bytes_per_row; + + // Full screen update requested? + if (mainBuffer.very_dirty) { + PFLAG_CLEAR_ALL; + vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ); + memcpy(the_buffer_copy, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); + VIDEO_DRV_LOCK_PIXELS; + int i1 = 0, i2 = 0; + for (uint32_t j = 0; j < VIDEO_MODE_Y; j++) { + Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); + i1 += src_bytes_per_row; + i2 += scr_bytes_per_row; + } +#ifdef USE_SDL_VIDEO + update_sdl_video(drv->s, 0, 0, VIDEO_MODE_X, VIDEO_MODE_Y); +#endif + VIDEO_DRV_UNLOCK_PIXELS; + return; + } + + // Setup partial blitter (use 64-pixel wide chunks) + const uint32 n_pixels = 64; + const uint32 n_chunks = VIDEO_MODE_X / n_pixels; + const uint32 n_pixels_left = VIDEO_MODE_X - (n_chunks * n_pixels); + const uint32 src_chunk_size = TrivialBytesPerRow(n_pixels, VIDEO_MODE_DEPTH); + const uint32 dst_chunk_size = TrivialBytesPerRow(n_pixels, DepthModeForPixelDepth(VIDEO_DRV_DEPTH)); + assert(src_chunk_size * n_chunks <= src_bytes_per_row); + assert(dst_chunk_size * n_chunks <= dst_bytes_per_row); + const uint32 src_chunk_size_left = src_bytes_per_row - (n_chunks * src_chunk_size); + const uint32 dst_chunk_size_left = dst_bytes_per_row - (n_chunks * dst_chunk_size); + + unsigned page = 0; + uint32 last_scanline = uint32(-1); + for (;;) { + const unsigned first_page = find_next_page_set(page); + if (first_page >= mainBuffer.pageCount) + break; + + page = find_next_page_clear(first_page); + PFLAG_CLEAR_RANGE(first_page, page); + + // Make the dirty pages read-only again + const int32 offset = first_page << mainBuffer.pageBits; + const uint32 length = (page - first_page) << mainBuffer.pageBits; + vm_protect((char *)mainBuffer.memStart + offset, length, VM_PAGE_READ); + + // Optimized for scanlines, don't process overlapping lines again + uint32 y1 = mainBuffer.pageInfo[first_page].top; + uint32 y2 = mainBuffer.pageInfo[page - 1].bottom; + if (last_scanline != uint32(-1)) { + if (y1 <= last_scanline && ++y1 >= VIDEO_MODE_Y) + continue; + if (y2 <= last_scanline && ++y2 >= VIDEO_MODE_Y) + continue; + } + last_scanline = y2; + + // Update the_host_buffer and copy of the_buffer, one line at a time + uint32 i1 = y1 * src_bytes_per_row; + uint32 i2 = y1 * scr_bytes_per_row; +#ifdef USE_SDL_VIDEO + int bbi = 0; + SDL_Rect bb[3] = { + { Sint16(VIDEO_MODE_X), Sint16(y1), 0, 0 }, + { Sint16(VIDEO_MODE_X), -1, 0, 0 }, + { Sint16(VIDEO_MODE_X), -1, 0, 0 } + }; +#endif + VIDEO_DRV_LOCK_PIXELS; + for (uint32 j = y1; j <= y2; j++) { + for (uint32 i = 0; i < n_chunks; i++) { + if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size) != 0) { + memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size); + Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size); +#ifdef USE_SDL_VIDEO + const int x = i * n_pixels; + if (x < bb[bbi].x) { + if (bb[bbi].w) + bb[bbi].w += bb[bbi].x - x; + else + bb[bbi].w = n_pixels; + bb[bbi].x = x; + } + else if (x >= bb[bbi].x + bb[bbi].w) + bb[bbi].w = x + n_pixels - bb[bbi].x; +#endif + } + i1 += src_chunk_size; + i2 += dst_chunk_size; + } + if (src_chunk_size_left && dst_chunk_size_left) { + if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left) != 0) { + memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left); + Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size_left); + } +#ifdef USE_SDL_VIDEO + const int x = n_chunks * n_pixels; + if (x < bb[bbi].x) { + if (bb[bbi].w) + bb[bbi].w += bb[bbi].x - x; + else + bb[bbi].w = n_pixels_left; + bb[bbi].x = x; + } + else if (x >= bb[bbi].x + bb[bbi].w) + bb[bbi].w = x + n_pixels_left - bb[bbi].x; +#endif + } + i1 += src_chunk_size_left; + i2 += dst_chunk_size_left + scr_bytes_left; +#ifdef USE_SDL_VIDEO + bb[bbi].h++; + if (bb[bbi].w && (j == y1 || j == y2 - 1 || j == y2)) { + bbi++; + assert(bbi <= 3); + if (j != y2) + bb[bbi].y = j + 1; + } +#endif + } +#ifdef USE_SDL_VIDEO + update_sdl_video(drv->s, bbi, bb); +#endif + VIDEO_DRV_UNLOCK_PIXELS; + } + mainBuffer.dirty = false; +} +#endif +#endif + +#endif /* ENABLE_VOSF */ + +#endif /* VIDEO_VOSF_H */ diff --git a/SheepShaver/src/CrossPlatform/vm_alloc.cpp b/SheepShaver/src/CrossPlatform/vm_alloc.cpp deleted file mode 120000 index cc80e1bc2..000000000 --- a/SheepShaver/src/CrossPlatform/vm_alloc.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/CrossPlatform/vm_alloc.cpp \ No newline at end of file diff --git a/SheepShaver/src/CrossPlatform/vm_alloc.cpp b/SheepShaver/src/CrossPlatform/vm_alloc.cpp new file mode 100644 index 000000000..176060c07 --- /dev/null +++ b/SheepShaver/src/CrossPlatform/vm_alloc.cpp @@ -0,0 +1,619 @@ +/* + * vm_alloc.cpp - Wrapper to various virtual memory allocation schemes + * (supports mmap, vm_allocate or fallbacks to malloc) + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef HAVE_WIN32_VM +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include +#endif + +#include +#include +#include +#include +#include +#include "vm_alloc.h" + +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + +#ifdef HAVE_MACH_VM +#ifndef HAVE_MACH_TASK_SELF +#ifdef HAVE_TASK_SELF +#define mach_task_self task_self +#else +#error "No task_self(), you lose." +#endif +#endif +#endif + +#ifdef HAVE_WIN32_VM +/* Windows is either ILP32 or LLP64 */ +typedef UINT_PTR vm_uintptr_t; +#else +/* Other systems are sane as they are either ILP32 or LP64 */ +typedef unsigned long vm_uintptr_t; +#endif + +/* We want MAP_32BIT, if available, for SheepShaver and BasiliskII + because the emulated target is 32-bit and this helps to allocate + memory so that branches could be resolved more easily (32-bit + displacement to code in .text), on AMD64 for example. */ +#if defined(__hpux) +#define MAP_32BIT MAP_ADDR32 +#endif +#ifndef MAP_32BIT +#define MAP_32BIT 0 +#endif +#ifdef __FreeBSD__ +#define FORCE_MAP_32BIT MAP_FIXED +#else +#define FORCE_MAP_32BIT MAP_32BIT +#endif +#ifndef MAP_ANON +#define MAP_ANON 0 +#endif +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS 0 +#endif + +/* NOTE: on linux MAP_32BIT is only implemented on AMD64 + it is a null op on all other architectures + thus the MAP_BASE setting below is the only thing + ensuring low addresses on aarch64 for example */ +#define MAP_EXTRA_FLAGS (MAP_32BIT) + +#ifdef HAVE_MMAP_VM +#if (defined(__linux__) && defined(__i386__)) || defined(__FreeBSD__) || HAVE_LINKER_SCRIPT +/* Force a reasonnable address below 0x80000000 on x86 so that we + don't get addresses above when the program is run on AMD64. + NOTE: this is empirically determined on Linux/x86. */ +#define MAP_BASE 0x10000000 +#elif DIRECT_ADDRESSING +/* linux does not implement any useful fallback behavior + such as allocating the next available address + and the first 4k-64k of address space is marked unavailable + for security reasons (see https://wiki.debian.org/mmap_min_addr) + so we must start requesting after the first page + or we get a high 64bit address that will crash direct addressing + + leaving NULL unmapped is a good idea anyway for debugging reasons */ +#define MAP_BASE 0x00010000 +#else +#define MAP_BASE 0x00000000 +#endif +static char * next_address = (char *)MAP_BASE; +#ifdef HAVE_MMAP_ANON +#define map_flags (MAP_ANON | MAP_EXTRA_FLAGS) +#define zero_fd -1 +#else +#ifdef HAVE_MMAP_ANONYMOUS +#define map_flags (MAP_ANONYMOUS | MAP_EXTRA_FLAGS) +#define zero_fd -1 +#else +#define map_flags (MAP_EXTRA_FLAGS) +static int zero_fd = -1; +#endif +#endif +#endif + +/* Translate generic VM map flags to host values. */ + +#ifdef HAVE_MMAP_VM +static int translate_map_flags(int vm_flags) +{ + int flags = 0; + if (vm_flags & VM_MAP_SHARED) + flags |= MAP_SHARED; + if (vm_flags & VM_MAP_PRIVATE) + flags |= MAP_PRIVATE; + if (vm_flags & VM_MAP_FIXED) + flags |= MAP_FIXED; + if (vm_flags & VM_MAP_32BIT) + flags |= FORCE_MAP_32BIT; + return flags; +} +#endif + +/* Align ADDR and SIZE to 64K boundaries. */ + +#ifdef HAVE_WIN32_VM +static inline LPVOID align_addr_segment(LPVOID addr) +{ + return LPVOID(vm_uintptr_t(addr) & ~vm_uintptr_t(0xFFFF)); +} + +static inline DWORD align_size_segment(LPVOID addr, DWORD size) +{ + return size + ((vm_uintptr_t)addr - (vm_uintptr_t)align_addr_segment(addr)); +} +#endif + +/* Translate generic VM prot flags to host values. */ + +#ifdef HAVE_WIN32_VM +static int translate_prot_flags(int prot_flags) +{ + int prot = PAGE_READWRITE; + if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ | VM_PAGE_WRITE)) + prot = PAGE_EXECUTE_READWRITE; + else if (prot_flags == (VM_PAGE_EXECUTE | VM_PAGE_READ)) + prot = PAGE_EXECUTE_READ; + else if (prot_flags == (VM_PAGE_READ | VM_PAGE_WRITE)) + prot = PAGE_READWRITE; + else if (prot_flags == VM_PAGE_READ) + prot = PAGE_READONLY; + else if (prot_flags == 0) + prot = PAGE_NOACCESS; + return prot; +} +#endif + +/* Translate Mach return codes to POSIX errno values. */ +#ifdef HAVE_MACH_VM +static int vm_error(kern_return_t ret_code) +{ + switch (ret_code) { + case KERN_SUCCESS: + return 0; + case KERN_INVALID_ADDRESS: + case KERN_NO_SPACE: + return ENOMEM; + case KERN_PROTECTION_FAILURE: + return EACCES; + default: + return EINVAL; + } +} +#endif + +/* Initialize the VM system. Returns 0 if successful, -1 for errors. */ + +int vm_init(void) +{ +#ifdef HAVE_MMAP_VM +#ifndef zero_fd + zero_fd = open("/dev/zero", O_RDWR); + if (zero_fd < 0) + return -1; +#endif +#endif + +// On 10.4 and earlier, reset CrashReporter's task signal handler to +// avoid having it show up for signals that get handled. +#if defined(__APPLE__) && defined(__MACH__) + struct utsname info; + + if (!uname(&info) && atoi(info.release) <= 8) { + task_set_exception_ports(mach_task_self(), + EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC, + MACH_PORT_NULL, + EXCEPTION_STATE_IDENTITY, + MACHINE_THREAD_STATE); + } +#endif + + return 0; +} + +/* Deallocate all internal data used to wrap virtual memory allocators. */ + +void vm_exit(void) +{ +#ifdef HAVE_MMAP_VM +#ifndef zero_fd + if (zero_fd != -1) { + close(zero_fd); + zero_fd = -1; + } +#endif +#endif +} + +static void *reserved_buf; +static const size_t RESERVED_SIZE = 64 * 1024 * 1024; // for 5K Retina + +void *vm_acquire_reserved(size_t size) { + return reserved_buf && size <= RESERVED_SIZE ? reserved_buf : VM_MAP_FAILED; +} + +int vm_init_reserved(void *hostAddress) { + int result = vm_acquire_fixed(hostAddress, RESERVED_SIZE); + if (result >= 0) + reserved_buf = hostAddress; + return result; +} + +/* Allocate zero-filled memory of SIZE bytes. The mapping is private + and default protection bits are read / write. The return value + is the actual mapping address chosen or VM_MAP_FAILED for errors. */ + +void * vm_acquire(size_t size, int options) +{ + void * addr; + + errno = 0; + + // VM_MAP_FIXED are to be used with vm_acquire_fixed() only + if (options & VM_MAP_FIXED) + return VM_MAP_FAILED; + +#ifndef HAVE_VM_WRITE_WATCH + if (options & VM_MAP_WRITE_WATCH) + return VM_MAP_FAILED; +#endif + +#if defined(HAVE_MACH_VM) + // vm_allocate() returns a zero-filled memory region + kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, reserved_buf ? size : size + RESERVED_SIZE, TRUE); + if (ret_code != KERN_SUCCESS) { + errno = vm_error(ret_code); + return VM_MAP_FAILED; + } + if (!reserved_buf) + reserved_buf = (char *)addr + size; +#elif defined(HAVE_MMAP_VM) + int fd = zero_fd; + int the_map_flags = translate_map_flags(options) | map_flags; + + if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED) + return VM_MAP_FAILED; + +#if DIRECT_ADDRESSING + // If MAP_32BIT and MAP_BASE fail to ensure + // a 32-bit address crash now instead of later. + // FIXME: make everything 64-bit clean and tear this all out. + if(sizeof(void *) > 4 && (options & VM_MAP_32BIT)) + assert((size_t)addr<0xffffffffL); +#endif + + next_address = (char *)addr + size; +#elif defined(HAVE_WIN32_VM) + int alloc_type = MEM_RESERVE | MEM_COMMIT; + if (options & VM_MAP_WRITE_WATCH) + alloc_type |= MEM_WRITE_WATCH; + + if ((addr = VirtualAlloc(NULL, size, alloc_type, PAGE_EXECUTE_READWRITE)) == NULL) + return VM_MAP_FAILED; +#else + if ((addr = calloc(size, 1)) == 0) + return VM_MAP_FAILED; + + // Omit changes for protections because they are not supported in this mode + return addr; +#endif + + // Explicitely protect the newly mapped region here because on some systems, + // say MacOS X, mmap() doesn't honour the requested protection flags. + if (vm_protect(addr, size, VM_PAGE_DEFAULT) != 0) + return VM_MAP_FAILED; + + return addr; +} + +/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned). + Retuns 0 if successful, -1 on errors. */ + +int vm_acquire_fixed(void * addr, size_t size, int options) +{ + errno = 0; + + // Fixed mappings are required to be private + if (options & VM_MAP_SHARED) + return -1; + +#ifndef HAVE_VM_WRITE_WATCH + if (options & VM_MAP_WRITE_WATCH) + return -1; +#endif + +#if defined(HAVE_MACH_VM) + // vm_allocate() returns a zero-filled memory region + kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, 0); + if (ret_code != KERN_SUCCESS) { + errno = vm_error(ret_code); + return -1; + } +#elif defined(HAVE_MMAP_VM) + int fd = zero_fd; + int the_map_flags = translate_map_flags(options) | map_flags | MAP_FIXED; + + if (mmap((caddr_t)addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0) == (void *)MAP_FAILED) + return -1; +#elif defined(HAVE_WIN32_VM) + // Windows cannot allocate Low Memory + if (addr == NULL) + return -1; + + int alloc_type = MEM_RESERVE | MEM_COMMIT; + if (options & VM_MAP_WRITE_WATCH) + alloc_type |= MEM_WRITE_WATCH; + + // Allocate a possibly offset region to align on 64K boundaries + LPVOID req_addr = align_addr_segment(addr); + DWORD req_size = align_size_segment(addr, size); + LPVOID ret_addr = VirtualAlloc(req_addr, req_size, alloc_type, PAGE_EXECUTE_READWRITE); + if (ret_addr != req_addr) + return -1; +#else + // Unsupported + return -1; +#endif + + // Explicitely protect the newly mapped region here because on some systems, + // say MacOS X, mmap() doesn't honour the requested protection flags. + if (vm_protect(addr, size, VM_PAGE_DEFAULT) != 0) + return -1; + + return 0; +} + +/* Deallocate any mapping for the region starting at ADDR and extending + LEN bytes. Returns 0 if successful, -1 on errors. */ + +int vm_release(void * addr, size_t size) +{ + // Safety check: don't try to release memory that was not allocated + if (addr == VM_MAP_FAILED) + return 0; + +#ifdef HAVE_MACH_VM + if (vm_deallocate(mach_task_self(), (vm_address_t)addr, size) != KERN_SUCCESS) + return -1; +#else +#ifdef HAVE_MMAP_VM + if (munmap((caddr_t)addr, size) != 0) + return -1; +#else +#ifdef HAVE_WIN32_VM + if (VirtualFree(align_addr_segment(addr), 0, MEM_RELEASE) == 0) + return -1; +#else + free(addr); +#endif +#endif +#endif + + return 0; +} + +/* Change the memory protection of the region starting at ADDR and + extending LEN bytes to PROT. Returns 0 if successful, -1 for errors. */ + +int vm_protect(void * addr, size_t size, int prot) +{ +#ifdef HAVE_MACH_VM + int ret_code = vm_protect(mach_task_self(), (vm_address_t)addr, size, 0, prot); + return ret_code == KERN_SUCCESS ? 0 : -1; +#else +#ifdef HAVE_MMAP_VM + int ret_code = mprotect((caddr_t)addr, size, prot); + return ret_code == 0 ? 0 : -1; +#else +#ifdef HAVE_WIN32_VM + DWORD old_prot; + int ret_code = VirtualProtect(addr, size, translate_prot_flags(prot), &old_prot); + return ret_code != 0 ? 0 : -1; +#else + // Unsupported + return -1; +#endif +#endif +#endif +} + +/* Return the addresses of the pages that got modified in the + specified range [ ADDR, ADDR + SIZE [ since the last reset of the watch + bits. Returns 0 if successful, -1 for errors. */ + +int vm_get_write_watch(void * addr, size_t size, + void ** pages, unsigned int * n_pages, + int options) +{ +#ifdef HAVE_VM_WRITE_WATCH +#ifdef HAVE_WIN32_VM + DWORD flags = 0; + if (options & VM_WRITE_WATCH_RESET) + flags |= WRITE_WATCH_FLAG_RESET; + + ULONG page_size; + ULONG_PTR count = *n_pages; + int ret_code = GetWriteWatch(flags, addr, size, pages, &count, &page_size); + if (ret_code != 0) + return -1; + + *n_pages = count; + return 0; +#endif +#endif + // Unsupported + return -1; +} + +/* Reset the write-tracking state for the specified range [ ADDR, ADDR + + SIZE [. Returns 0 if successful, -1 for errors. */ + +int vm_reset_write_watch(void * addr, size_t size) +{ +#ifdef HAVE_VM_WRITE_WATCH +#ifdef HAVE_WIN32_VM + int ret_code = ResetWriteWatch(addr, size); + return ret_code == 0 ? 0 : -1; +#endif +#endif + // Unsupported + return -1; +} + +/* Returns the size of a page. */ + +int vm_get_page_size(void) +{ +#ifdef HAVE_WIN32_VM + static vm_uintptr_t page_size = 0; + if (page_size == 0) { + SYSTEM_INFO si; + GetSystemInfo(&si); + page_size = si.dwAllocationGranularity; + } + return page_size; +#else + return getpagesize(); +#endif +} + +#ifdef CONFIGURE_TEST_VM_WRITE_WATCH +int main(void) +{ + int i, j; + + vm_init(); + + vm_uintptr_t page_size = vm_get_page_size(); + + char *area; + const int n_pages = 7; + const int area_size = n_pages * page_size; + const int map_options = VM_MAP_DEFAULT | VM_MAP_WRITE_WATCH; + if ((area = (char *)vm_acquire(area_size, map_options)) == VM_MAP_FAILED) + return 1; + + unsigned int n_modified_pages_expected = 0; + static const int touch_page[n_pages] = { 0, 1, 1, 0, 1, 0, 1 }; + for (i = 0; i < n_pages; i++) { + if (touch_page[i]) { + area[i * page_size] = 1; + ++n_modified_pages_expected; + } + } + + char *modified_pages[n_pages]; + unsigned int n_modified_pages = n_pages; + if (vm_get_write_watch(area, area_size, (void **)modified_pages, &n_modified_pages) < 0) + return 2; + if (n_modified_pages != n_modified_pages_expected) + return 3; + for (i = 0, j = 0; i < n_pages; i++) { + char v = area[i * page_size]; + if ((touch_page[i] && !v) || (!touch_page[i] && v)) + return 4; + if (!touch_page[i]) + continue; + if (modified_pages[j] != (area + i * page_size)) + return 5; + ++j; + } + + vm_release(area, area_size); + return 0; +} +#endif + +#ifdef CONFIGURE_TEST_VM_MAP +#include +#include + +static void fault_handler(int sig) +{ + exit(1); +} + +/* Tests covered here: + - TEST_VM_PROT_* program slices actually succeeds when a crash occurs + - TEST_VM_MAP_ANON* program slices succeeds when it could be compiled +*/ +int main(void) +{ + vm_init(); + + signal(SIGSEGV, fault_handler); +#ifdef SIGBUS + signal(SIGBUS, fault_handler); +#endif + +#define page_align(address) ((char *)((vm_uintptr_t)(address) & -page_size)) + vm_uintptr_t page_size = vm_get_page_size(); + + const int area_size = 6 * page_size; + volatile char * area = (volatile char *) vm_acquire(area_size); + volatile char * fault_address = area + (page_size * 7) / 2; + +#if defined(TEST_VM_MMAP_ANON) || defined(TEST_VM_MMAP_ANONYMOUS) + if (area == VM_MAP_FAILED) + return 1; + + if (vm_release((char *)area, area_size) < 0) + return 1; + + return 0; +#endif + +#if defined(TEST_VM_PROT_NONE_READ) || defined(TEST_VM_PROT_NONE_WRITE) + if (area == VM_MAP_FAILED) + return 0; + + if (vm_protect(page_align(fault_address), page_size, VM_PAGE_NOACCESS) < 0) + return 0; +#endif + +#if defined(TEST_VM_PROT_RDWR_WRITE) + if (area == VM_MAP_FAILED) + return 1; + + if (vm_protect(page_align(fault_address), page_size, VM_PAGE_READ) < 0) + return 1; + + if (vm_protect(page_align(fault_address), page_size, VM_PAGE_READ | VM_PAGE_WRITE) < 0) + return 1; +#endif + +#if defined(TEST_VM_PROT_READ_WRITE) + if (vm_protect(page_align(fault_address), page_size, VM_PAGE_READ) < 0) + return 0; +#endif + +#if defined(TEST_VM_PROT_NONE_READ) + // this should cause a core dump + char foo = *fault_address; + return 0; +#endif + +#if defined(TEST_VM_PROT_NONE_WRITE) || defined(TEST_VM_PROT_READ_WRITE) + // this should cause a core dump + *fault_address = 'z'; + return 0; +#endif + +#if defined(TEST_VM_PROT_RDWR_WRITE) + // this should not cause a core dump + *fault_address = 'z'; + return 0; +#endif +} +#endif diff --git a/SheepShaver/src/CrossPlatform/vm_alloc.h b/SheepShaver/src/CrossPlatform/vm_alloc.h deleted file mode 120000 index ef65a5618..000000000 --- a/SheepShaver/src/CrossPlatform/vm_alloc.h +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/CrossPlatform/vm_alloc.h \ No newline at end of file diff --git a/SheepShaver/src/CrossPlatform/vm_alloc.h b/SheepShaver/src/CrossPlatform/vm_alloc.h new file mode 100644 index 000000000..41dd949df --- /dev/null +++ b/SheepShaver/src/CrossPlatform/vm_alloc.h @@ -0,0 +1,138 @@ +/* + * vm_alloc.h - Wrapper to various virtual memory allocation schemes + * (supports mmap, vm_allocate or fallbacks to malloc) + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef VM_ALLOC_H +#define VM_ALLOC_H + +#ifdef HAVE_UNISTD_H +#include +#include +#endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_MACH_VM +extern "C" { +#include +#include +} +#endif + +#include + +/* Return value of `vm_acquire' in case of an error. */ +#ifdef HAVE_MACH_VM +#define VM_MAP_FAILED ((void *)-1) +#else +#ifdef HAVE_MMAP_VM +#define VM_MAP_FAILED ((void *)-1) +#else +#define VM_MAP_FAILED 0 +#endif +#endif + +/* Option to vm_get_write_watch() to reset the write-tracking state + once it was retrieved. Otherwise, you have to manually call + vm_reset_write_watch() and potentially lose some info. */ +#define VM_WRITE_WATCH_RESET 0x01 + +/* Mapping options. */ +#define VM_MAP_SHARED 0x01 +#define VM_MAP_PRIVATE 0x02 +#define VM_MAP_FIXED 0x04 +#define VM_MAP_32BIT 0x08 +#define VM_MAP_WRITE_WATCH 0x10 + +/* Default mapping options. */ +#define VM_MAP_DEFAULT (VM_MAP_PRIVATE) + +/* Protection bits. */ +#ifdef HAVE_MACH_VM +#define VM_PAGE_NOACCESS VM_PROT_NONE +#define VM_PAGE_READ VM_PROT_READ +#define VM_PAGE_WRITE VM_PROT_WRITE +#define VM_PAGE_EXECUTE VM_PROT_EXECUTE +#else +#ifdef HAVE_MMAP_VM +#define VM_PAGE_NOACCESS PROT_NONE +#define VM_PAGE_READ PROT_READ +#define VM_PAGE_WRITE PROT_WRITE +#define VM_PAGE_EXECUTE PROT_EXEC +#else +#define VM_PAGE_NOACCESS 0x0 +#define VM_PAGE_READ 0x1 +#define VM_PAGE_WRITE 0x2 +#define VM_PAGE_EXECUTE 0x4 +#endif +#endif + +/* Default protection bits. */ +#define VM_PAGE_DEFAULT (VM_PAGE_READ | VM_PAGE_WRITE) + +/* Initialize the VM system. Returns 0 if successful, -1 for errors. */ + +extern int vm_init(void); + +/* Deallocate all internal data used to wrap virtual memory allocators. */ + +extern void vm_exit(void); + +/* Allocate zero-filled memory of SIZE bytes. The mapping is private + and default protection bits are read / write. The return value + is the actual mapping address chosen or VM_MAP_FAILED for errors. */ + +extern void * vm_acquire(size_t size, int options = VM_MAP_DEFAULT); + +extern void * vm_acquire_reserved(size_t size); + +/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned). + Returns 0 if successful, -1 on errors. */ + +extern int vm_acquire_fixed(void * addr, size_t size, int options = VM_MAP_DEFAULT); + +/* Deallocate any mapping for the region starting at ADDR and extending + LEN bytes. Returns 0 if successful, -1 on errors. */ + +extern int vm_release(void * addr, size_t size); + +/* Change the memory protection of the region starting at ADDR and + extending SIZE bytes to PROT. Returns 0 if successful, -1 for errors. */ + +extern int vm_protect(void * addr, size_t size, int prot); + +/* Return the addresses of the pages that got modified since the last + reset of the write-tracking state for the specified range [ ADDR, + ADDR + SIZE [. Returns 0 if successful, -1 for errors. */ + +extern int vm_get_write_watch(void * addr, size_t size, + void ** pages, unsigned int * n_pages, + int options = 0); + +/* Reset the write-tracking state for the specified range [ ADDR, ADDR + + SIZE [. Returns 0 if successful, -1 for errors. */ + +extern int vm_reset_write_watch(void * addr, size_t size); + +/* Returns the size of a page. */ + +extern int vm_get_page_size(void); + +#endif /* VM_ALLOC_H */ diff --git a/SheepShaver/src/SDL b/SheepShaver/src/SDL deleted file mode 120000 index 48cb61ebe..000000000 --- a/SheepShaver/src/SDL +++ /dev/null @@ -1 +0,0 @@ -../../BasiliskII/src/SDL \ No newline at end of file diff --git a/SheepShaver/src/SDL/video_sdl.cpp b/SheepShaver/src/SDL/video_sdl.cpp new file mode 100644 index 000000000..395778a00 --- /dev/null +++ b/SheepShaver/src/SDL/video_sdl.cpp @@ -0,0 +1,2340 @@ +/* + * video_sdl.cpp - Video/graphics emulation, SDL 1.x specific stuff + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTES: + * The Ctrl key works like a qualifier for special actions: + * Ctrl-Tab = suspend DGA mode (TODO) + * Ctrl-Esc = emergency quit + * Ctrl-F1 = mount floppy + * Ctrl-F5 = grab mouse (in windowed mode) + * + * FIXMEs and TODOs: + * - Windows requires an extra mouse event to update the actual cursor image? + * - Ctr-Tab for suspend/resume but how? SDL does not support that for non-Linux + * - Ctrl-Fn doesn't generate SDL_KEYDOWN events (SDL bug?) + * - Mouse acceleration, there is no API in SDL yet for that + * - Force relative mode in Grab mode even if SDL provides absolute coordinates? + * - Gamma tables support is likely to be broken here + * - Events processing is bound to the general emulation thread as SDL requires + * to PumpEvents() within the same thread as the one that called SetVideoMode(). + * Besides, there can't seem to be a way to call SetVideoMode() from a child thread. + * - Backport hw cursor acceleration to Basilisk II? + * - Factor out code + */ + +#include "sysdeps.h" + +#include +#if (SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)) + +#include +#include +#include +#include + +#ifdef WIN32 +#include /* alloca() */ +#endif + +#include "cpu_emulation.h" +#include "main.h" +#include "adb.h" +#include "macos_util.h" +#include "prefs.h" +#include "user_strings.h" +#include "video.h" +#include "video_defs.h" +#include "video_blit.h" +#include "vm_alloc.h" + +#define DEBUG 0 +#include "debug.h" + +// Supported video modes +using std::vector; +static vector VideoModes; + +// Display types +#ifdef SHEEPSHAVER +enum { + DISPLAY_WINDOW = DIS_WINDOW, // windowed display + DISPLAY_SCREEN = DIS_SCREEN // fullscreen display +}; +extern int display_type; // See enum above +#else +enum { + DISPLAY_WINDOW, // windowed display + DISPLAY_SCREEN // fullscreen display +}; +static int display_type = DISPLAY_WINDOW; // See enum above +#endif + +// Constants +#if defined(WIN32) || __MACOSX__ +const char KEYCODE_FILE_NAME[] = "BasiliskII_keycodes"; +#else +const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; +#endif + + +// Global variables +static uint32 frame_skip; // Prefs items +static int16 mouse_wheel_mode; +static int16 mouse_wheel_lines; + +static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) +static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) +static uint32 the_buffer_size; // Size of allocated the_buffer + +static bool redraw_thread_active = false; // Flag: Redraw thread installed +#ifndef USE_CPU_EMUL_SERVICES +static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread +static SDL_Thread *redraw_thread = NULL; // Redraw thread +static volatile bool thread_stop_req = false; +static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req +#endif + +#ifdef ENABLE_VOSF +static bool use_vosf = false; // Flag: VOSF enabled +#else +static const bool use_vosf = false; // VOSF not possible +#endif + +static bool ctrl_down = false; // Flag: Ctrl key pressed +static bool caps_on = false; // Flag: Caps Lock on +static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread +static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread +static bool emul_suspended = false; // Flag: Emulator suspended + +static bool classic_mode = false; // Flag: Classic Mac video mode + +static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms +static int keycode_table[256]; // X keycode -> Mac keycode translation table + +// SDL variables +static int screen_depth; // Depth of current screen +static SDL_Cursor *sdl_cursor; // Copy of Mac cursor +static SDL_Color sdl_palette[256]; // Color palette to be used as CLUT and gamma table +static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors +static bool toggle_fullscreen = false; +static const int sdl_eventmask = SDL_MOUSEEVENTMASK | SDL_KEYEVENTMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK | SDL_ACTIVEEVENTMASK; + +static bool mouse_grabbed = false; +static bool mouse_grabbed_window_name_status = false; + +// Mutex to protect SDL events +static SDL_mutex *sdl_events_lock = NULL; +#define LOCK_EVENTS SDL_LockMutex(sdl_events_lock) +#define UNLOCK_EVENTS SDL_UnlockMutex(sdl_events_lock) + +// Mutex to protect palette +static SDL_mutex *sdl_palette_lock = NULL; +#define LOCK_PALETTE SDL_LockMutex(sdl_palette_lock) +#define UNLOCK_PALETTE SDL_UnlockMutex(sdl_palette_lock) + +// Mutex to protect frame buffer +static SDL_mutex *frame_buffer_lock = NULL; +#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock) +#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock) + +// Previously set gamma tables +static uint16 last_gamma_red[256]; +static uint16 last_gamma_green[256]; +static uint16 last_gamma_blue[256]; + +// Video refresh function +static void VideoRefreshInit(void); +static void (*video_refresh)(void); + + +// Prototypes +static int redraw_func(void *arg); + +// From sys_unix.cpp +extern void SysMountFirstFloppy(void); + + +/* + * SDL surface locking glue + */ + +#ifdef ENABLE_VOSF +#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ + if ((SURFACE)->flags & (SDL_HWSURFACE | SDL_FULLSCREEN)) \ + the_host_buffer = (uint8 *)(SURFACE)->pixels; \ +} while (0) +#else +#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) +#endif + +#define SDL_VIDEO_LOCK_SURFACE(SURFACE) do { \ + if (SDL_MUSTLOCK(SURFACE)) { \ + SDL_LockSurface(SURFACE); \ + SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE); \ + } \ +} while (0) + +#define SDL_VIDEO_UNLOCK_SURFACE(SURFACE) do { \ + if (SDL_MUSTLOCK(SURFACE)) \ + SDL_UnlockSurface(SURFACE); \ +} while (0) + + +/* + * Framebuffer allocation routines + */ + +static void *vm_acquire_framebuffer(uint32 size) +{ + // always try to reallocate framebuffer at the same address + static void *fb = VM_MAP_FAILED; + if (fb != VM_MAP_FAILED) { + if (vm_acquire_fixed(fb, size) < 0) { +#ifndef SHEEPSHAVER + printf("FATAL: Could not reallocate framebuffer at previous address\n"); +#endif + fb = VM_MAP_FAILED; + } + } + if (fb == VM_MAP_FAILED) + fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); + return fb; +} + +static inline void vm_release_framebuffer(void *fb, uint32 size) +{ + vm_release(fb, size); +} + +static inline int get_customized_color_depth(int default_depth) +{ + int display_color_depth = PrefsFindInt32("displaycolordepth"); + + D(bug("Get displaycolordepth %d\n", display_color_depth)); + + if(0 == display_color_depth) + return default_depth; + else{ + switch (display_color_depth) { + case 8: + return VIDEO_DEPTH_8BIT; + case 15: case 16: + return VIDEO_DEPTH_16BIT; + case 24: case 32: + return VIDEO_DEPTH_32BIT; + default: + return default_depth; + } + } +} + +/* + * Windows message handler + */ + +#ifdef WIN32 +#include +static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL + +extern void SysMediaArrived(void); +extern void SysMediaRemoved(void); +extern HWND GetMainWindowHandle(void); + +static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_DEVICECHANGE: + if (wParam == DBT_DEVICEREMOVECOMPLETE) { + DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; + if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) + SysMediaRemoved(); + } + else if (wParam == DBT_DEVICEARRIVAL) { + DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; + if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) + SysMediaArrived(); + } + return 0; + + default: + if (sdl_window_proc) + return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} +#endif + + +/* + * SheepShaver glue + */ + +#ifdef SHEEPSHAVER +// Color depth modes type +typedef int video_depth; + +// 1, 2, 4 and 8 bit depths use a color palette +static inline bool IsDirectMode(VIDEO_MODE const & mode) +{ + return IsDirectMode(mode.viAppleMode); +} + +// Abstract base class representing one (possibly virtual) monitor +// ("monitor" = rectangular display with a contiguous frame buffer) +class monitor_desc { +public: + monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) {} + virtual ~monitor_desc() {} + + // Get current Mac frame buffer base address + uint32 get_mac_frame_base(void) const {return screen_base;} + + // Set Mac frame buffer base address (called from switch_to_mode()) + void set_mac_frame_base(uint32 base) {screen_base = base;} + + // Get current video mode + const VIDEO_MODE &get_current_mode(void) const {return VModes[cur_mode];} + + // Called by the video driver to switch the video mode on this display + // (must call set_mac_frame_base()) + virtual void switch_to_current_mode(void) = 0; + + // Called by the video driver to set the color palette (in indexed modes) + // or the gamma table (in direct modes) + virtual void set_palette(uint8 *pal, int num) = 0; +}; + +// Vector of pointers to available monitor descriptions, filled by VideoInit() +static vector VideoMonitors; + +// Find Apple mode matching best specified dimensions +static int find_apple_resolution(int xsize, int ysize) +{ + if (xsize == 640 && ysize == 480) + return APPLE_640x480; + if (xsize == 800 && ysize == 600) + return APPLE_800x600; + if (xsize == 1024 && ysize == 768) + return APPLE_1024x768; + if (xsize == 1152 && ysize == 768) + return APPLE_1152x768; + if (xsize == 1152 && ysize == 900) + return APPLE_1152x900; + if (xsize == 1280 && ysize == 1024) + return APPLE_1280x1024; + if (xsize == 1600 && ysize == 1200) + return APPLE_1600x1200; + return APPLE_CUSTOM; +} + +// Display error alert +static void ErrorAlert(int error) +{ + ErrorAlert(GetString(error)); +} +#endif + + +/* + * monitor_desc subclass for SDL display + */ + +class SDL_monitor_desc : public monitor_desc { +public: + SDL_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} + ~SDL_monitor_desc() {} + + virtual void switch_to_current_mode(void); + virtual void set_palette(uint8 *pal, int num); + + bool video_open(void); + void video_close(void); +}; + + +/* + * Utility functions + */ + +// Find palette size for given color depth +static int palette_size(int mode) +{ + switch (mode) { + case VIDEO_DEPTH_1BIT: return 2; + case VIDEO_DEPTH_2BIT: return 4; + case VIDEO_DEPTH_4BIT: return 16; + case VIDEO_DEPTH_8BIT: return 256; + case VIDEO_DEPTH_16BIT: return 32; + case VIDEO_DEPTH_32BIT: return 256; + default: return 0; + } +} + +// Map video_mode depth ID to numerical depth value +static int mac_depth_of_video_depth(int video_depth) +{ + int depth = -1; + switch (video_depth) { + case VIDEO_DEPTH_1BIT: + depth = 1; + break; + case VIDEO_DEPTH_2BIT: + depth = 2; + break; + case VIDEO_DEPTH_4BIT: + depth = 4; + break; + case VIDEO_DEPTH_8BIT: + depth = 8; + break; + case VIDEO_DEPTH_16BIT: + depth = 16; + break; + case VIDEO_DEPTH_32BIT: + depth = 32; + break; + default: + abort(); + } + return depth; +} + +// Map video_mode depth ID to SDL screen depth +static int sdl_depth_of_video_depth(int video_depth) +{ + return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth); +} + +// Get screen dimensions +static void sdl_display_dimensions(int &width, int &height) +{ + static int max_width, max_height; + if (max_width == 0 && max_height == 0) { + max_width = 640 ; max_height = 480; + SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); + if (modes && modes != (SDL_Rect **)-1) { + // It turns out that on some implementations, and contrary to the documentation, + // the returned list is not sorted from largest to smallest (e.g. Windows) + for (int i = 0; modes[i] != NULL; i++) { + const int w = modes[i]->w; + const int h = modes[i]->h; + if (w > max_width && h > max_height) { + max_width = w; + max_height = h; + } + } + } + } + width = max_width; + height = max_height; +} + +static inline int sdl_display_width(void) +{ + int width, height; + sdl_display_dimensions(width, height); + return width; +} + +static inline int sdl_display_height(void) +{ + int width, height; + sdl_display_dimensions(width, height); + return height; +} + +// Check whether specified mode is available +static bool has_mode(int type, int width, int height, int depth) +{ + // Filter out out-of-bounds resolutions + if (width > sdl_display_width() || height > sdl_display_height()) + return false; + + // Rely on SDL capabilities + return SDL_VideoModeOK(width, height, + sdl_depth_of_video_depth(depth), + SDL_HWSURFACE | (type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0)) != 0; +} + +// Add mode to list of supported modes +static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) +{ + // Filter out unsupported modes + if (!has_mode(type, width, height, depth)) + return; + + // Fill in VideoMode entry + VIDEO_MODE mode; +#ifdef SHEEPSHAVER + resolution_id = find_apple_resolution(width, height); + mode.viType = type; +#endif + VIDEO_MODE_X = width; + VIDEO_MODE_Y = height; + VIDEO_MODE_RESOLUTION = resolution_id; + VIDEO_MODE_ROW_BYTES = bytes_per_row; + VIDEO_MODE_DEPTH = (video_depth)depth; + VideoModes.push_back(mode); +} + +// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) +static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth) +{ +#if !REAL_ADDRESSING && !DIRECT_ADDRESSING + int layout = FLAYOUT_DIRECT; + if (depth == VIDEO_DEPTH_16BIT) + layout = (screen_depth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; + else if (depth == VIDEO_DEPTH_32BIT) + layout = (screen_depth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; + MacFrameLayout = layout; + monitor.set_mac_frame_base(MacFrameBaseMac); + + // Set variables used by UAE memory banking + const VIDEO_MODE &mode = monitor.get_current_mode(); + MacFrameBaseHost = the_buffer; + MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; + InitFrameBufferMapping(); +#else + monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); +#endif + D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); +} + +// Set window name and class +static void set_window_name(int name) +{ + const SDL_VideoInfo *vi = SDL_GetVideoInfo(); + if (vi && vi->wm_available) { + const char *str = GetString(name); + SDL_WM_SetCaption(str, str); + } +} + +// Set mouse grab mode +static SDL_GrabMode set_grab_mode(SDL_GrabMode mode) +{ + const SDL_VideoInfo *vi = SDL_GetVideoInfo(); + return (vi && vi->wm_available ? SDL_WM_GrabInput(mode) : SDL_GRAB_OFF); +} + +// Migrate preferences items (XXX to be handled in MigratePrefs()) +static void migrate_screen_prefs(void) +{ +#ifdef SHEEPSHAVER + // Look-up priorities are: "screen", "screenmodes", "windowmodes". + if (PrefsFindString("screen")) + return; + + uint32 window_modes = PrefsFindInt32("windowmodes"); + uint32 screen_modes = PrefsFindInt32("screenmodes"); + int width = 0, height = 0; + if (screen_modes) { + static const struct { + int id; + int width; + int height; + } + modes[] = { + { 1, 640, 480 }, + { 2, 800, 600 }, + { 4, 1024, 768 }, + { 64, 1152, 768 }, + { 8, 1152, 900 }, + { 16, 1280, 1024 }, + { 32, 1600, 1200 }, + { 0, } + }; + for (int i = 0; modes[i].id != 0; i++) { + if (screen_modes & modes[i].id) { + if (width < modes[i].width && height < modes[i].height) { + width = modes[i].width; + height = modes[i].height; + } + } + } + } else { + if (window_modes & 1) + width = 640, height = 480; + if (window_modes & 2) + width = 800, height = 600; + } + if (width && height) { + char str[32]; + sprintf(str, "%s/%d/%d", screen_modes ? "dga" : "win", width, height); + PrefsReplaceString("screen", str); + } +#endif +} + +void update_sdl_video(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h) +{ + SDL_UpdateRect(screen, x, y, w, h); +} + +void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects) +{ + SDL_UpdateRects(screen, numrects, rects); +} + + +/* + * Display "driver" classes + */ + +class driver_base { +public: + driver_base(SDL_monitor_desc &m); + ~driver_base(); + + void init(); // One-time init + void set_video_mode(int flags); + void adapt_to_video_mode(); + + void update_palette(void); + void suspend(void) {} + void resume(void) {} + void toggle_mouse_grab(void); + void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } + + void disable_mouse_accel(void); + void restore_mouse_accel(void); + + void grab_mouse(void); + void ungrab_mouse(void); + +public: + SDL_monitor_desc &monitor; // Associated video monitor + const VIDEO_MODE &mode; // Video mode handled by the driver + + bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) + SDL_Surface *s; // The surface we draw into +}; + +#ifdef ENABLE_VOSF +static void update_display_window_vosf(driver_base *drv); +#endif +static void update_display_static(driver_base *drv); + +static driver_base *drv = NULL; // Pointer to currently used driver object + +#ifdef ENABLE_VOSF +# include "video_vosf.h" +#endif + +driver_base::driver_base(SDL_monitor_desc &m) + : monitor(m), mode(m.get_current_mode()), init_ok(false), s(NULL) +{ + the_buffer = NULL; + the_buffer_copy = NULL; +} + +void driver_base::set_video_mode(int flags) +{ + int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); + if ((s = SDL_SetVideoMode(VIDEO_MODE_X, VIDEO_MODE_Y, depth, + SDL_HWSURFACE | flags)) == NULL) + return; +#ifdef ENABLE_VOSF + the_host_buffer = (uint8 *)s->pixels; +#endif +} + +void driver_base::init() +{ + set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); + int aligned_height = (VIDEO_MODE_Y + 15) & ~15; + +#ifdef ENABLE_VOSF + use_vosf = true; + // Allocate memory for frame buffer (SIZE is extended to page-boundary) + the_buffer_size = page_extend((aligned_height + 2) * s->pitch); + the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); + the_buffer_copy = (uint8 *)malloc(the_buffer_size); + D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); + + // Check whether we can initialize the VOSF subsystem and it's profitable + if (!video_vosf_init(monitor)) { + WarningAlert(GetString(STR_VOSF_INIT_ERR)); + use_vosf = false; + } + else if (!video_vosf_profitable()) { + video_vosf_exit(); + printf("VOSF acceleration is not profitable on this platform, disabling it\n"); + use_vosf = false; + } + if (!use_vosf) { + free(the_buffer_copy); + vm_release(the_buffer, the_buffer_size); + the_host_buffer = NULL; + } +#endif + if (!use_vosf) { + // Allocate memory for frame buffer + the_buffer_size = (aligned_height + 2) * s->pitch; + the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); + the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); + D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); + } + + // Set frame buffer base + set_mac_frame_buffer(monitor, VIDEO_MODE_DEPTH); + + adapt_to_video_mode(); +} + +void driver_base::adapt_to_video_mode() { + ADBSetRelMouseMode(false); + + // Init blitting routines + SDL_PixelFormat *f = s->format; + VisualFormat visualFormat; + visualFormat.depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); + visualFormat.Rmask = f->Rmask; + visualFormat.Gmask = f->Gmask; + visualFormat.Bmask = f->Bmask; + Screen_blitter_init(visualFormat, true, mac_depth_of_video_depth(VIDEO_MODE_DEPTH)); + + // Load gray ramp to 8->16/32 expand map + if (!IsDirectMode(mode)) + for (int i=0; i<256; i++) + ExpandMap[i] = SDL_MapRGB(f, i, i, i); + + + bool hardware_cursor = false; +#ifdef SHEEPSHAVER + hardware_cursor = video_can_change_cursor(); + if (hardware_cursor) { + // Create cursor + if ((sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, 0, 0)) != NULL) { + SDL_SetCursor(sdl_cursor); + } + } + // Tell the video driver there's a change in cursor type + if (private_data) + private_data->cursorHardware = hardware_cursor; +#endif + // Hide cursor + SDL_ShowCursor(hardware_cursor); + + // Set window name/class + set_window_name(STR_WINDOW_TITLE); + + // Everything went well + init_ok = true; +} + +driver_base::~driver_base() +{ + ungrab_mouse(); + restore_mouse_accel(); + + if (s) + SDL_FreeSurface(s); + + // the_buffer shall always be mapped through vm_acquire_framebuffer() + if (the_buffer != VM_MAP_FAILED) { + D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); + vm_release_framebuffer(the_buffer, the_buffer_size); + the_buffer = NULL; + } + + // Free frame buffer(s) + if (!use_vosf) { + if (the_buffer_copy) { + free(the_buffer_copy); + the_buffer_copy = NULL; + } + } +#ifdef ENABLE_VOSF + else { + if (the_buffer_copy) { + D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); + free(the_buffer_copy); + the_buffer_copy = NULL; + } + + // Deinitialize VOSF + video_vosf_exit(); + } +#endif + + SDL_ShowCursor(1); +} + +// Palette has changed +void driver_base::update_palette(void) +{ + const VIDEO_MODE &mode = monitor.get_current_mode(); + + if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) + SDL_SetPalette(s, SDL_PHYSPAL, sdl_palette, 0, 256); +} + +// Disable mouse acceleration +void driver_base::disable_mouse_accel(void) +{ +} + +// Restore mouse acceleration to original value +void driver_base::restore_mouse_accel(void) +{ +} + +// Toggle mouse grab +void driver_base::toggle_mouse_grab(void) +{ + if (mouse_grabbed) + ungrab_mouse(); + else + grab_mouse(); +} + +// Grab mouse, switch to relative mouse mode +void driver_base::grab_mouse(void) +{ + if (!mouse_grabbed) { + SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_ON); + if (new_mode == SDL_GRAB_ON) { + disable_mouse_accel(); + mouse_grabbed = true; + } + } +} + +// Ungrab mouse, switch to absolute mouse mode +void driver_base::ungrab_mouse(void) +{ + if (mouse_grabbed) { + SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_OFF); + if (new_mode == SDL_GRAB_OFF) { + restore_mouse_accel(); + mouse_grabbed = false; + } + } +} + +/* + * Initialization + */ + +// Init keycode translation table +static void keycode_init(void) +{ + bool use_kc = PrefsFindBool("keycodes"); + if (use_kc) { + + // Get keycode file path from preferences + const char *kc_path = PrefsFindString("keycodefile"); + + // Open keycode table + FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); + if (f == NULL) { + char str[256]; + snprintf(str, sizeof(str), GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); + WarningAlert(str); + return; + } + + // Default translation table + for (int i=0; i<256; i++) + keycode_table[i] = -1; + + // Search for server vendor string, then read keycodes + char video_driver[256]; + SDL_VideoDriverName(video_driver, sizeof(video_driver)); + bool video_driver_found = false; + char line[256]; + int n_keys = 0; + while (fgets(line, sizeof(line) - 1, f)) { + // Read line + int len = strlen(line); + if (len == 0) + continue; + line[len-1] = 0; + + // Comments begin with "#" or ";" + if (line[0] == '#' || line[0] == ';' || line[0] == 0) + continue; + + if (video_driver_found) { + // Skip aliases as long as we have read keycodes yet + // Otherwise, it's another mapping and we have to stop + static const char sdl_str[] = "sdl"; + if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0 && n_keys == 0) + continue; + + // Read keycode + int x_code, mac_code; + if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) + keycode_table[x_code & 0xff] = mac_code, n_keys++; + else + break; + } else { + // Search for SDL video driver string + static const char sdl_str[] = "sdl"; + if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) { + char *p = line + sizeof(sdl_str); + if (strstr(video_driver, p) == video_driver) + video_driver_found = true; + } + } + } + + // Keycode file completely read + fclose(f); + use_keycodes = video_driver_found; + + // Vendor not found? Then display warning + if (!video_driver_found) { + char str[256]; + snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver, kc_path ? kc_path : KEYCODE_FILE_NAME); + WarningAlert(str); + return; + } + + D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver, n_keys)); + } +} + +// Open display for current mode +bool SDL_monitor_desc::video_open(void) +{ + D(bug("video_open()\n")); +#if DEBUG + const VIDEO_MODE &mode = get_current_mode(); + D(bug("Current video mode:\n")); + D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f))); +#endif + + // Create display driver object of requested type + drv = new(std::nothrow) driver_base(*this); + if (drv == NULL) + return false; + drv->init(); + if (!drv->init_ok) { + delete drv; + drv = NULL; + return false; + } + +#ifdef WIN32 + // Chain in a new message handler for WM_DEVICECHANGE + HWND the_window = GetMainWindowHandle(); + sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); + SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); +#endif + + // Initialize VideoRefresh function + VideoRefreshInit(); + + // Lock down frame buffer + LOCK_FRAME_BUFFER; + + // Start redraw/input thread +#ifndef USE_CPU_EMUL_SERVICES + redraw_thread_cancel = false; + redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, NULL)) != NULL); + if (!redraw_thread_active) { + printf("FATAL: cannot create redraw thread\n"); + return false; + } +#else + redraw_thread_active = true; +#endif + return true; +} + +#ifdef SHEEPSHAVER +bool VideoInit(void) +{ + const bool classic = false; +#else +bool VideoInit(bool classic) +{ +#endif + classic_mode = classic; + +#ifdef ENABLE_VOSF + // Zero the mainBuffer structure + mainBuffer.dirtyPages = NULL; + mainBuffer.pageInfo = NULL; +#endif + + // Create Mutexes + if ((sdl_events_lock = SDL_CreateMutex()) == NULL) + return false; + if ((sdl_palette_lock = SDL_CreateMutex()) == NULL) + return false; + if ((frame_buffer_lock = SDL_CreateMutex()) == NULL) + return false; + + // Init keycode translation + keycode_init(); + + // Read prefs + frame_skip = PrefsFindInt32("frameskip"); + mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); + mouse_wheel_lines = PrefsFindInt32("mousewheellines"); + + // Get screen mode from preferences + migrate_screen_prefs(); + const char *mode_str = NULL; + if (classic_mode) + mode_str = "win/512/342"; + else + mode_str = PrefsFindString("screen"); + + // Determine display type and default dimensions + int default_width, default_height; + if (classic) { + default_width = 512; + default_height = 384; + } + else { + default_width = 640; + default_height = 480; + } + display_type = DISPLAY_WINDOW; + if (mode_str) { + if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) + display_type = DISPLAY_WINDOW; + else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) + display_type = DISPLAY_SCREEN; + } + if (default_width <= 0) + default_width = sdl_display_width(); + else if (default_width > sdl_display_width()) + default_width = sdl_display_width(); + if (default_height <= 0) + default_height = sdl_display_height(); + else if (default_height > sdl_display_height()) + default_height = sdl_display_height(); + + // Mac screen depth follows X depth + screen_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; + int default_depth; + switch (screen_depth) { + case 8: + default_depth = VIDEO_DEPTH_8BIT; + break; + case 15: case 16: + default_depth = VIDEO_DEPTH_16BIT; + break; + case 24: case 32: + default_depth = VIDEO_DEPTH_32BIT; + break; + default: + default_depth = VIDEO_DEPTH_1BIT; + break; + } + + // Initialize list of video modes to try + struct { + int w; + int h; + int resolution_id; + } +#ifdef SHEEPSHAVER + // Omit Classic resolutions + video_modes[] = { + { -1, -1, 0x80 }, + { 640, 480, 0x81 }, + { 800, 600, 0x82 }, + { 1024, 768, 0x83 }, + { 1152, 870, 0x84 }, + { 1280, 1024, 0x85 }, + { 1600, 1200, 0x86 }, + { 0, } + }; +#else + video_modes[] = { + { -1, -1, 0x80 }, + { 512, 384, 0x80 }, + { 640, 480, 0x81 }, + { 800, 600, 0x82 }, + { 1024, 768, 0x83 }, + { 1152, 870, 0x84 }, + { 1280, 1024, 0x85 }, + { 1600, 1200, 0x86 }, + { 0, } + }; +#endif + video_modes[0].w = default_width; + video_modes[0].h = default_height; + + // Construct list of supported modes + if (display_type == DISPLAY_WINDOW) { + if (classic) + add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT); + else { + for (int i = 0; video_modes[i].w != 0; i++) { + const int w = video_modes[i].w; + const int h = video_modes[i].h; + if (i > 0 && (w >= default_width || h >= default_height)) + continue; + for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) + add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); + } + } + } else if (display_type == DISPLAY_SCREEN) { + for (int i = 0; video_modes[i].w != 0; i++) { + const int w = video_modes[i].w; + const int h = video_modes[i].h; + if (i > 0 && (w >= default_width || h >= default_height)) + continue; + if (w == 512 && h == 384) + continue; + for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) + add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); + } + } + + if (VideoModes.empty()) { + ErrorAlert(STR_NO_XVISUAL_ERR); + return false; + } + + // Find requested default mode with specified dimensions + uint32 default_id; + std::vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { + const VIDEO_MODE & mode = (*i); + if (VIDEO_MODE_X == default_width && VIDEO_MODE_Y == default_height && VIDEO_MODE_DEPTH == default_depth) { + default_id = VIDEO_MODE_RESOLUTION; +#ifdef SHEEPSHAVER + std::vector::const_iterator begin = VideoModes.begin(); + cur_mode = distance(begin, i); +#endif + break; + } + } + if (i == end) { // not found, use first available mode + const VIDEO_MODE & mode = VideoModes[0]; + default_depth = VIDEO_MODE_DEPTH; + default_id = VIDEO_MODE_RESOLUTION; +#ifdef SHEEPSHAVER + cur_mode = 0; +#endif + } + +#ifdef SHEEPSHAVER + for (int i = 0; i < VideoModes.size(); i++) + VModes[i] = VideoModes[i]; + VideoInfo *p = &VModes[VideoModes.size()]; + p->viType = DIS_INVALID; // End marker + p->viRowBytes = 0; + p->viXsize = p->viYsize = 0; + p->viAppleMode = 0; + p->viAppleID = 0; +#endif + +#if DEBUG + D(bug("Available video modes:\n")); + for (i = VideoModes.begin(); i != end; ++i) { + const VIDEO_MODE & mode = (*i); + int bits = 1 << VIDEO_MODE_DEPTH; + if (bits == 16) + bits = 15; + else if (bits == 32) + bits = 24; + D(bug(" %dx%d (ID %02x), %d colors\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << bits)); + } +#endif + + int color_depth = get_customized_color_depth(default_depth); + + D(bug("Return get_customized_color_depth %d\n", color_depth)); + + // Create SDL_monitor_desc for this (the only) display + SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)color_depth, default_id); + VideoMonitors.push_back(monitor); + + // Open display + return monitor->video_open(); +} + + +/* + * Deinitialization + */ + +// Close display +void SDL_monitor_desc::video_close(void) +{ + D(bug("video_close()\n")); + +#ifdef WIN32 + // Remove message handler for WM_DEVICECHANGE + HWND the_window = GetMainWindowHandle(); + SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); +#endif + + // Stop redraw thread +#ifndef USE_CPU_EMUL_SERVICES + if (redraw_thread_active) { + redraw_thread_cancel = true; + SDL_WaitThread(redraw_thread, NULL); + } +#endif + redraw_thread_active = false; + + // Unlock frame buffer + UNLOCK_FRAME_BUFFER; + D(bug(" frame buffer unlocked\n")); + + // Close display + delete drv; + drv = NULL; +} + +void VideoExit(void) +{ + // Close displays + vector::iterator i, end = VideoMonitors.end(); + for (i = VideoMonitors.begin(); i != end; ++i) + dynamic_cast(*i)->video_close(); + + // Destroy locks + if (frame_buffer_lock) + SDL_DestroyMutex(frame_buffer_lock); + if (sdl_palette_lock) + SDL_DestroyMutex(sdl_palette_lock); + if (sdl_events_lock) + SDL_DestroyMutex(sdl_events_lock); +} + + +/* + * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) + */ + +void VideoQuitFullScreen(void) +{ + D(bug("VideoQuitFullScreen()\n")); + quit_full_screen = true; +} + +static void do_toggle_fullscreen(void) +{ +#ifndef USE_CPU_EMUL_SERVICES + // pause redraw thread + thread_stop_ack = false; + thread_stop_req = true; + while (!thread_stop_ack) ; +#endif + + // save the mouse position + int x, y; + SDL_GetMouseState(&x, &y); + + // save the screen contents + SDL_Surface *tmp_surface = SDL_ConvertSurface(drv->s, drv->s->format, + drv->s->flags); + + // switch modes + display_type = (display_type == DISPLAY_SCREEN) ? DISPLAY_WINDOW + : DISPLAY_SCREEN; + drv->set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); + drv->adapt_to_video_mode(); + + // reset the palette +#ifdef SHEEPSHAVER + video_set_palette(); +#endif + drv->update_palette(); + + // restore the screen contents + SDL_BlitSurface(tmp_surface, NULL, drv->s, NULL); + SDL_FreeSurface(tmp_surface); + SDL_UpdateRect(drv->s, 0, 0, 0, 0); + + // reset the video refresh handler + VideoRefreshInit(); + + // while SetVideoMode is happening, control key up may be missed + ADBKeyUp(0x36); + + // restore the mouse position + SDL_WarpMouse(x, y); + + // resume redraw thread + toggle_fullscreen = false; +#ifndef USE_CPU_EMUL_SERVICES + thread_stop_req = false; +#endif +} + +/* + * Mac VBL interrupt + */ + +/* + * Execute video VBL routine + */ + +#ifdef SHEEPSHAVER +void VideoVBL(void) +{ + // Emergency quit requested? Then quit + if (emerg_quit) + QuitEmulator(); + + if (toggle_fullscreen) + do_toggle_fullscreen(); + + // Setting the window name must happen on the main thread, else it doesn't work on + // some platforms - e.g. macOS Sierra. + if (mouse_grabbed_window_name_status != mouse_grabbed) { + set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE); + mouse_grabbed_window_name_status = mouse_grabbed; + } + + // Temporarily give up frame buffer lock (this is the point where + // we are suspended when the user presses Ctrl-Tab) + UNLOCK_FRAME_BUFFER; + LOCK_FRAME_BUFFER; + + // Execute video VBL + if (private_data != NULL && private_data->interruptsEnabled) + VSLDoInterruptService(private_data->vslServiceID); +} +#else +void VideoInterrupt(void) +{ + // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() + SDL_PumpEvents(); + + // Emergency quit requested? Then quit + if (emerg_quit) + QuitEmulator(); + + if (toggle_fullscreen) + do_toggle_fullscreen(); + + // Setting the window name must happen on the main thread, else it doesn't work on + // some platforms - e.g. macOS Sierra. + if (mouse_grabbed_window_name_status != mouse_grabbed) { + set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE); + mouse_grabbed_window_name_status = mouse_grabbed; + } + + // Temporarily give up frame buffer lock (this is the point where + // we are suspended when the user presses Ctrl-Tab) + UNLOCK_FRAME_BUFFER; + LOCK_FRAME_BUFFER; +} +#endif + + +/* + * Set palette + */ + +#ifdef SHEEPSHAVER +void video_set_palette(void) +{ + monitor_desc * monitor = VideoMonitors[0]; + int n_colors = palette_size(monitor->get_current_mode().viAppleMode); + uint8 pal[256 * 3]; + for (int c = 0; c < n_colors; c++) { + pal[c*3 + 0] = mac_pal[c].red; + pal[c*3 + 1] = mac_pal[c].green; + pal[c*3 + 2] = mac_pal[c].blue; + } + monitor->set_palette(pal, n_colors); +} +#endif + +void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) +{ + const VIDEO_MODE &mode = get_current_mode(); + + if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) { + // handle the gamma ramp + + if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey + return; // ignore + + uint16 red[256]; + uint16 green[256]; + uint16 blue[256]; + + int repeats = 256 / num_in; + + for (int i = 0; i < num_in; i++) { + for (int j = 0; j < repeats; j++) { + red[i*repeats + j] = pal[i*3 + 0] << 8; + green[i*repeats + j] = pal[i*3 + 1] << 8; + blue[i*repeats + j] = pal[i*3 + 2] << 8; + } + } + + // fill remaining entries (if any) with last value + for (int i = num_in * repeats; i < 256; i++) { + red[i] = pal[(num_in - 1) * 3] << 8; + green[i] = pal[(num_in - 1) * 3 + 1] << 8; + blue[i] = pal[(num_in - 1) * 3 + 2] << 8; + } + + bool changed = (memcmp(red, last_gamma_red, 512) != 0 || + memcmp(green, last_gamma_green, 512) != 0 || + memcmp(blue, last_gamma_blue, 512) != 0); + + if (changed) { + int result = SDL_SetGammaRamp(red, green, blue); + + if (result < 0) { + fprintf(stderr, "SDL_SetGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); + } + + memcpy(last_gamma_red, red, 512); + memcpy(last_gamma_green, green, 512); + memcpy(last_gamma_blue, blue, 512); + } + + return; + } + + LOCK_PALETTE; + + // Convert colors to XColor array + int num_out = 256; + bool stretch = false; + SDL_Color *p = sdl_palette; + for (int i=0; ir = pal[c*3 + 0] * 0x0101; + p->g = pal[c*3 + 1] * 0x0101; + p->b = pal[c*3 + 2] * 0x0101; + p++; + } + + // Recalculate pixel color expansion map + if (!IsDirectMode(mode)) { + for (int i=0; i<256; i++) { + int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) + ExpandMap[i] = SDL_MapRGB(drv->s->format, pal[c*3+0], pal[c*3+1], pal[c*3+2]); + } + +#ifdef ENABLE_VOSF + if (use_vosf) { + // We have to redraw everything because the interpretation of pixel values changed + LOCK_VOSF; + PFLAG_SET_ALL; + UNLOCK_VOSF; + memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); + } +#endif + } + + // Tell redraw thread to change palette + sdl_palette_changed = true; + + UNLOCK_PALETTE; +} + + +/* + * Switch video mode + */ + +#ifdef SHEEPSHAVER +int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) +{ + /* return if no mode change */ + if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && + (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; + + /* first find video mode in table */ + for (int i=0; VModes[i].viType != DIS_INVALID; i++) { + if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && + (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { + csSave->saveMode = ReadMacInt16(ParamPtr + csMode); + csSave->saveData = ReadMacInt32(ParamPtr + csData); + csSave->savePage = ReadMacInt16(ParamPtr + csPage); + + // Disable interrupts and pause redraw thread + DisableInterrupt(); + thread_stop_ack = false; + thread_stop_req = true; + while (!thread_stop_ack) ; + + cur_mode = i; + monitor_desc *monitor = VideoMonitors[0]; + monitor->switch_to_current_mode(); + + WriteMacInt32(ParamPtr + csBaseAddr, screen_base); + csSave->saveBaseAddr=screen_base; + csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ + csSave->saveMode=VModes[cur_mode].viAppleMode; + + // Enable interrupts and resume redraw thread + thread_stop_req = false; + EnableInterrupt(); + return noErr; + } + } + return paramErr; +} +#endif + +void SDL_monitor_desc::switch_to_current_mode(void) +{ + // Close and reopen display + LOCK_EVENTS; + video_close(); + video_open(); + UNLOCK_EVENTS; + + if (drv == NULL) { + ErrorAlert(STR_OPEN_WINDOW_ERR); + QuitEmulator(); + } +} + + +/* + * Can we set the MacOS cursor image into the window? + */ + +#ifdef SHEEPSHAVER +bool video_can_change_cursor(void) +{ + if (display_type != DISPLAY_WINDOW) + return false; + +#if defined(__APPLE__) + static char driver[] = "Quartz?"; + static int quartzok = -1; + + if (quartzok < 0) { + if (SDL_VideoDriverName(driver, sizeof driver) == NULL || strncmp(driver, "Quartz", sizeof driver)) + quartzok = true; + else { + // Quartz driver bug prevents cursor changing in SDL 1.2.11 to 1.2.14. + const SDL_version *vp = SDL_Linked_Version(); + int version = SDL_VERSIONNUM(vp->major, vp->minor, vp->patch); + quartzok = (version <= SDL_VERSIONNUM(1, 2, 10) || version >= SDL_VERSIONNUM(1, 2, 15)); + } + } + + return quartzok; +#else + return true; +#endif +} +#endif + + +/* + * Set cursor image for window + */ + +#ifdef SHEEPSHAVER +void video_set_cursor(void) +{ + // Set new cursor image if it was changed + if (sdl_cursor) { + SDL_FreeCursor(sdl_cursor); + sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); + if (sdl_cursor) { + SDL_ShowCursor(private_data == NULL || private_data->cursorVisible); + SDL_SetCursor(sdl_cursor); + + // XXX Windows apparently needs an extra mouse event to + // make the new cursor image visible. + // On Mac, if mouse is grabbed, SDL_ShowCursor() recenters the + // mouse, we have to put it back. + bool move = false; +#ifdef WIN32 + move = true; +#elif defined(__APPLE__) + move = mouse_grabbed; +#endif + if (move) { + int visible = SDL_ShowCursor(-1); + if (visible) { + int x, y; + SDL_GetMouseState(&x, &y); + SDL_WarpMouse(x, y); + } + } + } + } +} +#endif + + +/* + * Keyboard-related utilify functions + */ + +static bool is_modifier_key(SDL_KeyboardEvent const & e) +{ + switch (e.keysym.sym) { + case SDLK_NUMLOCK: + case SDLK_CAPSLOCK: + case SDLK_SCROLLOCK: + case SDLK_RSHIFT: + case SDLK_LSHIFT: + case SDLK_RCTRL: + case SDLK_LCTRL: + case SDLK_RALT: + case SDLK_LALT: + case SDLK_RMETA: + case SDLK_LMETA: + case SDLK_LSUPER: + case SDLK_RSUPER: + case SDLK_MODE: + case SDLK_COMPOSE: + return true; + } + return false; +} + +static bool is_ctrl_down(SDL_keysym const & ks) +{ + return ctrl_down || (ks.mod & KMOD_CTRL); +} + + +/* + * Translate key event to Mac keycode, returns -1 if no keycode was found + * and -2 if the key was recognized as a hotkey + */ + +static int kc_decode(SDL_keysym const & ks, bool key_down) +{ + switch (ks.sym) { + case SDLK_a: return 0x00; + case SDLK_b: return 0x0b; + case SDLK_c: return 0x08; + case SDLK_d: return 0x02; + case SDLK_e: return 0x0e; + case SDLK_f: return 0x03; + case SDLK_g: return 0x05; + case SDLK_h: return 0x04; + case SDLK_i: return 0x22; + case SDLK_j: return 0x26; + case SDLK_k: return 0x28; + case SDLK_l: return 0x25; + case SDLK_m: return 0x2e; + case SDLK_n: return 0x2d; + case SDLK_o: return 0x1f; + case SDLK_p: return 0x23; + case SDLK_q: return 0x0c; + case SDLK_r: return 0x0f; + case SDLK_s: return 0x01; + case SDLK_t: return 0x11; + case SDLK_u: return 0x20; + case SDLK_v: return 0x09; + case SDLK_w: return 0x0d; + case SDLK_x: return 0x07; + case SDLK_y: return 0x10; + case SDLK_z: return 0x06; + + case SDLK_1: case SDLK_EXCLAIM: return 0x12; + case SDLK_2: case SDLK_AT: return 0x13; + case SDLK_3: case SDLK_HASH: return 0x14; + case SDLK_4: case SDLK_DOLLAR: return 0x15; + case SDLK_5: return 0x17; + case SDLK_6: return 0x16; + case SDLK_7: return 0x1a; + case SDLK_8: return 0x1c; + case SDLK_9: return 0x19; + case SDLK_0: return 0x1d; + + case SDLK_BACKQUOTE: return 0x0a; + case SDLK_MINUS: case SDLK_UNDERSCORE: return 0x1b; + case SDLK_EQUALS: case SDLK_PLUS: return 0x18; + case SDLK_LEFTBRACKET: return 0x21; + case SDLK_RIGHTBRACKET: return 0x1e; + case SDLK_BACKSLASH: return 0x2a; + case SDLK_SEMICOLON: case SDLK_COLON: return 0x29; + case SDLK_QUOTE: case SDLK_QUOTEDBL: return 0x27; + case SDLK_COMMA: case SDLK_LESS: return 0x2b; + case SDLK_PERIOD: case SDLK_GREATER: return 0x2f; + case SDLK_SLASH: case SDLK_QUESTION: return 0x2c; + + case SDLK_TAB: if (is_ctrl_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30; + case SDLK_RETURN: if (is_ctrl_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24; + case SDLK_SPACE: return 0x31; + case SDLK_BACKSPACE: return 0x33; + + case SDLK_DELETE: return 0x75; + case SDLK_INSERT: return 0x72; + case SDLK_HOME: case SDLK_HELP: return 0x73; + case SDLK_END: return 0x77; + case SDLK_PAGEUP: return 0x74; + case SDLK_PAGEDOWN: return 0x79; + + case SDLK_LCTRL: return 0x36; + case SDLK_RCTRL: return 0x36; + case SDLK_LSHIFT: return 0x38; + case SDLK_RSHIFT: return 0x38; +#if (defined(__APPLE__) && defined(__MACH__)) + case SDLK_LALT: return 0x3a; + case SDLK_RALT: return 0x3a; + case SDLK_LMETA: return 0x37; + case SDLK_RMETA: return 0x37; +#else + case SDLK_LALT: return 0x37; + case SDLK_RALT: return 0x37; + case SDLK_LMETA: return 0x3a; + case SDLK_RMETA: return 0x3a; +#endif + case SDLK_LSUPER: return 0x3a; // "Windows" key + case SDLK_RSUPER: return 0x3a; + case SDLK_MENU: return 0x32; + case SDLK_CAPSLOCK: return 0x39; + case SDLK_NUMLOCK: return 0x47; + + case SDLK_UP: return 0x3e; + case SDLK_DOWN: return 0x3d; + case SDLK_LEFT: return 0x3b; + case SDLK_RIGHT: return 0x3c; + + case SDLK_ESCAPE: if (is_ctrl_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35; + + case SDLK_F1: if (is_ctrl_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a; + case SDLK_F2: return 0x78; + case SDLK_F3: return 0x63; + case SDLK_F4: return 0x76; + case SDLK_F5: if (is_ctrl_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60; + case SDLK_F6: return 0x61; + case SDLK_F7: return 0x62; + case SDLK_F8: return 0x64; + case SDLK_F9: return 0x65; + case SDLK_F10: return 0x6d; + case SDLK_F11: return 0x67; + case SDLK_F12: return 0x6f; + + case SDLK_PRINT: return 0x69; + case SDLK_SCROLLOCK: return 0x6b; + case SDLK_PAUSE: return 0x71; + + case SDLK_KP0: return 0x52; + case SDLK_KP1: return 0x53; + case SDLK_KP2: return 0x54; + case SDLK_KP3: return 0x55; + case SDLK_KP4: return 0x56; + case SDLK_KP5: return 0x57; + case SDLK_KP6: return 0x58; + case SDLK_KP7: return 0x59; + case SDLK_KP8: return 0x5b; + case SDLK_KP9: return 0x5c; + case SDLK_KP_PERIOD: return 0x41; + case SDLK_KP_PLUS: return 0x45; + case SDLK_KP_MINUS: return 0x4e; + case SDLK_KP_MULTIPLY: return 0x43; + case SDLK_KP_DIVIDE: return 0x4b; + case SDLK_KP_ENTER: return 0x4c; + case SDLK_KP_EQUALS: return 0x51; + } + D(bug("Unhandled SDL keysym: %d\n", ks.sym)); + return -1; +} + +static int event2keycode(SDL_KeyboardEvent const &ev, bool key_down) +{ + return kc_decode(ev.keysym, key_down); +} + +static void force_complete_window_refresh() +{ + if (display_type == DISPLAY_WINDOW) { +#ifdef ENABLE_VOSF + if (use_vosf) { // VOSF refresh + LOCK_VOSF; + PFLAG_SET_ALL; + UNLOCK_VOSF; + } +#endif + // Ensure each byte of the_buffer_copy differs from the_buffer to force a full update. + const VIDEO_MODE &mode = VideoMonitors[0]->get_current_mode(); + const int len = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; + for (int i = 0; i < len; i++) + the_buffer_copy[i] = !the_buffer[i]; + } +} + +/* + * SDL event handling + */ + +static void handle_events(void) +{ + SDL_Event events[10]; + const int n_max_events = sizeof(events) / sizeof(events[0]); + int n_events; + + while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, sdl_eventmask)) > 0) { + for (int i = 0; i < n_events; i++) { + SDL_Event const & event = events[i]; + switch (event.type) { + + // Mouse button + case SDL_MOUSEBUTTONDOWN: { + unsigned int button = event.button.button; + if (button == SDL_BUTTON_LEFT) + ADBMouseDown(0); + else if (button == SDL_BUTTON_RIGHT) + ADBMouseDown(1); + else if (button == SDL_BUTTON_MIDDLE) + ADBMouseDown(2); + else if (button < 6) { // Wheel mouse + if (mouse_wheel_mode == 0) { + int key = (button == 5) ? 0x79 : 0x74; // Page up/down + ADBKeyDown(key); + ADBKeyUp(key); + } else { + int key = (button == 5) ? 0x3d : 0x3e; // Cursor up/down + for(int i=0; imouse_moved(event.motion.x, event.motion.y); + break; + + // Keyboard + case SDL_KEYDOWN: { + int code = -1; + if (use_keycodes && !is_modifier_key(event.key)) { + if (event2keycode(event.key, true) != -2) // This is called to process the hotkeys + code = keycode_table[event.key.keysym.scancode & 0xff]; + } else + code = event2keycode(event.key, true); + if (code >= 0) { + if (!emul_suspended) { + if (code == 0x39) { // Caps Lock pressed + if (caps_on) { + ADBKeyUp(code); + caps_on = false; + } else { + ADBKeyDown(code); + caps_on = true; + } + } else + ADBKeyDown(code); + if (code == 0x36) + ctrl_down = true; + } else { + if (code == 0x31) + drv->resume(); // Space wakes us up + } + } + break; + } + case SDL_KEYUP: { + int code = -1; + if (use_keycodes && !is_modifier_key(event.key)) { + if (event2keycode(event.key, false) != -2) // This is called to process the hotkeys + code = keycode_table[event.key.keysym.scancode & 0xff]; + } else + code = event2keycode(event.key, false); + if (code >= 0) { + if (code == 0x39) { // Caps Lock released + if (caps_on) { + ADBKeyUp(code); + caps_on = false; + } else { + ADBKeyDown(code); + caps_on = true; + } + } else + ADBKeyUp(code); + if (code == 0x36) + ctrl_down = false; + } + break; + } + + // Hidden parts exposed, force complete refresh of window + case SDL_VIDEOEXPOSE: + force_complete_window_refresh(); + break; + + // Window "close" widget clicked + case SDL_QUIT: + ADBKeyDown(0x7f); // Power key + ADBKeyUp(0x7f); + break; + + // Application activate/deactivate + case SDL_ACTIVEEVENT: + // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. + if (event.active.gain) + force_complete_window_refresh(); + break; + } + } + } +} + + +/* + * Window display update + */ + +// Static display update (fixed frame rate, but incremental) +static void update_display_static(driver_base *drv) +{ + // Incremental update code + int wide = 0, high = 0; + uint32 x1, x2, y1, y2; + const VIDEO_MODE &mode = drv->mode; + int bytes_per_row = VIDEO_MODE_ROW_BYTES; + uint8 *p, *p2; + + // Check for first line from top and first line from bottom that have changed + y1 = 0; + for (uint32 j = 0; j < VIDEO_MODE_Y; j++) { + if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { + y1 = j; + break; + } + } + y2 = y1 - 1; + for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) { + if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { + y2 = j; + break; + } + } + high = y2 - y1 + 1; + + // Check for first column from left and first column from right that have changed + if (high) { + if (VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) { + const int src_bytes_per_row = bytes_per_row; + const int dst_bytes_per_row = drv->s->pitch; + const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row; + + x1 = VIDEO_MODE_X / pixels_per_byte; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + for (uint32 i = 0; i < x1; i++) { + if (*p != *p2) { + x1 = i; + break; + } + p++; p2++; + } + } + x2 = x1; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + p += bytes_per_row; + p2 += bytes_per_row; + for (uint32 i = (VIDEO_MODE_X / pixels_per_byte); i > x2; i--) { + p--; p2--; + if (*p != *p2) { + x2 = i; + break; + } + } + } + x1 *= pixels_per_byte; + x2 *= pixels_per_byte; + wide = (x2 - x1 + pixels_per_byte - 1) & -pixels_per_byte; + + // Update copy of the_buffer + if (high && wide) { + + // Lock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_LockSurface(drv->s); + + // Blit to screen surface + int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte); + int di = y1 * dst_bytes_per_row + x1; + for (uint32 j = y1; j <= y2; j++) { + memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte); + Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte); + si += src_bytes_per_row; + di += dst_bytes_per_row; + } + + // Unlock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_UnlockSurface(drv->s); + + // Refresh display + SDL_UpdateRect(drv->s, x1, y1, wide, high); + } + + } else { + const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X; + const int dst_bytes_per_row = drv->s->pitch; + + x1 = VIDEO_MODE_X; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) { + if (*p != *p2) { + x1 = i / bytes_per_pixel; + break; + } + p++; p2++; + } + } + x2 = x1; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + p += bytes_per_row; + p2 += bytes_per_row; + for (uint32 i = VIDEO_MODE_X * bytes_per_pixel; i > x2 * bytes_per_pixel; i--) { + p--; + p2--; + if (*p != *p2) { + x2 = i / bytes_per_pixel; + break; + } + } + } + wide = x2 - x1; + + // Update copy of the_buffer + if (high && wide) { + + // Lock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_LockSurface(drv->s); + + // Blit to screen surface + for (uint32 j = y1; j <= y2; j++) { + uint32 i = j * bytes_per_row + x1 * bytes_per_pixel; + int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel; + memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); + Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide); + } + + // Unlock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_UnlockSurface(drv->s); + + // Refresh display + SDL_UpdateRect(drv->s, x1, y1, wide, high); + } + } + } +} + +// Static display update (fixed frame rate, bounding boxes based) +// XXX use NQD bounding boxes to help detect dirty areas? +static void update_display_static_bbox(driver_base *drv) +{ + const VIDEO_MODE &mode = drv->mode; + + // Allocate bounding boxes for SDL_UpdateRects() + const uint32 N_PIXELS = 64; + const uint32 n_x_boxes = (VIDEO_MODE_X + N_PIXELS - 1) / N_PIXELS; + const uint32 n_y_boxes = (VIDEO_MODE_Y + N_PIXELS - 1) / N_PIXELS; + SDL_Rect *boxes = (SDL_Rect *)alloca(sizeof(SDL_Rect) * n_x_boxes * n_y_boxes); + uint32 nr_boxes = 0; + + // Lock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_LockSurface(drv->s); + + // Update the surface from Mac screen + const uint32 bytes_per_row = VIDEO_MODE_ROW_BYTES; + const uint32 bytes_per_pixel = bytes_per_row / VIDEO_MODE_X; + const uint32 dst_bytes_per_row = drv->s->pitch; + for (uint32 y = 0; y < VIDEO_MODE_Y; y += N_PIXELS) { + uint32 h = N_PIXELS; + if (h > VIDEO_MODE_Y - y) + h = VIDEO_MODE_Y - y; + for (uint32 x = 0; x < VIDEO_MODE_X; x += N_PIXELS) { + uint32 w = N_PIXELS; + if (w > VIDEO_MODE_X - x) + w = VIDEO_MODE_X - x; + const int xs = w * bytes_per_pixel; + const int xb = x * bytes_per_pixel; + bool dirty = false; + for (uint32 j = y; j < (y + h); j++) { + const uint32 yb = j * bytes_per_row; + const uint32 dst_yb = j * dst_bytes_per_row; + if (memcmp(&the_buffer[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { + memcpy(&the_buffer_copy[yb + xb], &the_buffer[yb + xb], xs); + Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, the_buffer + yb + xb, xs); + dirty = true; + } + } + if (dirty) { + boxes[nr_boxes].x = x; + boxes[nr_boxes].y = y; + boxes[nr_boxes].w = w; + boxes[nr_boxes].h = h; + nr_boxes++; + } + } + } + + // Unlock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_UnlockSurface(drv->s); + + // Refresh display + if (nr_boxes) + SDL_UpdateRects(drv->s, nr_boxes, boxes); +} + + +// We suggest the compiler to inline the next two functions so that it +// may specialise the code according to the current screen depth and +// display type. A clever compiler would do that job by itself though... + +// NOTE: update_display_vosf is inlined too + +static inline void possibly_quit_dga_mode() +{ + // Quit DGA mode if requested (something terrible has happened and we + // want to give control back to the user) + if (quit_full_screen) { + quit_full_screen = false; + delete drv; + drv = NULL; + } +} + +static inline void possibly_ungrab_mouse() +{ + // Ungrab mouse if requested (something terrible has happened and we + // want to give control back to the user) + if (quit_full_screen) { + quit_full_screen = false; + if (drv) + drv->ungrab_mouse(); + } +} + +static inline void handle_palette_changes(void) +{ + LOCK_PALETTE; + + if (sdl_palette_changed) { + sdl_palette_changed = false; + drv->update_palette(); + } + + UNLOCK_PALETTE; +} + +static void video_refresh_window_static(void); + +static void video_refresh_dga(void) +{ + // Quit DGA mode if requested + possibly_quit_dga_mode(); + video_refresh_window_static(); +} + +#ifdef ENABLE_VOSF +#if REAL_ADDRESSING || DIRECT_ADDRESSING +static void video_refresh_dga_vosf(void) +{ + // Quit DGA mode if requested + possibly_quit_dga_mode(); + + // Update display (VOSF variant) + static uint32 tick_counter = 0; + if (++tick_counter >= frame_skip) { + tick_counter = 0; + if (mainBuffer.dirty) { + LOCK_VOSF; + update_display_dga_vosf(drv); + UNLOCK_VOSF; + } + } +} +#endif + +static void video_refresh_window_vosf(void) +{ + // Ungrab mouse if requested + possibly_ungrab_mouse(); + + // Update display (VOSF variant) + static uint32 tick_counter = 0; + if (++tick_counter >= frame_skip) { + tick_counter = 0; + if (mainBuffer.dirty) { + LOCK_VOSF; + update_display_window_vosf(drv); + UNLOCK_VOSF; + } + } +} +#endif // def ENABLE_VOSF + +static void video_refresh_window_static(void) +{ + // Ungrab mouse if requested + possibly_ungrab_mouse(); + + // Update display (static variant) + static uint32 tick_counter = 0; + if (++tick_counter >= frame_skip) { + tick_counter = 0; + const VIDEO_MODE &mode = drv->mode; + if ((int)VIDEO_MODE_DEPTH >= VIDEO_DEPTH_8BIT) + update_display_static_bbox(drv); + else + update_display_static(drv); + } +} + + +/* + * Thread for screen refresh, input handling etc. + */ + +static void VideoRefreshInit(void) +{ + // TODO: set up specialised 8bpp VideoRefresh handlers ? + if (display_type == DISPLAY_SCREEN) { +#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) + if (use_vosf) + video_refresh = video_refresh_dga_vosf; + else +#endif + video_refresh = video_refresh_dga; + } + else { +#ifdef ENABLE_VOSF + if (use_vosf) + video_refresh = video_refresh_window_vosf; + else +#endif + video_refresh = video_refresh_window_static; + } +} + +static inline void do_video_refresh(void) +{ + // Handle SDL events + handle_events(); + + // Update display + video_refresh(); + + + // Set new palette if it was changed + handle_palette_changes(); +} + +// This function is called on non-threaded platforms from a timer interrupt +void VideoRefresh(void) +{ + // We need to check redraw_thread_active to inhibit refreshed during + // mode changes on non-threaded platforms + if (!redraw_thread_active) + return; + + // Process pending events and update display + do_video_refresh(); +} + +const int VIDEO_REFRESH_HZ = 60; +const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; + +#ifndef USE_CPU_EMUL_SERVICES +static int redraw_func(void *arg) +{ + uint64 start = GetTicks_usec(); + int64 ticks = 0; + uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; + + while (!redraw_thread_cancel) { + + // Wait + next += VIDEO_REFRESH_DELAY; + int32 delay = int32(next - GetTicks_usec()); + if (delay > 0) + Delay_usec(delay); + else if (delay < -VIDEO_REFRESH_DELAY) + next = GetTicks_usec(); + ticks++; + + // Pause if requested (during video mode switches) + if (thread_stop_req) { + thread_stop_ack = true; + continue; + } + + // Process pending events and update display + do_video_refresh(); + } + + uint64 end = GetTicks_usec(); + D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); + return 0; +} +#endif + + +/* + * Record dirty area from NQD + */ + +#ifdef SHEEPSHAVER +void video_set_dirty_area(int x, int y, int w, int h) +{ +#ifdef ENABLE_VOSF + const VIDEO_MODE &mode = drv->mode; + const unsigned screen_width = VIDEO_MODE_X; + const unsigned screen_height = VIDEO_MODE_Y; + const unsigned bytes_per_row = VIDEO_MODE_ROW_BYTES; + + if (use_vosf) { + vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); + return; + } +#endif + + // XXX handle dirty bounding boxes for non-VOSF modes +} +#endif + +#endif // ends: SDL version check diff --git a/SheepShaver/src/SDL/video_sdl2.cpp b/SheepShaver/src/SDL/video_sdl2.cpp new file mode 100644 index 000000000..77f53fa96 --- /dev/null +++ b/SheepShaver/src/SDL/video_sdl2.cpp @@ -0,0 +1,2869 @@ +/* + * video_sdl2.cpp - Video/graphics emulation, SDL 2.x specific stuff + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * NOTES: + * The Ctrl key works like a qualifier for special actions: + * Ctrl-Tab = suspend DGA mode (TODO) + * Ctrl-Esc = emergency quit + * Ctrl-F1 = mount floppy + * Ctrl-F5 = grab mouse (in windowed mode) + * + * FIXMEs and TODOs: + * - Windows requires an extra mouse event to update the actual cursor image? + * - Ctr-Tab for suspend/resume but how? SDL does not support that for non-Linux + * - Ctrl-Fn doesn't generate SDL_KEYDOWN events (SDL bug?) + * - Mouse acceleration, there is no API in SDL yet for that + * - Gamma tables support is likely to be broken here + * - Events processing is bound to the general emulation thread as SDL requires + * to PumpEvents() within the same thread as the one that called SetVideoMode(). + * Besides, there can't seem to be a way to call SetVideoMode() from a child thread. + * - Backport hw cursor acceleration to Basilisk II? + * - Factor out code + */ + +#include "sysdeps.h" + +#include +#if SDL_VERSION_ATLEAST(2,0,0) + +#include +#include +#include +#include +#include + +#ifdef __MACOSX__ +#include "utils_macosx.h" +#endif + +#ifdef WIN32 +#include /* alloca() */ +#endif + +#include +#include "main.h" +#include "adb.h" +#include "macos_util.h" +#include "prefs.h" +#include "user_strings.h" +#include "video.h" +#include "video_defs.h" +#include "video_blit.h" +#include "vm_alloc.h" + +#define DEBUG 0 +#include "debug.h" + +#define CODE_INVALID -1 +#define CODE_HOTKEY -2 + +// Supported video modes +using std::vector; +static vector VideoModes; + +// Display types +#ifdef SHEEPSHAVER +enum { + DISPLAY_WINDOW = DIS_WINDOW, // windowed display + DISPLAY_SCREEN = DIS_SCREEN // fullscreen display +}; +extern int display_type; // See enum above +#else +enum { + DISPLAY_WINDOW, // windowed display + DISPLAY_SCREEN // fullscreen display +}; +static int display_type = DISPLAY_WINDOW; // See enum above +#endif + +// Constants +#if defined(__MACOSX__) || defined(WIN32) +const char KEYCODE_FILE_NAME[] = "keycodes"; +const char KEYCODE_FILE_NAME2[] = "BasiliskII_keycodes"; +#else +const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; +const char KEYCODE_FILE_NAME2[] = DATADIR "/BasiliskII_keycodes"; +#endif + + +// Global variables +static uint32 frame_skip; // Prefs items +static int16 mouse_wheel_mode; +static int16 mouse_wheel_lines; +static bool mouse_wheel_reverse; + +static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) +static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) +static uint32 the_buffer_size; // Size of allocated the_buffer + +static bool redraw_thread_active = false; // Flag: Redraw thread installed +#ifndef USE_CPU_EMUL_SERVICES +static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread +static SDL_Thread *redraw_thread = NULL; // Redraw thread +static volatile bool thread_stop_req = false; +static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req +#endif + +#ifdef ENABLE_VOSF +static bool use_vosf = false; // Flag: VOSF enabled +#else +static const bool use_vosf = false; // VOSF not possible +#endif + +static bool ctrl_down = false; // Flag: Ctrl key pressed +static bool opt_down = false; // Flag: Opt key pressed +static bool cmd_down = false; // Flag: Cmd key pressed +static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread +static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread +static bool emul_suspended = false; // Flag: Emulator suspended + +static bool classic_mode = false; // Flag: Classic Mac video mode + +static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms +static int keycode_table[256]; // X keycode -> Mac keycode translation table + +// SDL variables +SDL_Window * sdl_window = NULL; // Wraps an OS-native window +static SDL_Surface * host_surface = NULL; // Surface in host-OS display format +static SDL_Surface * guest_surface = NULL; // Surface in guest-OS display format +static SDL_Renderer * sdl_renderer = NULL; // Handle to SDL2 renderer +static SDL_threadID sdl_renderer_thread_id = 0; // Thread ID where the SDL_renderer was created, and SDL_renderer ops should run (for compatibility w/ d3d9) +static SDL_Texture * sdl_texture = NULL; // Handle to a GPU texture, with which to draw guest_surface to +static SDL_Rect sdl_update_video_rect = {0,0,0,0}; // Union of all rects to update, when updating sdl_texture +static SDL_mutex * sdl_update_video_mutex = NULL; // Mutex to protect sdl_update_video_rect +static int screen_depth; // Depth of current screen +static SDL_Cursor *sdl_cursor = NULL; // Copy of Mac cursor +static SDL_Palette *sdl_palette = NULL; // Color palette to be used as CLUT and gamma table +static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors +static bool toggle_fullscreen = false; +static bool did_add_event_watch = false; + +static bool mouse_grabbed = false; + +// Mutex to protect SDL events +static SDL_mutex *sdl_events_lock = NULL; +#define LOCK_EVENTS SDL_LockMutex(sdl_events_lock) +#define UNLOCK_EVENTS SDL_UnlockMutex(sdl_events_lock) + +// Mutex to protect palette +static SDL_mutex *sdl_palette_lock = NULL; +#define LOCK_PALETTE SDL_LockMutex(sdl_palette_lock) +#define UNLOCK_PALETTE SDL_UnlockMutex(sdl_palette_lock) + +// Mutex to protect frame buffer +static SDL_mutex *frame_buffer_lock = NULL; +#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock) +#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock) + +// Initially set gamma tables +static uint16 init_gamma_red[256]; +static uint16 init_gamma_green[256]; +static uint16 init_gamma_blue[256]; +static bool init_gamma_valid; + +// Previously set gamma tables +static uint16 last_gamma_red[256]; +static uint16 last_gamma_green[256]; +static uint16 last_gamma_blue[256]; + +// Video refresh function +static void VideoRefreshInit(void); +static void (*video_refresh)(void); + + +// Prototypes +static int redraw_func(void *arg); +static int present_sdl_video(); +static int SDLCALL on_sdl_event_generated(void *userdata, SDL_Event * event); +static bool is_fullscreen(SDL_Window *); + +// From sys_unix.cpp +extern void SysMountFirstFloppy(void); + + +/* + * SDL surface locking glue + */ + +#ifdef ENABLE_VOSF +#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ + if (sdl_window && SDL_GetWindowFlags(sdl_window) & (SDL_WINDOW_FULLSCREEN)) \ + the_host_buffer = (uint8 *)(SURFACE)->pixels; \ +} while (0) +#else +#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) +#endif + +#define SDL_VIDEO_LOCK_SURFACE(SURFACE) do { \ + if (SDL_MUSTLOCK(SURFACE)) { \ + SDL_LockSurface(SURFACE); \ + SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE); \ + } \ +} while (0) + +#define SDL_VIDEO_UNLOCK_SURFACE(SURFACE) do { \ + if (SDL_MUSTLOCK(SURFACE)) \ + SDL_UnlockSurface(SURFACE); \ +} while (0) + + +/* + * Framebuffer allocation routines + */ + +static void *vm_acquire_framebuffer(uint32 size) +{ +#ifdef HAVE_MACH_VM + return vm_acquire_reserved(size); +#else + // always try to reallocate framebuffer at the same address + static void *fb = VM_MAP_FAILED; + if (fb != VM_MAP_FAILED) { + if (vm_acquire_fixed(fb, size) < 0) { +#ifndef SHEEPSHAVER + printf("FATAL: Could not reallocate framebuffer at previous address\n"); +#endif + fb = VM_MAP_FAILED; + } + } + if (fb == VM_MAP_FAILED) + fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); + return fb; +#endif +} + +static inline void vm_release_framebuffer(void *fb, uint32 size) +{ +#ifndef HAVE_MACH_VM + vm_release(fb, size); +#endif +} + +static inline int get_customized_color_depth(int default_depth) +{ + int display_color_depth = PrefsFindInt32("displaycolordepth"); + + D(bug("Get displaycolordepth %d\n", display_color_depth)); + + if(0 == display_color_depth) + return default_depth; + else{ + switch (display_color_depth) { + case 8: + return VIDEO_DEPTH_8BIT; + case 15: case 16: + return VIDEO_DEPTH_16BIT; + case 24: case 32: + return VIDEO_DEPTH_32BIT; + default: + return default_depth; + } + } +} + +/* + * Windows message handler + */ + +#ifdef WIN32 +#include +static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL + +extern void SysMediaArrived(void); +extern void SysMediaRemoved(void); +extern HWND GetMainWindowHandle(void); + +static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_DEVICECHANGE: + if (wParam == DBT_DEVICEREMOVECOMPLETE) { + DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; + if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) + SysMediaRemoved(); + } + else if (wParam == DBT_DEVICEARRIVAL) { + DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; + if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) + SysMediaArrived(); + } + return 0; + + default: + if (sdl_window_proc) + return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} +#endif + + +/* + * SheepShaver glue + */ + +#ifdef SHEEPSHAVER +// Color depth modes type +typedef int video_depth; + +// 1, 2, 4 and 8 bit depths use a color palette +static inline bool IsDirectMode(VIDEO_MODE const & mode) +{ + return IsDirectMode(mode.viAppleMode); +} + +// Abstract base class representing one (possibly virtual) monitor +// ("monitor" = rectangular display with a contiguous frame buffer) +class monitor_desc { +public: + monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) {} + virtual ~monitor_desc() {} + + // Get current Mac frame buffer base address + uint32 get_mac_frame_base(void) const {return screen_base;} + + // Set Mac frame buffer base address (called from switch_to_mode()) + void set_mac_frame_base(uint32 base) {screen_base = base;} + + // Get current video mode + const VIDEO_MODE &get_current_mode(void) const {return VModes[cur_mode];} + + // Called by the video driver to switch the video mode on this display + // (must call set_mac_frame_base()) + virtual void switch_to_current_mode(void) = 0; + + // Called by the video driver to set the color palette (in indexed modes) + virtual void set_palette(uint8 *pal, int num) = 0; + + // Called by the video driver to set the gamma table + virtual void set_gamma(uint8 *gamma, int num) = 0; +}; + +// Vector of pointers to available monitor descriptions, filled by VideoInit() +static vector VideoMonitors; + +// Find Apple mode matching best specified dimensions +static int find_apple_resolution(int xsize, int ysize) +{ + if (xsize == 640 && ysize == 480) + return APPLE_640x480; + if (xsize == 800 && ysize == 600) + return APPLE_800x600; + if (xsize == 1024 && ysize == 768) + return APPLE_1024x768; + if (xsize == 1152 && ysize == 768) + return APPLE_1152x768; + if (xsize == 1152 && ysize == 900) + return APPLE_1152x900; + if (xsize == 1280 && ysize == 1024) + return APPLE_1280x1024; + if (xsize == 1600 && ysize == 1200) + return APPLE_1600x1200; + return APPLE_CUSTOM; +} + +// Display error alert +static void ErrorAlert(int error) +{ + ErrorAlert(GetString(error)); +} +#endif + + +/* + * monitor_desc subclass for SDL display + */ + +class SDL_monitor_desc : public monitor_desc { +public: + SDL_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} + ~SDL_monitor_desc() {} + + virtual void switch_to_current_mode(void); + virtual void set_palette(uint8 *pal, int num); + virtual void set_gamma(uint8 *gamma, int num); + + bool video_open(void); + void video_close(void); +}; + + +/* + * Utility functions + */ + +// Find palette size for given color depth +static int palette_size(int mode) +{ + switch (mode) { + case VIDEO_DEPTH_1BIT: return 2; + case VIDEO_DEPTH_2BIT: return 4; + case VIDEO_DEPTH_4BIT: return 16; + case VIDEO_DEPTH_8BIT: return 256; + case VIDEO_DEPTH_16BIT: return 32; + case VIDEO_DEPTH_32BIT: return 256; + default: return 0; + } +} + +// Map video_mode depth ID to numerical depth value +static int mac_depth_of_video_depth(int video_depth) +{ + int depth = -1; + switch (video_depth) { + case VIDEO_DEPTH_1BIT: + depth = 1; + break; + case VIDEO_DEPTH_2BIT: + depth = 2; + break; + case VIDEO_DEPTH_4BIT: + depth = 4; + break; + case VIDEO_DEPTH_8BIT: + depth = 8; + break; + case VIDEO_DEPTH_16BIT: + depth = 16; + break; + case VIDEO_DEPTH_32BIT: + depth = 32; + break; + default: + abort(); + } + return depth; +} + +// Map video_mode depth ID to SDL screen depth +static int sdl_depth_of_video_depth(int video_depth) +{ + return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth); +} + +// Get screen dimensions +static void sdl_display_dimensions(int &width, int &height) +{ + SDL_DisplayMode desktop_mode; + const int display_index = 0; // TODO: try supporting multiple displays + if (SDL_GetDesktopDisplayMode(display_index, &desktop_mode) != 0) { + // TODO: report a warning, here? + width = height = 0; + return; + } + width = desktop_mode.w; + height = desktop_mode.h; +} + +static inline int sdl_display_width(void) +{ + int width, height; + sdl_display_dimensions(width, height); + return width; +} + +static inline int sdl_display_height(void) +{ + int width, height; + sdl_display_dimensions(width, height); + return height; +} + +// Check whether specified mode is available +static bool has_mode(int type, int width, int height, int depth) +{ + // Filter out out-of-bounds resolutions + if (width > sdl_display_width() || height > sdl_display_height()) + return false; + + // Whatever size it is, beyond what we've checked, we'll scale to/from as appropriate. + return true; +} + +// Add mode to list of supported modes +static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) +{ + // Filter out unsupported modes + if (!has_mode(type, width, height, depth)) + return; + + // Fill in VideoMode entry + VIDEO_MODE mode; +#ifdef SHEEPSHAVER + resolution_id = find_apple_resolution(width, height); + mode.viType = type; +#endif + VIDEO_MODE_X = width; + VIDEO_MODE_Y = height; + VIDEO_MODE_RESOLUTION = resolution_id; + VIDEO_MODE_ROW_BYTES = bytes_per_row; + VIDEO_MODE_DEPTH = (video_depth)depth; + VideoModes.push_back(mode); +} + +// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) +static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order) +{ +#if !REAL_ADDRESSING && !DIRECT_ADDRESSING + int layout = FLAYOUT_DIRECT; + if (depth == VIDEO_DEPTH_16BIT) + layout = (screen_depth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; + else if (depth == VIDEO_DEPTH_32BIT) + layout = (screen_depth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; + if (native_byte_order) + MacFrameLayout = layout; + else + MacFrameLayout = FLAYOUT_DIRECT; + monitor.set_mac_frame_base(MacFrameBaseMac); + + // Set variables used by UAE memory banking + const VIDEO_MODE &mode = monitor.get_current_mode(); + MacFrameBaseHost = the_buffer; + MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; + InitFrameBufferMapping(); +#else + monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); +#endif + D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); +} + +// Set window name and class +static void set_window_name() { + if (!sdl_window) return; + const char *title = PrefsFindString("title"); + std::string s = title ? title : GetString(STR_WINDOW_TITLE); + if (mouse_grabbed) { + s += GetString(STR_WINDOW_TITLE_GRABBED0); + int hotkey = PrefsFindInt32("hotkey"); + if (!hotkey) hotkey = 1; + if (hotkey & 1) s += GetString(STR_WINDOW_TITLE_GRABBED1); + if (hotkey & 2) s += GetString(STR_WINDOW_TITLE_GRABBED2); + if (hotkey & 4) s += GetString(STR_WINDOW_TITLE_GRABBED3); + s += GetString(STR_WINDOW_TITLE_GRABBED4); + } + SDL_SetWindowTitle(sdl_window, s.c_str()); +} + +// Migrate preferences items (XXX to be handled in MigratePrefs()) +static void migrate_screen_prefs(void) +{ +#ifdef SHEEPSHAVER + // Look-up priorities are: "screen", "screenmodes", "windowmodes". + if (PrefsFindString("screen")) + return; + + uint32 window_modes = PrefsFindInt32("windowmodes"); + uint32 screen_modes = PrefsFindInt32("screenmodes"); + int width = 0, height = 0; + if (screen_modes) { + static const struct { + int id; + int width; + int height; + } + modes[] = { + { 1, 640, 480 }, + { 2, 800, 600 }, + { 4, 1024, 768 }, + { 64, 1152, 768 }, + { 8, 1152, 900 }, + { 16, 1280, 1024 }, + { 32, 1600, 1200 }, + { 0, } + }; + for (int i = 0; modes[i].id != 0; i++) { + if (screen_modes & modes[i].id) { + if (width < modes[i].width && height < modes[i].height) { + width = modes[i].width; + height = modes[i].height; + } + } + } + } else { + if (window_modes & 1) + width = 640, height = 480; + if (window_modes & 2) + width = 800, height = 600; + } + if (width && height) { + char str[32]; + sprintf(str, "%s/%d/%d", screen_modes ? "dga" : "win", width, height); + PrefsReplaceString("screen", str); + } +#endif +} + + +/* + * Display "driver" classes + */ + +class driver_base { +public: + driver_base(SDL_monitor_desc &m); + ~driver_base(); + + void init(); // One-time init + void set_video_mode(int flags); + void adapt_to_video_mode(); + + void update_palette(void); + void suspend(void) {} + void resume(void) {} + void toggle_mouse_grab(void); + void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } + + void disable_mouse_accel(void); + void restore_mouse_accel(void); + + void grab_mouse(void); + void ungrab_mouse(void); + +public: + SDL_monitor_desc &monitor; // Associated video monitor + const VIDEO_MODE &mode; // Video mode handled by the driver + + bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) + SDL_Surface *s; // The surface we draw into +}; + +#ifdef ENABLE_VOSF +static void update_display_window_vosf(driver_base *drv); +#endif +static void update_display_static(driver_base *drv); + +static driver_base *drv = NULL; // Pointer to currently used driver object + +#ifdef ENABLE_VOSF +# include "video_vosf.h" +#endif + +driver_base::driver_base(SDL_monitor_desc &m) + : monitor(m), mode(m.get_current_mode()), init_ok(false), s(NULL) +{ + the_buffer = NULL; + the_buffer_copy = NULL; +} + +static void delete_sdl_video_surfaces() +{ + if (sdl_texture) { + SDL_DestroyTexture(sdl_texture); + sdl_texture = NULL; + } + + if (host_surface) { + if (host_surface == guest_surface) { + guest_surface = NULL; + } + + SDL_FreeSurface(host_surface); + host_surface = NULL; + } + + if (guest_surface) { + SDL_FreeSurface(guest_surface); + guest_surface = NULL; + } +} + +static void delete_sdl_video_window() +{ + if (sdl_renderer) { + SDL_DestroyRenderer(sdl_renderer); + sdl_renderer = NULL; + } + + if (sdl_window) { + SDL_DestroyWindow(sdl_window); + sdl_window = NULL; + } +} + +static void shutdown_sdl_video() +{ + delete_sdl_video_surfaces(); + delete_sdl_video_window(); +} + +static int get_mag_rate() +{ + int m = PrefsFindInt32("mag_rate"); + return m < 1 ? 1 : m > 4 ? 4 : m; +} + +static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags) +{ + if (guest_surface) { + delete_sdl_video_surfaces(); + } + + int window_width = width; + int window_height = height; + Uint32 window_flags = SDL_WINDOW_ALLOW_HIGHDPI; + const int window_flags_to_monitor = SDL_WINDOW_FULLSCREEN; + + if (flags & SDL_WINDOW_FULLSCREEN) { + SDL_DisplayMode desktop_mode; + if (SDL_GetDesktopDisplayMode(0, &desktop_mode) != 0) { + shutdown_sdl_video(); + return NULL; + } +#ifdef __MACOSX__ + window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + window_width = desktop_mode.w; + window_height = desktop_mode.h; +#else + window_flags |= SDL_WINDOW_FULLSCREEN; +#endif + } + + if (sdl_window) { + int old_window_width, old_window_height, old_window_flags; + SDL_GetWindowSize(sdl_window, &old_window_width, &old_window_height); + old_window_flags = SDL_GetWindowFlags(sdl_window); + if (old_window_width != window_width || + old_window_height != window_height || + (old_window_flags & window_flags_to_monitor) != (window_flags & window_flags_to_monitor)) + { + delete_sdl_video_window(); + } + } + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, PrefsFindBool("scale_nearest") ? "nearest" : "linear"); + +#if defined(__MACOSX__) && SDL_VERSION_ATLEAST(2,0,14) + if (MetalIsAvailable()) window_flags |= SDL_WINDOW_METAL; +#endif + + if (!sdl_window) { + int m = get_mag_rate(); + sdl_window = SDL_CreateWindow( + "", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + m * window_width, + m * window_height, + window_flags); + if (!sdl_window) { + shutdown_sdl_video(); + return NULL; + } + set_window_name(); + } + if (flags & SDL_WINDOW_FULLSCREEN) SDL_SetWindowGrab(sdl_window, SDL_TRUE); + + // Some SDL events (regarding some native-window events), need processing + // as they are generated. SDL2 has a facility, SDL_AddEventWatch(), which + // allows events to be processed as they are generated. + if (!did_add_event_watch) { + SDL_AddEventWatch(&on_sdl_event_generated, NULL); + did_add_event_watch = true; + } + + if (!sdl_renderer) { + const char *render_driver = PrefsFindString("sdlrender"); + if (render_driver) { + SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver); + } + else { +#ifdef WIN32 + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); +#elif defined(__MACOSX__) && SDL_VERSION_ATLEAST(2,0,14) + SDL_SetHint(SDL_HINT_RENDER_DRIVER, window_flags & SDL_WINDOW_METAL ? "metal" : "opengl"); +#else + SDL_SetHint(SDL_HINT_RENDER_DRIVER, ""); +#endif + } + + bool sdl_vsync = PrefsFindBool("sdl_vsync"); + if (sdl_vsync) { + SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); + } + + sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0); + + if (!sdl_renderer) { + shutdown_sdl_video(); + return NULL; + } + sdl_renderer_thread_id = SDL_ThreadID(); + + SDL_RendererInfo info; + memset(&info, 0, sizeof(info)); + SDL_GetRendererInfo(sdl_renderer, &info); + printf("Using SDL_Renderer driver: %s\n", (info.name ? info.name : "(null)")); + } + + if (!sdl_update_video_mutex) { + sdl_update_video_mutex = SDL_CreateMutex(); + } + + SDL_assert(sdl_texture == NULL); + sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); + if (!sdl_texture) { + shutdown_sdl_video(); + return NULL; + } + sdl_update_video_rect.x = 0; + sdl_update_video_rect.y = 0; + sdl_update_video_rect.w = 0; + sdl_update_video_rect.h = 0; + + SDL_assert(guest_surface == NULL); + SDL_assert(host_surface == NULL); + switch (bpp) { + case 8: + guest_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0); + break; + case 16: + guest_surface = SDL_CreateRGBSurface(0, width, height, 16, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000); + break; + case 32: + guest_surface = SDL_CreateRGBSurface(0, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + host_surface = guest_surface; + break; + default: + printf("WARNING: An unsupported bpp of %d was used\n", bpp); + break; + } + if (!guest_surface) { + shutdown_sdl_video(); + return NULL; + } + + if (!host_surface) { + Uint32 texture_format; + if (SDL_QueryTexture(sdl_texture, &texture_format, NULL, NULL, NULL) != 0) { + printf("ERROR: Unable to get the SDL texture's pixel format: %s\n", SDL_GetError()); + shutdown_sdl_video(); + return NULL; + } + + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + if (!SDL_PixelFormatEnumToMasks(texture_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + printf("ERROR: Unable to determine format for host SDL_surface: %s\n", SDL_GetError()); + shutdown_sdl_video(); + return NULL; + } + + host_surface = SDL_CreateRGBSurface(0, width, height, bpp, Rmask, Gmask, Bmask, Amask); + if (!host_surface) { + printf("ERROR: Unable to create host SDL_surface: %s\n", SDL_GetError()); + shutdown_sdl_video(); + return NULL; + } + } + + if (SDL_RenderSetLogicalSize(sdl_renderer, width, height) != 0) { + printf("ERROR: Unable to set SDL rendeer's logical size (to %dx%d): %s\n", + width, height, SDL_GetError()); + shutdown_sdl_video(); + return NULL; + } + + SDL_RenderSetIntegerScale(sdl_renderer, PrefsFindBool("scale_integer") ? SDL_TRUE : SDL_FALSE); + + return guest_surface; +} + +static int present_sdl_video() +{ + if (SDL_RectEmpty(&sdl_update_video_rect)) return 0; + + if (!sdl_renderer || !sdl_texture || !guest_surface) { + printf("WARNING: A video mode does not appear to have been set.\n"); + return -1; + } + + // Some systems, such as D3D9, can fail if and when they are used across + // certain operations. To address this, only utilize SDL_Renderer in a + // single thread, preferably the main thread. + // + // This was added as part of a fix for https://github.com/DavidLudwig/macemu/issues/21 + // "BasiliskII, Win32: resizing a window does not stretch " + SDL_assert(SDL_ThreadID() == sdl_renderer_thread_id); + + // Make sure the display's internal (to SDL, possibly the OS) buffer gets + // cleared. Not doing so can, if and when letterboxing is applied (whereby + // colored bars are drawn on the screen's sides to help with aspect-ratio + // correction), the colored bars can be an unknown color. + SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, 0); // Use black + SDL_RenderClear(sdl_renderer); // Clear the display + + // We're about to work with sdl_update_video_rect, so stop other threads from + // modifying it! + LOCK_PALETTE; + SDL_LockMutex(sdl_update_video_mutex); + // Convert from the guest OS' pixel format, to the host OS' texture, if necessary. + if (host_surface != guest_surface && + host_surface != NULL && + guest_surface != NULL) + { + SDL_Rect destRect = sdl_update_video_rect; + int result = SDL_BlitSurface(guest_surface, &sdl_update_video_rect, host_surface, &destRect); + if (result != 0) { + SDL_UnlockMutex(sdl_update_video_mutex); + UNLOCK_PALETTE; + return -1; + } + } + UNLOCK_PALETTE; // passed potential deadlock, can unlock palette + + // Update the host OS' texture + void * srcPixels = (void *)((uint8_t *)host_surface->pixels + + sdl_update_video_rect.y * host_surface->pitch + + sdl_update_video_rect.x * host_surface->format->BytesPerPixel); + + if (SDL_UpdateTexture(sdl_texture, &sdl_update_video_rect, srcPixels, host_surface->pitch) != 0) { + SDL_UnlockMutex(sdl_update_video_mutex); + return -1; + } + + // We are done working with pixels in host_surface. Reset sdl_update_video_rect, then let + // other threads modify it, as-needed. + sdl_update_video_rect.x = 0; + sdl_update_video_rect.y = 0; + sdl_update_video_rect.w = 0; + sdl_update_video_rect.h = 0; + SDL_UnlockMutex(sdl_update_video_mutex); + + // Copy the texture to the display + if (SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL) != 0) { + return -1; + } + + // Update the display + SDL_RenderPresent(sdl_renderer); + + // Indicate success to the caller! + return 0; +} + +void update_sdl_video(SDL_Surface *s, int numrects, SDL_Rect *rects) +{ + // TODO: make sure SDL_Renderer resources get displayed, if and when + // MacsBug is running (and VideoInterrupt() might not get called) + + SDL_LockMutex(sdl_update_video_mutex); + for (int i = 0; i < numrects; ++i) { + SDL_UnionRect(&sdl_update_video_rect, &rects[i], &sdl_update_video_rect); + } + SDL_UnlockMutex(sdl_update_video_mutex); +} + +void update_sdl_video(SDL_Surface *s, Sint32 x, Sint32 y, Sint32 w, Sint32 h) +{ + SDL_Rect temp = {x, y, w, h}; + update_sdl_video(s, 1, &temp); +} + +#ifdef SHEEPSHAVER +static void MagBits(Uint8 *dst, Uint8 *src, int mag) { + for (int y = 0; y < 16; y++) + for (int x = 0; x < 16; x++) { + int sa = 16 * y + x; + if (!(src[sa >> 3] & 0x80 >> (sa & 7))) continue; + for (int dy = 0; dy < mag; dy++) + for (int dx = 0; dx < mag; dx++) { + int da = 16 * mag * (mag * y + dy) + mag * x + dx; + dst[da >> 3] |= 0x80 >> (da & 7); + } + } +} +static SDL_Cursor *MagCursor(bool hot) { + int w, h; + SDL_GetWindowSize(sdl_window, &w, &h); + int mag = std::min(w / drv->VIDEO_MODE_X, h / drv->VIDEO_MODE_Y); + Uint8 *data = (Uint8 *)SDL_calloc(1, 32 * mag * mag); + Uint8 *mask = (Uint8 *)SDL_calloc(1, 32 * mag * mag); + MagBits(data, &MacCursor[4], mag); + MagBits(mask, &MacCursor[36], mag); + SDL_Cursor *cursor = SDL_CreateCursor(data, mask, 16 * mag, 16 * mag, hot ? MacCursor[2] * mag : 0, hot ? MacCursor[3] * mag : 0); + SDL_free(data); + SDL_free(mask); + return cursor; +} +#endif + +void driver_base::set_video_mode(int flags) +{ + int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); + if ((s = init_sdl_video(VIDEO_MODE_X, VIDEO_MODE_Y, depth, flags)) == NULL) + return; +#ifdef ENABLE_VOSF + the_host_buffer = (uint8 *)s->pixels; +#endif +} + +void driver_base::init() +{ + set_video_mode(display_type == DISPLAY_SCREEN ? SDL_WINDOW_FULLSCREEN : 0); + int aligned_height = (VIDEO_MODE_Y + 15) & ~15; + +#ifdef ENABLE_VOSF + use_vosf = true; + // Allocate memory for frame buffer (SIZE is extended to page-boundary) + the_buffer_size = page_extend((aligned_height + 2) * s->pitch); + the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); + the_buffer_copy = (uint8 *)malloc(the_buffer_size); + D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); + + // Check whether we can initialize the VOSF subsystem and it's profitable + if (!video_vosf_init(monitor)) { + WarningAlert(GetString(STR_VOSF_INIT_ERR)); + use_vosf = false; + } + else if (!video_vosf_profitable()) { + video_vosf_exit(); + printf("VOSF acceleration is not profitable on this platform, disabling it\n"); + use_vosf = false; + } + if (!use_vosf) { + free(the_buffer_copy); + vm_release(the_buffer, the_buffer_size); + the_host_buffer = NULL; + } +#endif + if (!use_vosf) { + // Allocate memory for frame buffer + the_buffer_size = (aligned_height + 2) * s->pitch; + the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); + the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); + D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); + } + + // Set frame buffer base + set_mac_frame_buffer(monitor, VIDEO_MODE_DEPTH, true); + + adapt_to_video_mode(); + + // set default B/W palette + sdl_palette = SDL_AllocPalette(256); + sdl_palette->colors[1] = (SDL_Color){ .r = 0, .g = 0, .b = 0, .a = 255 }; + SDL_SetSurfacePalette(s, sdl_palette); +} + +void driver_base::adapt_to_video_mode() { + ADBSetRelMouseMode(mouse_grabbed); + + // Init blitting routines + SDL_PixelFormat *f = s->format; + VisualFormat visualFormat; + visualFormat.depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); + visualFormat.Rmask = f->Rmask; + visualFormat.Gmask = f->Gmask; + visualFormat.Bmask = f->Bmask; + Screen_blitter_init(visualFormat, true, mac_depth_of_video_depth(VIDEO_MODE_DEPTH)); + + // Load gray ramp to 8->16/32 expand map + if (!IsDirectMode(mode)) + for (int i=0; i<256; i++) + ExpandMap[i] = SDL_MapRGB(f, i, i, i); + + + bool hardware_cursor = false; +#ifdef SHEEPSHAVER + hardware_cursor = video_can_change_cursor(); + if (hardware_cursor) { + // Create cursor + if ((sdl_cursor = MagCursor(false)) != NULL) { + SDL_SetCursor(sdl_cursor); + } + } + // Tell the video driver there's a change in cursor type + if (private_data) + private_data->cursorHardware = hardware_cursor; +#endif + SDL_LockMutex(sdl_update_video_mutex); + sdl_update_video_rect.x = 0; + sdl_update_video_rect.y = 0; + sdl_update_video_rect.w = VIDEO_MODE_X; + sdl_update_video_rect.h = VIDEO_MODE_Y; + SDL_UnlockMutex(sdl_update_video_mutex); + + // Hide cursor + SDL_ShowCursor(hardware_cursor); + + // Set window name/class + set_window_name(); + + // Everything went well + init_ok = true; +} + +driver_base::~driver_base() +{ + ungrab_mouse(); + restore_mouse_accel(); + + // HACK: Just delete instances of SDL_Surface and SDL_Texture, rather + // than also the SDL_Window and SDL_Renderer. This fixes a bug whereby + // OSX hosts, when in fullscreen, will, on a guest OS resolution change, + // do a series of switches (using OSX's "Spaces" feature) to and from + // the Basilisk II desktop, + delete_sdl_video_surfaces(); // This deletes instances of SDL_Surface and SDL_Texture + //shutdown_sdl_video(); // This deletes SDL_Window, SDL_Renderer, in addition to + // instances of SDL_Surface and SDL_Texture. + + // the_buffer shall always be mapped through vm_acquire_framebuffer() + if (the_buffer != VM_MAP_FAILED) { + D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); + vm_release_framebuffer(the_buffer, the_buffer_size); + the_buffer = NULL; + } + + // Free frame buffer(s) + if (!use_vosf) { + if (the_buffer_copy) { + free(the_buffer_copy); + the_buffer_copy = NULL; + } + } +#ifdef ENABLE_VOSF + else { + if (the_buffer_copy) { + D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); + free(the_buffer_copy); + the_buffer_copy = NULL; + } + + // Deinitialize VOSF + video_vosf_exit(); + } +#endif + + SDL_ShowCursor(1); +} + +// Palette has changed +void driver_base::update_palette(void) +{ + const VIDEO_MODE &mode = monitor.get_current_mode(); + + if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) { + SDL_SetSurfacePalette(s, sdl_palette); + SDL_LockMutex(sdl_update_video_mutex); + sdl_update_video_rect.x = 0; + sdl_update_video_rect.y = 0; + sdl_update_video_rect.w = VIDEO_MODE_X; + sdl_update_video_rect.h = VIDEO_MODE_Y; + SDL_UnlockMutex(sdl_update_video_mutex); + } +} + +// Disable mouse acceleration +void driver_base::disable_mouse_accel(void) +{ +} + +// Restore mouse acceleration to original value +void driver_base::restore_mouse_accel(void) +{ +} + +// Toggle mouse grab +void driver_base::toggle_mouse_grab(void) +{ + if (mouse_grabbed) + ungrab_mouse(); + else + grab_mouse(); +} + +static void update_mouse_grab() +{ + if (mouse_grabbed) { + SDL_SetRelativeMouseMode(SDL_TRUE); + } else { + SDL_SetRelativeMouseMode(SDL_FALSE); + } +} + +// Grab mouse, switch to relative mouse mode +void driver_base::grab_mouse(void) +{ + if (!mouse_grabbed) { + mouse_grabbed = true; + update_mouse_grab(); + set_window_name(); + disable_mouse_accel(); + ADBSetRelMouseMode(true); + } +} + +// Ungrab mouse, switch to absolute mouse mode +void driver_base::ungrab_mouse(void) +{ + if (mouse_grabbed) { + mouse_grabbed = false; + update_mouse_grab(); + set_window_name(); + restore_mouse_accel(); + ADBSetRelMouseMode(false); + } +} + +/* + * Initialization + */ + +// Init keycode translation table +static void keycode_init(void) +{ + bool use_kc = PrefsFindBool("keycodes"); + if (use_kc) { + + // Get keycode file path from preferences + const char *kc_path = PrefsFindString("keycodefile"); + + // Open keycode table + FILE *f = fopen(kc_path && *kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); + if (f == NULL) f = fopen(KEYCODE_FILE_NAME2, "r"); + if (f == NULL) { + char str[256]; + snprintf(str, sizeof(str), GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); + WarningAlert(str); + return; + } + + // Default translation table + for (int i=0; i<256; i++) + keycode_table[i] = CODE_INVALID; + + // Search for server vendor string, then read keycodes + const char * video_driver = SDL_GetCurrentVideoDriver(); + bool video_driver_found = false; + char line[256]; + int n_keys = 0; + while (fgets(line, sizeof(line) - 1, f)) { + // Read line + int len = strlen(line); + if (len == 0) + continue; + line[len-1] = 0; + + // Comments begin with "#" or ";" + if (line[0] == '#' || line[0] == ';' || line[0] == 0) + continue; + + if (video_driver_found) { + // Skip aliases as long as we have read keycodes yet + // Otherwise, it's another mapping and we have to stop + static const char sdl_str[] = "sdl"; + if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0 && n_keys == 0) + continue; + + // Read keycode + int x_code, mac_code; + if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) + keycode_table[x_code & 0xff] = mac_code, n_keys++; + else + break; + } else { + // Search for SDL video driver string + static const char sdl_str[] = "sdl"; + if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) { + char *p = line + sizeof(sdl_str); + if (video_driver && strstr(video_driver, p) == video_driver) + video_driver_found = true; + } + } + } + + // Keycode file completely read + fclose(f); + use_keycodes = video_driver_found; + + // Vendor not found? Then display warning + if (!video_driver_found) { + char str[256]; + snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver ? video_driver : "", kc_path ? kc_path : KEYCODE_FILE_NAME); + WarningAlert(str); + return; + } + + D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver ? video_driver : "", n_keys)); + } +} + +// Open display for current mode +bool SDL_monitor_desc::video_open(void) +{ + D(bug("video_open()\n")); +#if DEBUG + const VIDEO_MODE &mode = get_current_mode(); + D(bug("Current video mode:\n")); + D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f))); +#endif + + // Create display driver object of requested type + drv = new(std::nothrow) driver_base(*this); + if (drv == NULL) + return false; + drv->init(); + if (!drv->init_ok) { + delete drv; + drv = NULL; + return false; + } + +#ifdef WIN32 + // Chain in a new message handler for WM_DEVICECHANGE + HWND the_window = GetMainWindowHandle(); + sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); + SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); +#endif + + // Initialize VideoRefresh function + VideoRefreshInit(); + + // Lock down frame buffer + LOCK_FRAME_BUFFER; + + // Start redraw/input thread +#ifndef USE_CPU_EMUL_SERVICES + redraw_thread_cancel = false; + redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, "Redraw Thread", NULL)) != NULL); + if (!redraw_thread_active) { + printf("FATAL: cannot create redraw thread\n"); + return false; + } +#else + redraw_thread_active = true; +#endif + return true; +} + +#ifdef SHEEPSHAVER +bool VideoInit(void) +{ + const bool classic = false; +#else +bool VideoInit(bool classic) +{ +#endif + classic_mode = classic; + +#ifdef ENABLE_VOSF + // Zero the mainBuffer structure + mainBuffer.dirtyPages = NULL; + mainBuffer.pageInfo = NULL; +#endif + + // Create Mutexes + if ((sdl_events_lock = SDL_CreateMutex()) == NULL) + return false; + if ((sdl_palette_lock = SDL_CreateMutex()) == NULL) + return false; + if ((frame_buffer_lock = SDL_CreateMutex()) == NULL) + return false; + + // Init keycode translation + keycode_init(); + + // Read prefs + frame_skip = PrefsFindInt32("frameskip"); + mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); + mouse_wheel_lines = PrefsFindInt32("mousewheellines"); + mouse_wheel_reverse = mouse_wheel_lines < 0; + if (mouse_wheel_reverse) mouse_wheel_lines = -mouse_wheel_lines; + + // Get screen mode from preferences + migrate_screen_prefs(); + const char *mode_str = NULL; + if (classic_mode) + mode_str = "win/512/342"; + else + mode_str = PrefsFindString("screen"); + + // Determine display type and default dimensions + int default_width, default_height; + if (classic) { + default_width = 512; + default_height = 384; + } + else { + default_width = 640; + default_height = 480; + } + display_type = DISPLAY_WINDOW; + if (mode_str) { + if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) + display_type = DISPLAY_WINDOW; + else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) + display_type = DISPLAY_SCREEN; + } + if (default_width <= 0) + default_width = sdl_display_width(); + else if (default_width > sdl_display_width()) + default_width = sdl_display_width(); + if (default_height <= 0) + default_height = sdl_display_height(); + else if (default_height > sdl_display_height()) + default_height = sdl_display_height(); + + // Mac screen depth follows X depth + screen_depth = 32; + SDL_DisplayMode desktop_mode; + if (SDL_GetDesktopDisplayMode(0, &desktop_mode) == 0) { + screen_depth = SDL_BITSPERPIXEL(desktop_mode.format); + } + int default_depth; + switch (screen_depth) { + case 8: + default_depth = VIDEO_DEPTH_8BIT; + break; + case 15: case 16: + default_depth = VIDEO_DEPTH_16BIT; + break; + case 24: case 32: + default_depth = VIDEO_DEPTH_32BIT; + break; + default: + default_depth = VIDEO_DEPTH_1BIT; + break; + } + + // Initialize list of video modes to try + struct { + int w; + int h; + int resolution_id; + } +#ifdef SHEEPSHAVER + // Omit Classic resolutions + video_modes[] = { + { -1, -1, 0x80 }, + { 640, 480, 0x81 }, + { 800, 600, 0x82 }, + { 1024, 768, 0x83 }, + { 1152, 870, 0x84 }, + { 1280, 1024, 0x85 }, + { 1600, 1200, 0x86 }, + { 0, } + }; +#else + video_modes[] = { + { -1, -1, 0x80 }, + { 512, 384, 0x80 }, + { 640, 480, 0x81 }, + { 800, 600, 0x82 }, + { 1024, 768, 0x83 }, + { 1152, 870, 0x84 }, + { 1280, 1024, 0x85 }, + { 1600, 1200, 0x86 }, + { 0, } + }; +#endif + video_modes[0].w = default_width; + video_modes[0].h = default_height; + + // Construct list of supported modes + if (display_type == DISPLAY_WINDOW) { + if (classic) + add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT); + else { + for (int i = 0; video_modes[i].w != 0; i++) { + const int w = video_modes[i].w; + const int h = video_modes[i].h; + if (i > 0 && (w >= default_width || h >= default_height)) + continue; + for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) + add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); + } + } + } else if (display_type == DISPLAY_SCREEN) { + for (int i = 0; video_modes[i].w != 0; i++) { + const int w = video_modes[i].w; + const int h = video_modes[i].h; + if (i > 0 && (w >= default_width || h >= default_height)) + continue; + for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) + add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); + } + } + + if (VideoModes.empty()) { + ErrorAlert(STR_NO_XVISUAL_ERR); + return false; + } + + // Find requested default mode with specified dimensions + uint32 default_id; + std::vector::const_iterator i, end = VideoModes.end(); + for (i = VideoModes.begin(); i != end; ++i) { + const VIDEO_MODE & mode = (*i); + if (VIDEO_MODE_X == default_width && VIDEO_MODE_Y == default_height && VIDEO_MODE_DEPTH == default_depth) { + default_id = VIDEO_MODE_RESOLUTION; +#ifdef SHEEPSHAVER + std::vector::const_iterator begin = VideoModes.begin(); + cur_mode = distance(begin, i); +#endif + break; + } + } + if (i == end) { // not found, use first available mode + const VIDEO_MODE & mode = VideoModes[0]; + default_depth = VIDEO_MODE_DEPTH; + default_id = VIDEO_MODE_RESOLUTION; +#ifdef SHEEPSHAVER + cur_mode = 0; +#endif + } + +#ifdef SHEEPSHAVER + for (int i = 0; i < VideoModes.size(); i++) + VModes[i] = VideoModes[i]; + VideoInfo *p = &VModes[VideoModes.size()]; + p->viType = DIS_INVALID; // End marker + p->viRowBytes = 0; + p->viXsize = p->viYsize = 0; + p->viAppleMode = 0; + p->viAppleID = 0; +#endif + +#if DEBUG + D(bug("Available video modes:\n")); + for (i = VideoModes.begin(); i != end; ++i) { + const VIDEO_MODE & mode = (*i); + int bits = 1 << VIDEO_MODE_DEPTH; + if (bits == 16) + bits = 15; + else if (bits == 32) + bits = 24; + D(bug(" %dx%d (ID %02x), %d colors\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << bits)); + } +#endif + + int color_depth = get_customized_color_depth(default_depth); + + D(bug("Return get_customized_color_depth %d\n", color_depth)); + + // Create SDL_monitor_desc for this (the only) display + SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)color_depth, default_id); + VideoMonitors.push_back(monitor); + + // Open display + return monitor->video_open(); +} + + +/* + * Deinitialization + */ + +// Close display +void SDL_monitor_desc::video_close(void) +{ + D(bug("video_close()\n")); + +#ifdef WIN32 + // Remove message handler for WM_DEVICECHANGE + HWND the_window = GetMainWindowHandle(); + SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); +#endif + + // Stop redraw thread +#ifndef USE_CPU_EMUL_SERVICES + if (redraw_thread_active) { + redraw_thread_cancel = true; + SDL_WaitThread(redraw_thread, NULL); + } +#endif + redraw_thread_active = false; + + // Unlock frame buffer + UNLOCK_FRAME_BUFFER; + D(bug(" frame buffer unlocked\n")); + + // Close display + delete drv; + drv = NULL; +} + +void VideoExit(void) +{ + // Close displays + vector::iterator i, end = VideoMonitors.end(); + for (i = VideoMonitors.begin(); i != end; ++i) + dynamic_cast(*i)->video_close(); + + // Destroy locks + if (frame_buffer_lock) + SDL_DestroyMutex(frame_buffer_lock); + if (sdl_palette_lock) + SDL_DestroyMutex(sdl_palette_lock); + if (sdl_events_lock) + SDL_DestroyMutex(sdl_events_lock); +} + + +/* + * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) + */ + +void VideoQuitFullScreen(void) +{ + D(bug("VideoQuitFullScreen()\n")); + quit_full_screen = true; +} + +static void ApplyGammaRamp() { + if (sdl_window) { + int result; + if (!init_gamma_valid) { + result = SDL_GetWindowGammaRamp(sdl_window, init_gamma_red, init_gamma_green, init_gamma_blue); + if (result < 0) + fprintf(stderr, "SDL_GetWindowGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); + init_gamma_valid = true; + } + const char *s = PrefsFindString("gammaramp"); + if (!s) s = "off"; + if (strcmp(s, "off") && (strcmp(s, "fullscreen") || display_type == DISPLAY_SCREEN)) + result = SDL_SetWindowGammaRamp(sdl_window, last_gamma_red, last_gamma_green, last_gamma_blue); + else + result = SDL_SetWindowGammaRamp(sdl_window, init_gamma_red, init_gamma_green, init_gamma_blue); + if (result < 0) + fprintf(stderr, "SDL_SetWindowGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); + } +} + +static void do_toggle_fullscreen(void) +{ +#ifndef USE_CPU_EMUL_SERVICES + // pause redraw thread + thread_stop_ack = false; + thread_stop_req = true; + while (!thread_stop_ack) ; +#endif + + // Apply fullscreen + if (sdl_window) { + if (display_type == DISPLAY_SCREEN) { + display_type = DISPLAY_WINDOW; + SDL_SetWindowFullscreen(sdl_window, 0); + const VIDEO_MODE &mode = drv->mode; + int m = get_mag_rate(); + SDL_SetWindowSize(sdl_window, m * VIDEO_MODE_X, m * VIDEO_MODE_Y); + SDL_SetWindowGrab(sdl_window, SDL_FALSE); + } else { + display_type = DISPLAY_SCREEN; +#ifdef __MACOSX__ + SDL_SetWindowFullscreen(sdl_window, SDL_WINDOW_FULLSCREEN_DESKTOP); +#else + SDL_SetWindowFullscreen(sdl_window, SDL_WINDOW_FULLSCREEN); +#endif + SDL_SetWindowGrab(sdl_window, SDL_TRUE); + } + } + + // switch modes + drv->adapt_to_video_mode(); + + // reset the palette +#ifdef SHEEPSHAVER + video_set_palette(); +#endif + ApplyGammaRamp(); + drv->update_palette(); + + // reset the video refresh handler + VideoRefreshInit(); + + // while SetVideoMode is happening, control key up may be missed + ADBKeyUp(0x36); + + // resume redraw thread + toggle_fullscreen = false; +#ifndef USE_CPU_EMUL_SERVICES + thread_stop_req = false; +#endif +} + +/* + * Mac VBL interrupt + */ + +/* + * Execute video VBL routine + */ + +static bool is_fullscreen(SDL_Window * window) +{ +#ifdef __MACOSX__ + // On OSX, SDL, at least as of 2.0.5 (and possibly beyond), does not always + // report changes to fullscreen via the SDL_WINDOW_FULLSCREEN flag. + // (Example: https://bugzilla.libsdl.org/show_bug.cgi?id=3766 , which + // involves fullscreen/windowed toggles via window-manager UI controls). + // Until it does, or adds a facility to do so, we'll use a platform-specific + // code path to detect fullscreen changes. + extern bool is_fullscreen_osx(SDL_Window * window); + return is_fullscreen_osx(sdl_window); +#else + if (!window) { + return false; + } + const Uint32 sdl_window_flags = SDL_GetWindowFlags(sdl_window); + return (sdl_window_flags & SDL_WINDOW_FULLSCREEN) != 0; +#endif +} + +#ifdef SHEEPSHAVER +void VideoVBL(void) +{ + // Emergency quit requested? Then quit + if (emerg_quit) + QuitEmulator(); + + if (toggle_fullscreen) + do_toggle_fullscreen(); + + present_sdl_video(); + + // Temporarily give up frame buffer lock (this is the point where + // we are suspended when the user presses Ctrl-Tab) + UNLOCK_FRAME_BUFFER; + LOCK_FRAME_BUFFER; + + // Execute video VBL + if (private_data != NULL && private_data->interruptsEnabled) + VSLDoInterruptService(private_data->vslServiceID); +} +#else +void VideoInterrupt(void) +{ + // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() + SDL_PumpEvents(); + + // Emergency quit requested? Then quit + if (emerg_quit) + QuitEmulator(); + + if (toggle_fullscreen) + do_toggle_fullscreen(); + + present_sdl_video(); + + // Temporarily give up frame buffer lock (this is the point where + // we are suspended when the user presses Ctrl-Tab) + UNLOCK_FRAME_BUFFER; + LOCK_FRAME_BUFFER; +} +#endif + + +/* + * Set palette + */ + +#ifdef SHEEPSHAVER +void video_set_palette(void) +{ + monitor_desc * monitor = VideoMonitors[0]; + int n_colors = palette_size(monitor->get_current_mode().viAppleMode); + uint8 pal[256 * 3]; + for (int c = 0; c < n_colors; c++) { + pal[c*3 + 0] = mac_pal[c].red; + pal[c*3 + 1] = mac_pal[c].green; + pal[c*3 + 2] = mac_pal[c].blue; + } + monitor->set_palette(pal, n_colors); +} + +void video_set_gamma(int n_colors) +{ + monitor_desc * monitor = VideoMonitors[0]; + uint8 gamma[256 * 3]; + for (int c = 0; c < n_colors; c++) { + gamma[c*3 + 0] = mac_gamma[c].red; + gamma[c*3 + 1] = mac_gamma[c].green; + gamma[c*3 + 2] = mac_gamma[c].blue; + } + monitor->set_gamma(gamma, n_colors); +} +#endif + +void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) +{ + + const VIDEO_MODE &mode = get_current_mode(); + + LOCK_PALETTE; + + // Convert colors to XColor array + int num_out = 256; + bool stretch = false; + + if (!sdl_palette) { + sdl_palette = SDL_AllocPalette(num_out); + } + + SDL_Color *p = sdl_palette->colors; + for (int i=0; ir = pal[c*3 + 0] * 0x0101; + p->g = pal[c*3 + 1] * 0x0101; + p->b = pal[c*3 + 2] * 0x0101; + p++; + } + + // Recalculate pixel color expansion map + if (!IsDirectMode(mode)) { + for (int i=0; i<256; i++) { + int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) + ExpandMap[i] = SDL_MapRGB(drv->s->format, pal[c*3+0], pal[c*3+1], pal[c*3+2]); + } + +#ifdef ENABLE_VOSF + if (use_vosf) { + // We have to redraw everything because the interpretation of pixel values changed + LOCK_VOSF; + PFLAG_SET_ALL; + UNLOCK_VOSF; + memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); + } +#endif + } + + // Tell redraw thread to change palette + sdl_palette_changed = true; + + UNLOCK_PALETTE; +} + +void SDL_monitor_desc::set_gamma(uint8 *gamma, int num_in) +{ + // handle the gamma ramp + + if (gamma[0] == 127 && gamma[num_in*3-1] == 127) // solid grey + return; // ignore + + uint16 red[256]; + uint16 green[256]; + uint16 blue[256]; + + int repeats = 256 / num_in; + + for (int i = 0; i < num_in; i++) { + for (int j = 0; j < repeats; j++) { + red[i*repeats + j] = gamma[i*3 + 0] << 8; + green[i*repeats + j] = gamma[i*3 + 1] << 8; + blue[i*repeats + j] = gamma[i*3 + 2] << 8; + } + } + + // fill remaining entries (if any) with last value + for (int i = num_in * repeats; i < 256; i++) { + red[i] = gamma[(num_in - 1) * 3] << 8; + green[i] = gamma[(num_in - 1) * 3 + 1] << 8; + blue[i] = gamma[(num_in - 1) * 3 + 2] << 8; + } + + bool changed = (memcmp(red, last_gamma_red, 512) != 0 || + memcmp(green, last_gamma_green, 512) != 0 || + memcmp(blue, last_gamma_blue, 512) != 0); + + if (changed) { + memcpy(last_gamma_red, red, 512); + memcpy(last_gamma_green, green, 512); + memcpy(last_gamma_blue, blue, 512); + ApplyGammaRamp(); + } + +} + + + +/* + * Switch video mode + */ + +#ifdef SHEEPSHAVER +int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) +{ + /* return if no mode change */ + if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && + (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; + + /* first find video mode in table */ + for (int i=0; VModes[i].viType != DIS_INVALID; i++) { + if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && + (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { + csSave->saveMode = ReadMacInt16(ParamPtr + csMode); + csSave->saveData = ReadMacInt32(ParamPtr + csData); + csSave->savePage = ReadMacInt16(ParamPtr + csPage); + + // Disable interrupts and pause redraw thread + DisableInterrupt(); + thread_stop_ack = false; + thread_stop_req = true; + while (!thread_stop_ack) ; + + cur_mode = i; + monitor_desc *monitor = VideoMonitors[0]; + monitor->switch_to_current_mode(); + + WriteMacInt32(ParamPtr + csBaseAddr, screen_base); + csSave->saveBaseAddr=screen_base; + csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ + csSave->saveMode=VModes[cur_mode].viAppleMode; + + // Enable interrupts and resume redraw thread + thread_stop_req = false; + EnableInterrupt(); + return noErr; + } + } + return paramErr; +} +#endif + +static bool is_cursor_in_mac_screen() { + + int windowX, windowY; + int cursorX, cursorY; + int deltaX, deltaY; + bool out; + + // TODO figure out a check for full screen mode + if (display_type == DISPLAY_SCREEN) + return true; + + if (display_type == DISPLAY_WINDOW) { + + if (sdl_window == NULL || SDL_GetMouseFocus() != sdl_window) + return false; + + SDL_GetWindowPosition(sdl_window, &windowX, &windowY); + SDL_GetGlobalMouseState(&cursorX, &cursorY); + deltaX = cursorX - windowX; + deltaY = cursorY - windowY; + D(bug("cursor relative {%d,%d}\n", deltaX, deltaY)); + const VIDEO_MODE &mode = drv->mode; + const int m = get_mag_rate(); + out = deltaX >= 0 && deltaX < VIDEO_MODE_X * m && + deltaY >= 0 && deltaY < VIDEO_MODE_Y * m; + D(bug("cursor in window? %s\n", out? "yes" : "no")); + return out; + } + + return false; +} + +void SDL_monitor_desc::switch_to_current_mode(void) +{ + // Close and reopen display + LOCK_EVENTS; + video_close(); + video_open(); + UNLOCK_EVENTS; + + if (drv == NULL) { + ErrorAlert(STR_OPEN_WINDOW_ERR); + QuitEmulator(); + } +} + + +/* + * Can we set the MacOS cursor image into the window? + */ + +#ifdef SHEEPSHAVER +bool video_can_change_cursor(void) +{ + return PrefsFindBool("hardcursor") && (display_type == DISPLAY_WINDOW || PrefsFindBool("scale_integer")); +} +#endif + + +/* + * Set cursor image for window + */ + +#ifdef SHEEPSHAVER +void video_set_cursor(void) +{ + // Set new cursor image if it was changed + if (sdl_cursor) { + SDL_FreeCursor(sdl_cursor); + sdl_cursor = MagCursor(true); + if (sdl_cursor) { + SDL_ShowCursor(private_data == NULL || private_data->cursorVisible); + SDL_SetCursor(sdl_cursor); + + // XXX Windows apparently needs an extra mouse event to + // make the new cursor image visible. + // On Mac, if mouse is grabbed, SDL_ShowCursor() recenters the + // mouse, we have to put it back. + bool move = false; +#ifdef WIN32 + move = true; +#elif defined(__APPLE__) + move = mouse_grabbed; +#endif + if (move) { + int visible = SDL_ShowCursor(-1); + if (visible) { + bool cursor_in_window = is_cursor_in_mac_screen(); + + if (cursor_in_window) { + int x, y; + SDL_GetMouseState(&x, &y); + D(bug("WarpMouse to {%d,%d} via video_set_cursor\n", x, y)); + SDL_WarpMouseInWindow(sdl_window, x, y); + } + } + } + } + } +} +#endif + + +/* + * Keyboard-related utilify functions + */ + +static bool is_hotkey_down(SDL_Keysym const & ks) +{ + int hotkey = PrefsFindInt32("hotkey"); + if (!hotkey) hotkey = 1; + return (ctrl_down || (ks.mod & KMOD_CTRL) || !(hotkey & 1)) && + (opt_down || (ks.mod & KMOD_ALT) || !(hotkey & 2)) && + (cmd_down || (ks.mod & KMOD_GUI) || !(hotkey & 4)); +} + +static int modify_opt_cmd(int code) { + static bool f, c; + if (!f) { + f = true; + c = PrefsFindBool("swap_opt_cmd"); + } + if (c) { + switch (code) { + case 0x37: return 0x3a; + case 0x3a: return 0x37; + } + } + return code; +} + +/* + * Translate key event to Mac keycode, returns CODE_INVALID if no keycode was found + * and CODE_HOTKEY if the key was recognized as a hotkey + */ + +static int kc_decode(SDL_Keysym const & ks, bool key_down) +{ + switch (ks.sym) { + case SDLK_a: return 0x00; + case SDLK_b: return 0x0b; + case SDLK_c: return 0x08; + case SDLK_d: return 0x02; + case SDLK_e: return 0x0e; + case SDLK_f: return 0x03; + case SDLK_g: return 0x05; + case SDLK_h: return 0x04; + case SDLK_i: return 0x22; + case SDLK_j: return 0x26; + case SDLK_k: return 0x28; + case SDLK_l: return 0x25; + case SDLK_m: return 0x2e; + case SDLK_n: return 0x2d; + case SDLK_o: return 0x1f; + case SDLK_p: return 0x23; + case SDLK_q: return 0x0c; + case SDLK_r: return 0x0f; + case SDLK_s: return 0x01; + case SDLK_t: return 0x11; + case SDLK_u: return 0x20; + case SDLK_v: return 0x09; + case SDLK_w: return 0x0d; + case SDLK_x: return 0x07; + case SDLK_y: return 0x10; + case SDLK_z: return 0x06; + + case SDLK_1: case SDLK_EXCLAIM: return 0x12; + case SDLK_2: case SDLK_AT: return 0x13; + case SDLK_3: case SDLK_HASH: return 0x14; + case SDLK_4: case SDLK_DOLLAR: return 0x15; + case SDLK_5: return 0x17; + case SDLK_6: return 0x16; + case SDLK_7: return 0x1a; + case SDLK_8: return 0x1c; + case SDLK_9: return 0x19; + case SDLK_0: return 0x1d; + + case SDLK_BACKQUOTE: case 167: return 0x32; + case SDLK_MINUS: case SDLK_UNDERSCORE: return 0x1b; + case SDLK_EQUALS: case SDLK_PLUS: return 0x18; + case SDLK_LEFTBRACKET: return 0x21; + case SDLK_RIGHTBRACKET: return 0x1e; + case SDLK_BACKSLASH: return 0x2a; + case SDLK_SEMICOLON: case SDLK_COLON: return 0x29; + case SDLK_QUOTE: case SDLK_QUOTEDBL: return 0x27; + case SDLK_COMMA: case SDLK_LESS: return 0x2b; + case SDLK_PERIOD: case SDLK_GREATER: return 0x2f; + case SDLK_SLASH: case SDLK_QUESTION: return 0x2c; + + case SDLK_TAB: if (is_hotkey_down(ks)) {if (!key_down) drv->suspend(); return CODE_HOTKEY;} else return 0x30; + case SDLK_RETURN: if (is_hotkey_down(ks)) {if (!key_down) toggle_fullscreen = true; return CODE_HOTKEY;} else return 0x24; + case SDLK_SPACE: return 0x31; + case SDLK_BACKSPACE: return 0x33; + + case SDLK_DELETE: return 0x75; + case SDLK_INSERT: return 0x72; + case SDLK_HOME: case SDLK_HELP: return 0x73; + case SDLK_END: return 0x77; + case SDLK_PAGEUP: return 0x74; + case SDLK_PAGEDOWN: return 0x79; + + case SDLK_LCTRL: return 0x36; + case SDLK_RCTRL: return 0x36; + case SDLK_LSHIFT: return 0x38; + case SDLK_RSHIFT: return 0x38; + case SDLK_LALT: case SDLK_RALT: return 0x3a; + case SDLK_LGUI: case SDLK_RGUI: return 0x37; + case SDLK_MENU: return 0x32; + case SDLK_CAPSLOCK: return 0x39; + case SDLK_NUMLOCKCLEAR: return 0x47; + + case SDLK_UP: return 0x3e; + case SDLK_DOWN: return 0x3d; + case SDLK_LEFT: return 0x3b; + case SDLK_RIGHT: return 0x3c; + + case SDLK_ESCAPE: if (is_hotkey_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return CODE_HOTKEY;} else return 0x35; + + case SDLK_F1: if (is_hotkey_down(ks)) {if (!key_down) SysMountFirstFloppy(); return CODE_HOTKEY;} else return 0x7a; + case SDLK_F2: return 0x78; + case SDLK_F3: return 0x63; + case SDLK_F4: return 0x76; + case SDLK_F5: return 0x60; + case SDLK_F6: return 0x61; + case SDLK_F7: return 0x62; + case SDLK_F8: return 0x64; + case SDLK_F9: return 0x65; + case SDLK_F10: return 0x6d; + case SDLK_F11: return 0x67; + case SDLK_F12: return 0x6f; + + case SDLK_PRINTSCREEN: return 0x69; + case SDLK_SCROLLLOCK: return 0x6b; + case SDLK_PAUSE: return 0x71; + + case SDLK_KP_0: return 0x52; + case SDLK_KP_1: return 0x53; + case SDLK_KP_2: return 0x54; + case SDLK_KP_3: return 0x55; + case SDLK_KP_4: return 0x56; + case SDLK_KP_5: return 0x57; + case SDLK_KP_6: return 0x58; + case SDLK_KP_7: return 0x59; + case SDLK_KP_8: return 0x5b; + case SDLK_KP_9: return 0x5c; + case SDLK_KP_PERIOD: return 0x41; + case SDLK_KP_PLUS: return 0x45; + case SDLK_KP_MINUS: return 0x4e; + case SDLK_KP_MULTIPLY: return 0x43; + case SDLK_KP_DIVIDE: return 0x4b; + case SDLK_KP_ENTER: return 0x4c; + case SDLK_KP_EQUALS: return 0x51; + } + D(bug("Unhandled SDL keysym: %d\n", ks.sym)); + return CODE_INVALID; +} + +static int event2keycode(SDL_KeyboardEvent const &ev, bool key_down) +{ + return kc_decode(ev.keysym, key_down); +} + +static void force_complete_window_refresh() +{ + if (display_type == DISPLAY_WINDOW) { +#ifdef ENABLE_VOSF + if (use_vosf) { // VOSF refresh + LOCK_VOSF; + PFLAG_SET_ALL; + UNLOCK_VOSF; + } +#endif + // Ensure each byte of the_buffer_copy differs from the_buffer to force a full update. + const VIDEO_MODE &mode = VideoMonitors[0]->get_current_mode(); + const int len = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; + for (int i = 0; i < len; i++) + the_buffer_copy[i] = !the_buffer[i]; + } +} + +/* + * SDL event handling + */ + +// possible return codes for SDL-registered event watches +enum { + EVENT_DROP_FROM_QUEUE = 0, + EVENT_ADD_TO_QUEUE = 1 +}; + +// Some events need to be processed in the host-app's main thread, due to +// host-OS requirements. +// +// This function is called by SDL, whenever it generates an SDL_Event. It has +// the ability to process events, and optionally, to prevent them from being +// added to SDL's event queue (and retrieve-able via SDL_PeepEvents(), etc.) +static int SDLCALL on_sdl_event_generated(void *userdata, SDL_Event * event) +{ + switch (event->type) { + case SDL_KEYUP: { + SDL_Keysym const & ks = event->key.keysym; + switch (ks.sym) { + case SDLK_F5: { + if (is_hotkey_down(ks) && !PrefsFindBool("hardcursor")) { + drv->toggle_mouse_grab(); + return EVENT_DROP_FROM_QUEUE; + } + } break; + } + } break; + + case SDL_WINDOWEVENT: { + switch (event->window.event) { + case SDL_WINDOWEVENT_RESIZED: { + if (!redraw_thread_active) break; + // Handle changes of fullscreen. This is done here, in + // on_sdl_event_generated() and not the main SDL_Event-processing + // loop, in order to perform this change on the main thread. + // (Some os'es UI APIs, such as OSX's NSWindow, are not + // thread-safe.) + const bool is_full = is_fullscreen(sdl_window); + const bool adjust_fullscreen = \ + (display_type == DISPLAY_WINDOW && is_full) || + (display_type == DISPLAY_SCREEN && !is_full); + if (adjust_fullscreen) { + do_toggle_fullscreen(); + +#if __MACOSX__ + // HACK-FIX: on OSX hosts, make sure that the OSX menu + // bar does not show up in fullscreen mode, when the + // cursor is near the top of the screen, lest the + // guest OS' menu bar be obscured. + if (is_full) { + extern void set_menu_bar_visible_osx(bool); + set_menu_bar_visible_osx(false); + } +#endif + } + } break; + } + } break; + } + + return EVENT_ADD_TO_QUEUE; +} + + +static void handle_events(void) +{ + SDL_Event events[10]; + const int n_max_events = sizeof(events) / sizeof(events[0]); + int n_events; + + while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) > 0) { + for (int i = 0; i < n_events; i++) { + SDL_Event & event = events[i]; + + switch (event.type) { + + // Mouse button + case SDL_MOUSEBUTTONDOWN: { + unsigned int button = event.button.button; + if (button == SDL_BUTTON_LEFT) + ADBMouseDown(0); + else if (button == SDL_BUTTON_RIGHT) + ADBMouseDown(1); + else if (button == SDL_BUTTON_MIDDLE) + ADBMouseDown(2); + break; + } + case SDL_MOUSEBUTTONUP: { + unsigned int button = event.button.button; + if (button == SDL_BUTTON_LEFT) + ADBMouseUp(0); + else if (button == SDL_BUTTON_RIGHT) + ADBMouseUp(1); + else if (button == SDL_BUTTON_MIDDLE) + ADBMouseUp(2); + break; + } + + // Mouse moved + case SDL_MOUSEMOTION: + if (mouse_grabbed) { + drv->mouse_moved(event.motion.xrel, event.motion.yrel); + } else { + drv->mouse_moved(event.motion.x, event.motion.y); + } + break; + + case SDL_MOUSEWHEEL: + if (!event.wheel.y) break; + if (!mouse_wheel_mode) { + int key = (event.wheel.y < 0) ^ mouse_wheel_reverse ? 0x79 : 0x74; // Page up/down + ADBKeyDown(key); + ADBKeyUp(key); + } + else { + int key = (event.wheel.y < 0) ^ mouse_wheel_reverse ? 0x3d : 0x3e; // Cursor up/down + for (int i = 0; i < mouse_wheel_lines; i++) { + ADBKeyDown(key); + ADBKeyUp(key); + } + } + break; + + // Keyboard + case SDL_KEYDOWN: { + if (event.key.repeat) + break; + int code = CODE_INVALID; + if (use_keycodes && event2keycode(event.key, true) != CODE_HOTKEY) + code = keycode_table[event.key.keysym.scancode & 0xff]; + if (code == CODE_INVALID) + code = event2keycode(event.key, true); + if (code >= 0) { + if (!emul_suspended) { + code = modify_opt_cmd(code); +#ifdef __MACOSX__ + ADBKeyDown(code); +#else + if (code == 0x39) + (SDL_GetModState() & KMOD_CAPS ? ADBKeyDown : ADBKeyUp)(code); + else + ADBKeyDown(code); +#endif + if (code == 0x36) + ctrl_down = true; + if (code == 0x3a) + opt_down = true; + if (code == 0x37) + cmd_down = true; + + } else { + if (code == 0x31) + drv->resume(); // Space wakes us up + } + } + break; + } + case SDL_KEYUP: { + int code = CODE_INVALID; + if (use_keycodes && event2keycode(event.key, false) != CODE_HOTKEY) + code = keycode_table[event.key.keysym.scancode & 0xff]; + if (code == CODE_INVALID) + code = event2keycode(event.key, false); + if (code >= 0) { + code = modify_opt_cmd(code); +#ifdef __MACOSX__ + ADBKeyUp(code); +#else + if (code != 0x39) + ADBKeyUp(code); +#endif + if (code == 0x36) + ctrl_down = false; + if (code == 0x3a) + opt_down = false; + if (code == 0x37) + cmd_down = false; + } + break; + } + + case SDL_WINDOWEVENT: { + switch (event.window.event) { + // Hidden parts exposed, force complete refresh of window + case SDL_WINDOWEVENT_EXPOSED: + force_complete_window_refresh(); + break; + + // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. + case SDL_WINDOWEVENT_RESTORED: + force_complete_window_refresh(); + break; + + } + break; + } + + // Window "close" widget clicked + case SDL_QUIT: + if (SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) break; + ADBKeyDown(0x7f); // Power key + ADBKeyUp(0x7f); + break; + } + } + } +} + + +/* + * Window display update + */ + +// Static display update (fixed frame rate, but incremental) +static void update_display_static(driver_base *drv) +{ + // Incremental update code + int wide = 0, high = 0; + uint32 x1, x2, y1, y2; + const VIDEO_MODE &mode = drv->mode; + int bytes_per_row = VIDEO_MODE_ROW_BYTES; + uint8 *p, *p2; + uint32 x2_clipped, wide_clipped; + + // Check for first line from top and first line from bottom that have changed + y1 = 0; + for (uint32 j = 0; j < VIDEO_MODE_Y; j++) { + if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { + y1 = j; + break; + } + } + y2 = y1 - 1; + for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) { + if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { + y2 = j; + break; + } + } + high = y2 - y1 + 1; + + // Check for first column from left and first column from right that have changed + if (high) { + if ((int)VIDEO_MODE_DEPTH < (int)VIDEO_DEPTH_8BIT) { + const int src_bytes_per_row = bytes_per_row; + const int dst_bytes_per_row = drv->s->pitch; + const int pixels_per_byte = 8/mac_depth_of_video_depth(VIDEO_MODE_DEPTH); + + const uint32 line_len = TrivialBytesPerRow(VIDEO_MODE_X, VIDEO_MODE_DEPTH); + + x1 = line_len; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + for (uint32 i = 0; i < x1; i++) { + if (*p != *p2) { + x1 = i; + break; + } + p++; p2++; + } + } + x2 = x1; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + p += bytes_per_row; + p2 += bytes_per_row; + for (uint32 i = line_len; i > x2; i--) { + p--; p2--; + if (*p != *p2) { + x2 = i; + break; + } + } + } + + x1 *= pixels_per_byte; + x2 *= pixels_per_byte; + wide = x2 - x1; + x2_clipped = x2 > VIDEO_MODE_X? VIDEO_MODE_X : x2; + wide_clipped = x2_clipped - x1; + + // Update copy of the_buffer + if (high && wide) { + + // Lock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_LockSurface(drv->s); + + // Blit to screen surface + int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte); + int di = y1 * dst_bytes_per_row + x1; + for (uint32 j = y1; j <= y2; j++) { + memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte); + Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte); + si += src_bytes_per_row; + di += dst_bytes_per_row; + } + + // Unlock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_UnlockSurface(drv->s); + + // Refresh display + update_sdl_video(drv->s, x1, y1, wide_clipped, high); + } + + } else { + const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X; + const int dst_bytes_per_row = drv->s->pitch; + + x1 = VIDEO_MODE_X; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) { + if (*p != *p2) { + x1 = i / bytes_per_pixel; + break; + } + p++; p2++; + } + } + x2 = x1; + for (uint32 j = y1; j <= y2; j++) { + p = &the_buffer[j * bytes_per_row]; + p2 = &the_buffer_copy[j * bytes_per_row]; + p += bytes_per_row; + p2 += bytes_per_row; + for (uint32 i = VIDEO_MODE_X * bytes_per_pixel; i > x2 * bytes_per_pixel; i--) { + p--; + p2--; + if (*p != *p2) { + x2 = i / bytes_per_pixel; + break; + } + } + } + wide = x2 - x1; + + // Update copy of the_buffer + if (high && wide) { + + // Lock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_LockSurface(drv->s); + + // Blit to screen surface + for (uint32 j = y1; j <= y2; j++) { + uint32 i = j * bytes_per_row + x1 * bytes_per_pixel; + int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel; + memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); + Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide); + } + + // Unlock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_UnlockSurface(drv->s); + + // Refresh display + update_sdl_video(drv->s, x1, y1, wide, high); + } + } + } +} + +// Static display update (fixed frame rate, bounding boxes based) +// XXX use NQD bounding boxes to help detect dirty areas? +static void update_display_static_bbox(driver_base *drv) +{ + const VIDEO_MODE &mode = drv->mode; + + // Allocate bounding boxes for SDL_UpdateRects() + const uint32 N_PIXELS = 64; + const uint32 n_x_boxes = (VIDEO_MODE_X + N_PIXELS - 1) / N_PIXELS; + const uint32 n_y_boxes = (VIDEO_MODE_Y + N_PIXELS - 1) / N_PIXELS; + SDL_Rect *boxes = (SDL_Rect *)alloca(sizeof(SDL_Rect) * n_x_boxes * n_y_boxes); + uint32 nr_boxes = 0; + + // Lock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_LockSurface(drv->s); + + // Update the surface from Mac screen + const uint32 bytes_per_row = VIDEO_MODE_ROW_BYTES; + const uint32 bytes_per_pixel = bytes_per_row / VIDEO_MODE_X; + const uint32 dst_bytes_per_row = drv->s->pitch; + for (uint32 y = 0; y < VIDEO_MODE_Y; y += N_PIXELS) { + uint32 h = N_PIXELS; + if (h > VIDEO_MODE_Y - y) + h = VIDEO_MODE_Y - y; + for (uint32 x = 0; x < VIDEO_MODE_X; x += N_PIXELS) { + uint32 w = N_PIXELS; + if (w > VIDEO_MODE_X - x) + w = VIDEO_MODE_X - x; + const int xs = w * bytes_per_pixel; + const int xb = x * bytes_per_pixel; + bool dirty = false; + for (uint32 j = y; j < (y + h); j++) { + const uint32 yb = j * bytes_per_row; + const uint32 dst_yb = j * dst_bytes_per_row; + if (memcmp(&the_buffer[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { + memcpy(&the_buffer_copy[yb + xb], &the_buffer[yb + xb], xs); + Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, the_buffer + yb + xb, xs); + dirty = true; + } + } + if (dirty) { + boxes[nr_boxes].x = x; + boxes[nr_boxes].y = y; + boxes[nr_boxes].w = w; + boxes[nr_boxes].h = h; + nr_boxes++; + } + } + } + + // Unlock surface, if required + if (SDL_MUSTLOCK(drv->s)) + SDL_UnlockSurface(drv->s); + + // Refresh display + if (nr_boxes) + update_sdl_video(drv->s, nr_boxes, boxes); +} + + +// We suggest the compiler to inline the next two functions so that it +// may specialise the code according to the current screen depth and +// display type. A clever compiler would do that job by itself though... + +// NOTE: update_display_vosf is inlined too + +static inline void possibly_quit_dga_mode() +{ + // Quit DGA mode if requested (something terrible has happened and we + // want to give control back to the user) + if (quit_full_screen) { + quit_full_screen = false; + delete drv; + drv = NULL; + } +} + +static inline void possibly_ungrab_mouse() +{ + // Ungrab mouse if requested (something terrible has happened and we + // want to give control back to the user) + if (quit_full_screen) { + quit_full_screen = false; + if (drv) + drv->ungrab_mouse(); + } +} + +static inline void handle_palette_changes(void) +{ + LOCK_PALETTE; + + if (sdl_palette_changed) { + sdl_palette_changed = false; + drv->update_palette(); + } + + UNLOCK_PALETTE; +} + +static void video_refresh_window_static(void); + +static void video_refresh_dga(void) +{ + // Quit DGA mode if requested + possibly_quit_dga_mode(); + video_refresh_window_static(); +} + +#ifdef ENABLE_VOSF +#if REAL_ADDRESSING || DIRECT_ADDRESSING +static void video_refresh_dga_vosf(void) +{ + // Quit DGA mode if requested + possibly_quit_dga_mode(); + + // Update display (VOSF variant) + static uint32 tick_counter = 0; + if (++tick_counter >= frame_skip) { + tick_counter = 0; + if (mainBuffer.dirty) { + LOCK_VOSF; + update_display_dga_vosf(drv); + UNLOCK_VOSF; + } + } +} +#endif + +static void video_refresh_window_vosf(void) +{ + // Ungrab mouse if requested + possibly_ungrab_mouse(); + + // Update display (VOSF variant) + static uint32 tick_counter = 0; + if (++tick_counter >= frame_skip) { + tick_counter = 0; + if (mainBuffer.dirty) { + LOCK_VOSF; + update_display_window_vosf(drv); + UNLOCK_VOSF; + } + } +} +#endif // def ENABLE_VOSF + +static void video_refresh_window_static(void) +{ + // Ungrab mouse if requested + possibly_ungrab_mouse(); + + // Update display (static variant) + static uint32 tick_counter = 0; + if (++tick_counter >= frame_skip) { + tick_counter = 0; + const VIDEO_MODE &mode = drv->mode; + if ((int)VIDEO_MODE_DEPTH >= VIDEO_DEPTH_8BIT) + update_display_static_bbox(drv); + else + update_display_static(drv); + } +} + + +/* + * Thread for screen refresh, input handling etc. + */ + +static void VideoRefreshInit(void) +{ + // TODO: set up specialised 8bpp VideoRefresh handlers ? + if (display_type == DISPLAY_SCREEN) { +#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) + if (use_vosf) + video_refresh = video_refresh_dga_vosf; + else +#endif + video_refresh = video_refresh_dga; + } + else { +#ifdef ENABLE_VOSF + if (use_vosf) + video_refresh = video_refresh_window_vosf; + else +#endif + video_refresh = video_refresh_window_static; + } +} + +static inline void do_video_refresh(void) +{ + // Handle SDL events + handle_events(); + + // Update display + video_refresh(); + + + // Set new palette if it was changed + handle_palette_changes(); +} + +// This function is called on non-threaded platforms from a timer interrupt +void VideoRefresh(void) +{ + // We need to check redraw_thread_active to inhibit refreshed during + // mode changes on non-threaded platforms + if (!redraw_thread_active) + return; + + // Process pending events and update display + do_video_refresh(); +} + +const int VIDEO_REFRESH_HZ = 60; +const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; + +#ifndef USE_CPU_EMUL_SERVICES +static int redraw_func(void *arg) +{ + uint64 start = GetTicks_usec(); + int64 ticks = 0; + uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; + + while (!redraw_thread_cancel) { + + // Wait + next += VIDEO_REFRESH_DELAY; + int32 delay = int32(next - GetTicks_usec()); + if (delay > 0) + Delay_usec(delay); + else if (delay < -VIDEO_REFRESH_DELAY) + next = GetTicks_usec(); + ticks++; + + // Pause if requested (during video mode switches) + if (thread_stop_req) { + thread_stop_ack = true; + continue; + } + + // Process pending events and update display + do_video_refresh(); + } + + uint64 end = GetTicks_usec(); + D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); + return 0; +} +#endif + + +/* + * Record dirty area from NQD + */ + +#ifdef SHEEPSHAVER +void video_set_dirty_area(int x, int y, int w, int h) +{ +#ifdef ENABLE_VOSF + const VIDEO_MODE &mode = drv->mode; + const unsigned screen_width = VIDEO_MODE_X; + const unsigned screen_height = VIDEO_MODE_Y; + const unsigned bytes_per_row = VIDEO_MODE_ROW_BYTES; + + if (use_vosf) { + vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); + return; + } +#endif + + // XXX handle dirty bounding boxes for non-VOSF modes +} +#endif + +#endif // ends: SDL version check From ab2fedcbe4f7454302952076dcd1ad38c2b4f61e Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 12 Jun 2021 15:15:21 -0700 Subject: [PATCH 11/24] Consolidate m68k memory map allocation --- BasiliskII/src/CrossPlatform/video_vosf.h | 48 ++--- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 86 +------- BasiliskII/src/CrossPlatform/vm_alloc.h | 8 - BasiliskII/src/MacOSX/main_macosx.mm | 137 +------------ BasiliskII/src/SDL/video_sdl.cpp | 1 + BasiliskII/src/SDL/video_sdl2.cpp | 107 ++++------ BasiliskII/src/Unix/main_unix.cpp | 137 +------------ BasiliskII/src/Windows/main_windows.cpp | 145 +------------- BasiliskII/src/include/main.h | 1 - BasiliskII/src/main.cpp | 31 +-- BasiliskII/src/rom_patches.cpp | 8 +- BasiliskII/src/rsrc_patches.cpp | 4 +- BasiliskII/src/uae_cpu/basilisk_glue.cpp | 184 +++++++++++++++--- BasiliskII/src/uae_cpu/compiler/compemu.h | 2 +- .../src/uae_cpu/compiler/compemu_support.cpp | 101 ++-------- BasiliskII/src/uae_cpu/cpu_emulation.h | 3 + BasiliskII/src/uae_cpu/memory.cpp | 11 +- 17 files changed, 267 insertions(+), 747 deletions(-) diff --git a/BasiliskII/src/CrossPlatform/video_vosf.h b/BasiliskII/src/CrossPlatform/video_vosf.h index 0c182925c..ff5412bec 100644 --- a/BasiliskII/src/CrossPlatform/video_vosf.h +++ b/BasiliskII/src/CrossPlatform/video_vosf.h @@ -211,13 +211,18 @@ static int log_base_2(uint32 x) } // Extend size to page boundary -static uint32 page_extend(uint32 size) -{ - const uint32 page_size = vm_get_page_size(); - const uint32 page_mask = page_size - 1; +static size_t page_extend(size_t size){ + const size_t page_size = vm_get_page_size(); + const size_t page_mask = page_size - 1; return (size + page_mask) & ~page_mask; } +// For use with assert() +static bool is_page_aligned(size_t size){ + const size_t page_size = vm_get_page_size(); + const size_t page_mask = page_size - 1; + return (size&page_mask)==0; +} /* * Check if VOSF acceleration is profitable on this platform @@ -272,17 +277,16 @@ static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faul * Initialize the VOSF system (mainBuffer structure, SIGSEGV handler) */ -static bool video_vosf_init(MONITOR_INIT) -{ +static bool video_vosf_init(MONITOR_INIT){ VIDEO_MODE_INIT_MONITOR; - const uintptr page_size = vm_get_page_size(); - const uintptr page_mask = page_size - 1; - - // Round up frame buffer base to page boundary - mainBuffer.memStart = (((uintptr) the_buffer) + page_mask) & ~page_mask; + const size_t page_size = vm_get_page_size(); + const size_t page_mask = page_size - 1; - // The frame buffer size shall already be aligned to page boundary (use page_extend) + // Must be page aligned (use page_extend) + assert(is_page_aligned((size_t)MacFrameBaseHost)); + assert(is_page_aligned(the_buffer_size)); + mainBuffer.memStart = (uintptr)MacFrameBaseHost; mainBuffer.memLength = the_buffer_size; mainBuffer.pageSize = page_size; @@ -513,7 +517,7 @@ static void update_display_window_vosf(VIDEO_DRV_WIN_INIT) const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES; int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j; for (j = y1; j <= y2; j++) { - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); + Screen_blit(the_host_buffer + i2, MacFrameBaseHost + i1, src_bytes_per_row); i1 += src_bytes_per_row; i2 += dst_bytes_per_row; } @@ -554,11 +558,11 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT){ if (mainBuffer.very_dirty) { PFLAG_CLEAR_ALL; vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ); - memcpy(the_buffer_copy, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); + memcpy(the_buffer_copy, MacFrameBaseHost, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); VIDEO_DRV_LOCK_PIXELS; int i1 = 0, i2 = 0; for (uint32_t j = 0; j < VIDEO_MODE_Y; j++) { - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); + Screen_blit(the_host_buffer + i2, MacFrameBaseHost + i1, src_bytes_per_row); i1 += src_bytes_per_row; i2 += scr_bytes_per_row; } @@ -606,7 +610,7 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT){ } last_scanline = y2; - // Update the_host_buffer and copy of the_buffer, one line at a time + // Update the_host_buffer and copy of frame buffer, one line at a time uint32 i1 = y1 * src_bytes_per_row; uint32 i2 = y1 * scr_bytes_per_row; #ifdef USE_SDL_VIDEO @@ -620,9 +624,9 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT){ VIDEO_DRV_LOCK_PIXELS; for (uint32 j = y1; j <= y2; j++) { for (uint32 i = 0; i < n_chunks; i++) { - if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size) != 0) { - memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size); - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size); + if (memcmp(the_buffer_copy + i1, MacFrameBaseHost + i1, src_chunk_size) != 0) { + memcpy(the_buffer_copy + i1, MacFrameBaseHost + i1, src_chunk_size); + Screen_blit(the_host_buffer + i2, MacFrameBaseHost + i1, src_chunk_size); #ifdef USE_SDL_VIDEO const int x = i * n_pixels; if (x < bb[bbi].x) { @@ -640,9 +644,9 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT){ i2 += dst_chunk_size; } if (src_chunk_size_left && dst_chunk_size_left) { - if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left) != 0) { - memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left); - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size_left); + if (memcmp(the_buffer_copy + i1, MacFrameBaseHost + i1, src_chunk_size_left) != 0) { + memcpy(the_buffer_copy + i1, MacFrameBaseHost + i1, src_chunk_size_left); + Screen_blit(the_host_buffer + i2, MacFrameBaseHost + i1, src_chunk_size_left); } #ifdef USE_SDL_VIDEO const int x = n_chunks * n_pixels; diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index 176060c07..cb30a3be9 100755 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -133,8 +133,6 @@ static int translate_map_flags(int vm_flags) flags |= MAP_SHARED; if (vm_flags & VM_MAP_PRIVATE) flags |= MAP_PRIVATE; - if (vm_flags & VM_MAP_FIXED) - flags |= MAP_FIXED; if (vm_flags & VM_MAP_32BIT) flags |= FORCE_MAP_32BIT; return flags; @@ -236,34 +234,14 @@ void vm_exit(void) #endif } -static void *reserved_buf; -static const size_t RESERVED_SIZE = 64 * 1024 * 1024; // for 5K Retina - -void *vm_acquire_reserved(size_t size) { - return reserved_buf && size <= RESERVED_SIZE ? reserved_buf : VM_MAP_FAILED; -} - -int vm_init_reserved(void *hostAddress) { - int result = vm_acquire_fixed(hostAddress, RESERVED_SIZE); - if (result >= 0) - reserved_buf = hostAddress; - return result; -} - /* Allocate zero-filled memory of SIZE bytes. The mapping is private and default protection bits are read / write. The return value is the actual mapping address chosen or VM_MAP_FAILED for errors. */ -void * vm_acquire(size_t size, int options) -{ +void * vm_acquire(size_t size, int options){ void * addr; - errno = 0; - // VM_MAP_FIXED are to be used with vm_acquire_fixed() only - if (options & VM_MAP_FIXED) - return VM_MAP_FAILED; - #ifndef HAVE_VM_WRITE_WATCH if (options & VM_MAP_WRITE_WATCH) return VM_MAP_FAILED; @@ -271,19 +249,18 @@ void * vm_acquire(size_t size, int options) #if defined(HAVE_MACH_VM) // vm_allocate() returns a zero-filled memory region - kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, reserved_buf ? size : size + RESERVED_SIZE, TRUE); + kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, TRUE); if (ret_code != KERN_SUCCESS) { errno = vm_error(ret_code); return VM_MAP_FAILED; } - if (!reserved_buf) - reserved_buf = (char *)addr + size; #elif defined(HAVE_MMAP_VM) int fd = zero_fd; int the_map_flags = translate_map_flags(options) | map_flags; if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED) return VM_MAP_FAILED; + printf("next=%p got=%p size=%p\n",next_address,addr,size); #if DIRECT_ADDRESSING // If MAP_32BIT and MAP_BASE fail to ensure @@ -317,63 +294,6 @@ void * vm_acquire(size_t size, int options) return addr; } -/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned). - Retuns 0 if successful, -1 on errors. */ - -int vm_acquire_fixed(void * addr, size_t size, int options) -{ - errno = 0; - - // Fixed mappings are required to be private - if (options & VM_MAP_SHARED) - return -1; - -#ifndef HAVE_VM_WRITE_WATCH - if (options & VM_MAP_WRITE_WATCH) - return -1; -#endif - -#if defined(HAVE_MACH_VM) - // vm_allocate() returns a zero-filled memory region - kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, 0); - if (ret_code != KERN_SUCCESS) { - errno = vm_error(ret_code); - return -1; - } -#elif defined(HAVE_MMAP_VM) - int fd = zero_fd; - int the_map_flags = translate_map_flags(options) | map_flags | MAP_FIXED; - - if (mmap((caddr_t)addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0) == (void *)MAP_FAILED) - return -1; -#elif defined(HAVE_WIN32_VM) - // Windows cannot allocate Low Memory - if (addr == NULL) - return -1; - - int alloc_type = MEM_RESERVE | MEM_COMMIT; - if (options & VM_MAP_WRITE_WATCH) - alloc_type |= MEM_WRITE_WATCH; - - // Allocate a possibly offset region to align on 64K boundaries - LPVOID req_addr = align_addr_segment(addr); - DWORD req_size = align_size_segment(addr, size); - LPVOID ret_addr = VirtualAlloc(req_addr, req_size, alloc_type, PAGE_EXECUTE_READWRITE); - if (ret_addr != req_addr) - return -1; -#else - // Unsupported - return -1; -#endif - - // Explicitely protect the newly mapped region here because on some systems, - // say MacOS X, mmap() doesn't honour the requested protection flags. - if (vm_protect(addr, size, VM_PAGE_DEFAULT) != 0) - return -1; - - return 0; -} - /* Deallocate any mapping for the region starting at ADDR and extending LEN bytes. Returns 0 if successful, -1 on errors. */ diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.h b/BasiliskII/src/CrossPlatform/vm_alloc.h index 41dd949df..ec0b594b0 100644 --- a/BasiliskII/src/CrossPlatform/vm_alloc.h +++ b/BasiliskII/src/CrossPlatform/vm_alloc.h @@ -57,7 +57,6 @@ extern "C" { /* Mapping options. */ #define VM_MAP_SHARED 0x01 #define VM_MAP_PRIVATE 0x02 -#define VM_MAP_FIXED 0x04 #define VM_MAP_32BIT 0x08 #define VM_MAP_WRITE_WATCH 0x10 @@ -101,13 +100,6 @@ extern void vm_exit(void); extern void * vm_acquire(size_t size, int options = VM_MAP_DEFAULT); -extern void * vm_acquire_reserved(size_t size); - -/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned). - Returns 0 if successful, -1 on errors. */ - -extern int vm_acquire_fixed(void * addr, size_t size, int options = VM_MAP_DEFAULT); - /* Deallocate any mapping for the region starting at ADDR and extending LEN bytes. Returns 0 if successful, -1 on errors. */ diff --git a/BasiliskII/src/MacOSX/main_macosx.mm b/BasiliskII/src/MacOSX/main_macosx.mm index b226e93bd..3eadf09f8 100644 --- a/BasiliskII/src/MacOSX/main_macosx.mm +++ b/BasiliskII/src/MacOSX/main_macosx.mm @@ -39,7 +39,6 @@ #include using std::string; -#include "cpu_emulation.h" #include "sys.h" #include "rom_patches.h" #include "xpram.h" @@ -50,7 +49,6 @@ #include "user_strings.h" #include "version.h" #include "main.h" -#include "vm_alloc.h" #include "sigsegv.h" #if USE_JIT @@ -64,25 +62,16 @@ #define DEBUG 0 #include "debug.h" - #include "main_macosx.h" // To bridge between main() and misc. classes - -// Constants -const char ROM_FILE_NAME[] = "ROM"; -const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area - - static char *bundle = NULL; // If in an OS X application bundle, its path - // CPU and FPU type, addressing mode int CPUType; bool CPUIs68060; int FPUType; bool TwentyFourBitAddressing; - // Global variables #ifdef HAVE_PTHREADS @@ -98,31 +87,11 @@ #endif -#if USE_SCRATCHMEM_SUBTERFUGE -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -#endif - #ifdef ENABLE_MON static struct sigaction sigint_sa; // sigaction for SIGINT handler static void sigint_handler(...); #endif -/* - * Helpers to map memory that can be accessed from the Mac side - */ - -// NOTE: VM_MAP_32BIT is only used when compiling a 64-bit JIT on specific platforms -void *vm_acquire_mac(size_t size) -{ - return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - -static int vm_acquire_mac_fixed(void *addr, size_t size) -{ - return vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - - /* * SIGSEGV handler */ @@ -206,14 +175,11 @@ static void usage(const char *prg_name) exit(0); } -int main(int argc, char **argv) -{ +int main(int argc, char **argv){ const char *vmdir = NULL; char str[256]; // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; srand(time(NULL)); tzset(); @@ -320,87 +286,11 @@ bool InitEmulator (void) // Register dump state function when we got mad after a segfault sigsegv_set_dump_state(sigsegv_dump_state); - // Read RAM size - RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - if (RAMSize > 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) - RAMSize = 1023*1024*1024; - -#if DIRECT_ADDRESSING - RAMSize = RAMSize & -getpagesize(); // Round down to page boundary -#endif - - // Initialize VM system - vm_init(); - - // Create areas for Mac RAM and ROM - { - uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); - if (ram_rom_area == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - RAMBaseHost = ram_rom_area; - ROMBaseHost = RAMBaseHost + RAMSize; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Allocate scratch memory - ScratchMem = (uint8 *)vm_acquire_mac(SCRATCH_MEM_SIZE); - if (ScratchMem == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block -#endif - -#if DIRECT_ADDRESSING - // RAMBaseMac shall always be zero - MEMBaseDiff = (uintptr)RAMBaseHost; - RAMBaseMac = 0; - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif - D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); - D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); - - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - if ( ! rom_path ) - if ( bundle ) - WarningAlert("No rom pathname set. Trying BasiliskII.app/ROM"); - else - WarningAlert("No rom pathname set. Trying ./ROM"); - - // Load Mac ROM - int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY); - if (rom_fd < 0) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - QuitEmulator(); - } - printf(GetString(STR_READING_ROM_FILE)); - ROMSize = lseek(rom_fd, 0, SEEK_END); - if (ROMSize != 64*1024 && ROMSize != 128*1024 && ROMSize != 256*1024 && ROMSize != 512*1024 && ROMSize != 1024*1024) { - ErrorAlert(STR_ROM_SIZE_ERR); - close(rom_fd); - QuitEmulator(); - } - lseek(rom_fd, 0, SEEK_SET); - if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - close(rom_fd); - QuitEmulator(); - } - - // Initialize everything if (!InitAll(vmdir)) QuitEmulator(); D(bug("Initialization complete\n")); - #ifdef ENABLE_MON // Setup SIGINT handler to enter mon sigemptyset(&sigint_sa.sa_mask); @@ -409,7 +299,6 @@ bool InitEmulator (void) sigaction(SIGINT, &sigint_sa, NULL); #endif - return YES; } @@ -420,8 +309,7 @@ bool InitEmulator (void) * Quit emulator */ -void QuitEmuNoExit() -{ +void QuitEmuNoExit(){ D(bug("QuitEmulator\n")); // Exit 680x0 emulation @@ -430,24 +318,6 @@ void QuitEmuNoExit() // Deinitialize everything ExitAll(); - // Free ROM/RAM areas - if (RAMBaseHost != VM_MAP_FAILED) { - vm_release(RAMBaseHost, RAMSize + 0x100000); - RAMBaseHost = NULL; - ROMBaseHost = NULL; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Delete scratch memory area - if (ScratchMem != (uint8 *)VM_MAP_FAILED) { - vm_release((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); - ScratchMem = NULL; - } -#endif - - // Exit VM wrappers - vm_exit(); - // Exit system routines SysExit(); @@ -455,8 +325,7 @@ void QuitEmuNoExit() PrefsExit(); } -void QuitEmulator(void) -{ +void QuitEmulator(void){ QuitEmuNoExit(); // Stop run loop? diff --git a/BasiliskII/src/SDL/video_sdl.cpp b/BasiliskII/src/SDL/video_sdl.cpp index 395778a00..3161c6dc1 100644 --- a/BasiliskII/src/SDL/video_sdl.cpp +++ b/BasiliskII/src/SDL/video_sdl.cpp @@ -100,6 +100,7 @@ static uint32 frame_skip; // Prefs items static int16 mouse_wheel_mode; static int16 mouse_wheel_lines; +#error merge changes from SDL2 static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) static uint32 the_buffer_size; // Size of allocated the_buffer diff --git a/BasiliskII/src/SDL/video_sdl2.cpp b/BasiliskII/src/SDL/video_sdl2.cpp index 77f53fa96..7e3225f6e 100644 --- a/BasiliskII/src/SDL/video_sdl2.cpp +++ b/BasiliskII/src/SDL/video_sdl2.cpp @@ -110,9 +110,9 @@ static int16 mouse_wheel_mode; static int16 mouse_wheel_lines; static bool mouse_wheel_reverse; -static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) -static uint32 the_buffer_size; // Size of allocated the_buffer +extern uint8* MacFrameBaseHost; // Mac frame buffer (where MacOS draws into) +static uint8* the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) +static uint32 the_buffer_size; // Size of active frame buffer static bool redraw_thread_active = false; // Flag: Redraw thread installed #ifndef USE_CPU_EMUL_SERVICES @@ -224,41 +224,7 @@ extern void SysMountFirstFloppy(void); SDL_UnlockSurface(SURFACE); \ } while (0) - -/* - * Framebuffer allocation routines - */ - -static void *vm_acquire_framebuffer(uint32 size) -{ -#ifdef HAVE_MACH_VM - return vm_acquire_reserved(size); -#else - // always try to reallocate framebuffer at the same address - static void *fb = VM_MAP_FAILED; - if (fb != VM_MAP_FAILED) { - if (vm_acquire_fixed(fb, size) < 0) { -#ifndef SHEEPSHAVER - printf("FATAL: Could not reallocate framebuffer at previous address\n"); -#endif - fb = VM_MAP_FAILED; - } - } - if (fb == VM_MAP_FAILED) - fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return fb; -#endif -} - -static inline void vm_release_framebuffer(void *fb, uint32 size) -{ -#ifndef HAVE_MACH_VM - vm_release(fb, size); -#endif -} - -static inline int get_customized_color_depth(int default_depth) -{ +static inline int get_customized_color_depth(int default_depth){ int display_color_depth = PrefsFindInt32("displaycolordepth"); D(bug("Get displaycolordepth %d\n", display_color_depth)); @@ -520,9 +486,9 @@ static void add_mode(int type, int width, int height, int resolution_id, int byt VideoModes.push_back(mode); } -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order) -{ +// Set Mac frame layout and base address +static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order){ + assert(MacFrameBaseHost); #if !REAL_ADDRESSING && !DIRECT_ADDRESSING int layout = FLAYOUT_DIRECT; if (depth == VIDEO_DEPTH_16BIT) @@ -537,11 +503,11 @@ static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool nati // Set variables used by UAE memory banking const VIDEO_MODE &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - InitFrameBufferMapping(); + memory_init(); #else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); + assert(Host2MacAddr(0)); + monitor.set_mac_frame_base(Host2MacAddr(MacFrameBaseHost)); #endif D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); } @@ -660,7 +626,6 @@ static driver_base *drv = NULL; // Pointer to currently used driver object driver_base::driver_base(SDL_monitor_desc &m) : monitor(m), mode(m.get_current_mode()), init_ok(false), s(NULL) { - the_buffer = NULL; the_buffer_copy = NULL; } @@ -1025,9 +990,10 @@ void driver_base::init() use_vosf = true; // Allocate memory for frame buffer (SIZE is extended to page-boundary) the_buffer_size = page_extend((aligned_height + 2) * s->pitch); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); + assert(the_buffer_size<=VRAMSize); + assert(MacFrameBaseHost); the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); + D(bug("MacFrameBaseHost = %p, the_buffer_copy = %p, the_host_buffer = %p\n", MacFrameBaseHost, the_buffer_copy, the_host_buffer)); // Check whether we can initialize the VOSF subsystem and it's profitable if (!video_vosf_init(monitor)) { @@ -1041,16 +1007,16 @@ void driver_base::init() } if (!use_vosf) { free(the_buffer_copy); - vm_release(the_buffer, the_buffer_size); the_host_buffer = NULL; } #endif if (!use_vosf) { // Allocate memory for frame buffer the_buffer_size = (aligned_height + 2) * s->pitch; + assert(the_buffer_size<=VRAMSize); + assert(MacFrameBaseHost); the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); + D(bug("MacFrameBaseHost = %p, the_buffer_copy = %p\n", MacFrameBaseHost, the_buffer_copy)); } // Set frame buffer base @@ -1126,13 +1092,6 @@ driver_base::~driver_base() //shutdown_sdl_video(); // This deletes SDL_Window, SDL_Renderer, in addition to // instances of SDL_Surface and SDL_Texture. - // the_buffer shall always be mapped through vm_acquire_framebuffer() - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release_framebuffer(the_buffer, the_buffer_size); - the_buffer = NULL; - } - // Free frame buffer(s) if (!use_vosf) { if (the_buffer_copy) { @@ -2211,11 +2170,11 @@ static void force_complete_window_refresh() UNLOCK_VOSF; } #endif - // Ensure each byte of the_buffer_copy differs from the_buffer to force a full update. + // Ensure each byte of the_buffer_copy differs from Mac framebuffer to force a full update. const VIDEO_MODE &mode = VideoMonitors[0]->get_current_mode(); const int len = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; for (int i = 0; i < len; i++) - the_buffer_copy[i] = !the_buffer[i]; + the_buffer_copy[i] = !MacFrameBaseHost[i]; } } @@ -2449,14 +2408,14 @@ static void update_display_static(driver_base *drv) // Check for first line from top and first line from bottom that have changed y1 = 0; for (uint32 j = 0; j < VIDEO_MODE_Y; j++) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { + if (memcmp(&MacFrameBaseHost[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { y1 = j; break; } } y2 = y1 - 1; for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { + if (memcmp(&MacFrameBaseHost[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { y2 = j; break; } @@ -2474,7 +2433,7 @@ static void update_display_static(driver_base *drv) x1 = line_len; for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; + p = &MacFrameBaseHost[j * bytes_per_row]; p2 = &the_buffer_copy[j * bytes_per_row]; for (uint32 i = 0; i < x1; i++) { if (*p != *p2) { @@ -2486,7 +2445,7 @@ static void update_display_static(driver_base *drv) } x2 = x1; for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; + p = &MacFrameBaseHost[j * bytes_per_row]; p2 = &the_buffer_copy[j * bytes_per_row]; p += bytes_per_row; p2 += bytes_per_row; @@ -2505,7 +2464,7 @@ static void update_display_static(driver_base *drv) x2_clipped = x2 > VIDEO_MODE_X? VIDEO_MODE_X : x2; wide_clipped = x2_clipped - x1; - // Update copy of the_buffer + // Update copy of frame buffer if (high && wide) { // Lock surface, if required @@ -2516,8 +2475,8 @@ static void update_display_static(driver_base *drv) int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte); int di = y1 * dst_bytes_per_row + x1; for (uint32 j = y1; j <= y2; j++) { - memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte); - Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte); + memcpy(the_buffer_copy + si, MacFrameBaseHost + si, wide / pixels_per_byte); + Screen_blit((uint8 *)drv->s->pixels + di, MacFrameBaseHost + si, wide / pixels_per_byte); si += src_bytes_per_row; di += dst_bytes_per_row; } @@ -2536,7 +2495,7 @@ static void update_display_static(driver_base *drv) x1 = VIDEO_MODE_X; for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; + p = &MacFrameBaseHost[j * bytes_per_row]; p2 = &the_buffer_copy[j * bytes_per_row]; for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) { if (*p != *p2) { @@ -2548,7 +2507,7 @@ static void update_display_static(driver_base *drv) } x2 = x1; for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; + p = &MacFrameBaseHost[j * bytes_per_row]; p2 = &the_buffer_copy[j * bytes_per_row]; p += bytes_per_row; p2 += bytes_per_row; @@ -2563,7 +2522,7 @@ static void update_display_static(driver_base *drv) } wide = x2 - x1; - // Update copy of the_buffer + // Update copy of frame buffer if (high && wide) { // Lock surface, if required @@ -2574,8 +2533,8 @@ static void update_display_static(driver_base *drv) for (uint32 j = y1; j <= y2; j++) { uint32 i = j * bytes_per_row + x1 * bytes_per_pixel; int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel; - memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); - Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide); + memcpy(the_buffer_copy + i, MacFrameBaseHost + i, bytes_per_pixel * wide); + Screen_blit((uint8 *)drv->s->pixels + dst_i, MacFrameBaseHost + i, bytes_per_pixel * wide); } // Unlock surface, if required @@ -2624,9 +2583,9 @@ static void update_display_static_bbox(driver_base *drv) for (uint32 j = y; j < (y + h); j++) { const uint32 yb = j * bytes_per_row; const uint32 dst_yb = j * dst_bytes_per_row; - if (memcmp(&the_buffer[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { - memcpy(&the_buffer_copy[yb + xb], &the_buffer[yb + xb], xs); - Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, the_buffer + yb + xb, xs); + if (memcmp(&MacFrameBaseHost[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { + memcpy(&the_buffer_copy[yb + xb], &MacFrameBaseHost[yb + xb], xs); + Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, MacFrameBaseHost + yb + xb, xs); dirty = true; } } diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 5df70a9d1..bf829c02f 100755 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -53,7 +53,6 @@ #include using std::string; -#include "cpu_emulation.h" #include "sys.h" #include "rom_patches.h" #include "xpram.h" @@ -66,19 +65,9 @@ using std::string; #include "user_strings.h" #include "version.h" #include "main.h" -#include "vm_alloc.h" #include "sigsegv.h" #include "rpc.h" -#if USE_JIT -#ifdef UPDATE_UAE -extern void (*flush_icache)(void); // from compemu_support.cpp -extern bool UseJIT; -#else -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif -#endif - #ifdef ENABLE_MON # include "mon.h" #endif @@ -86,16 +75,6 @@ extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_suppo #define DEBUG 0 #include "debug.h" -// Constants -const char ROM_FILE_NAME[] = "ROM"; -const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes #ifdef HAVE_PTHREADS @@ -119,10 +98,6 @@ static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to pro #endif -#if USE_SCRATCHMEM_SUBTERFUGE -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -#endif - #if !defined(HAVE_PTHREADS) static struct sigaction timer_sa; // sigaction used for timer @@ -140,7 +115,6 @@ static void sigint_handler(...); static rpc_connection_t *gui_connection = NULL; // RPC connection to the GUI static const char *gui_connection_path = NULL; // GUI connection identifier - // Prototypes static void *xpram_func(void *arg); static void *tick_func(void *arg); @@ -166,23 +140,6 @@ char *strdup(const char *s) } - -/* - * Helpers to map memory that can be accessed from the Mac side - */ - -// NOTE: VM_MAP_32BIT is only used when compiling a 64-bit JIT on specific platforms -void *vm_acquire_mac(size_t size) -{ - return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - -static int vm_acquire_mac_fixed(void *addr, size_t size) -{ - return vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - - /* * SIGSEGV handler */ @@ -326,8 +283,7 @@ static void usage(const char *prg_name) exit(0); } -int main(int argc, char **argv) -{ +int main(int argc, char **argv){ #if defined(ENABLE_GTK) && !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND) XInitThreads(); #endif @@ -335,8 +291,6 @@ int main(int argc, char **argv) char str[256]; // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; srand(time(NULL)); tzset(); @@ -499,82 +453,11 @@ int main(int argc, char **argv) // Register dump state function when we got mad after a segfault sigsegv_set_dump_state(sigsegv_dump_state); - // Read RAM size - RAMSize = PrefsFindInt32("ramsize"); - if (RAMSize <= 1000) { - RAMSize *= 1024 * 1024; - } - RAMSize &= 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - if (RAMSize > 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) - RAMSize = 1023*1024*1024; - -#if DIRECT_ADDRESSING - RAMSize = RAMSize & -getpagesize(); // Round down to page boundary -#endif - - // Initialize VM system - vm_init(); - - // Create areas for Mac RAM and ROM - { - uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); - if (ram_rom_area == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - RAMBaseHost = ram_rom_area; - ROMBaseHost = RAMBaseHost + RAMSize; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Allocate scratch memory - ScratchMem = (uint8 *)vm_acquire_mac(SCRATCH_MEM_SIZE); - if (ScratchMem == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block -#endif - -#if DIRECT_ADDRESSING - // RAMBaseMac shall always be zero - MEMBaseDiff = (uintptr)RAMBaseHost; - RAMBaseMac = 0; - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif - #if __MACOSX__ extern void set_current_directory(); set_current_directory(); #endif - // Get rom file path from preferences - const char *rom_path = PrefsFindString("rom"); - - // Load Mac ROM - int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY); - if (rom_fd < 0) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - QuitEmulator(); - } - printf("%s", GetString(STR_READING_ROM_FILE)); - ROMSize = lseek(rom_fd, 0, SEEK_END); - if (ROMSize != 64*1024 && ROMSize != 128*1024 && ROMSize != 256*1024 && ROMSize != 512*1024 && ROMSize != 1024*1024) { - ErrorAlert(STR_ROM_SIZE_ERR); - close(rom_fd); - QuitEmulator(); - } - lseek(rom_fd, 0, SEEK_SET); - if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - close(rom_fd); - QuitEmulator(); - } - // Initialize everything if (!InitAll(vmdir)) QuitEmulator(); @@ -720,24 +603,6 @@ void QuitEmulator(void) // Deinitialize everything ExitAll(); - // Free ROM/RAM areas - if (RAMBaseHost != VM_MAP_FAILED) { - vm_release(RAMBaseHost, RAMSize + 0x100000); - RAMBaseHost = NULL; - ROMBaseHost = NULL; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Delete scratch memory area - if (ScratchMem != (uint8 *)VM_MAP_FAILED) { - vm_release((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); - ScratchMem = NULL; - } -#endif - - // Exit VM wrappers - vm_exit(); - // Exit system routines SysExit(); diff --git a/BasiliskII/src/Windows/main_windows.cpp b/BasiliskII/src/Windows/main_windows.cpp index bceef52b8..ca242d81d 100755 --- a/BasiliskII/src/Windows/main_windows.cpp +++ b/BasiliskII/src/Windows/main_windows.cpp @@ -32,7 +32,6 @@ #include typedef std::basic_string tstring; -#include "cpu_emulation.h" #include "sys.h" #include "rom_patches.h" #include "xpram.h" @@ -46,7 +45,6 @@ typedef std::basic_string tstring; #include "user_strings.h" #include "version.h" #include "main.h" -#include "vm_alloc.h" #include "sigsegv.h" #include "util_windows.h" @@ -61,19 +59,6 @@ extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_suppo #define DEBUG 0 #include "debug.h" - -// Constants -const TCHAR ROM_FILE_NAME[] = TEXT("ROM"); -const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area - - -// CPU and FPU type, addressing mode -int CPUType; -bool CPUIs68060; -int FPUType; -bool TwentyFourBitAddressing; - - // Global variables HANDLE emul_thread = NULL; // Handle of MacOS emulation thread (main thread) @@ -90,16 +75,11 @@ static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags #define LOCK_INTFLAGS SDL_LockMutex(intflag_lock) #define UNLOCK_INTFLAGS SDL_UnlockMutex(intflag_lock) -#if USE_SCRATCHMEM_SUBTERFUGE -uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes -#endif - // Prototypes static int xpram_func(void *arg); static int tick_func(void *arg); static void one_tick(...); - /* * Ersatz functions */ @@ -117,17 +97,6 @@ char *strdup(const char *s) } - -/* - * Map memory that can be accessed from the Mac side - */ - -void *vm_acquire_mac(size_t size) -{ - return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); -} - - /* * SIGSEGV handler */ @@ -202,14 +171,11 @@ static void usage(const char *prg_name) exit(0); } -int main(int argc, char **argv) -{ +int main(int argc, char **argv){ char str[256]; bool cd_boot = false; // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; srand(unsigned(time(NULL))); tzset(); @@ -313,76 +279,6 @@ int main(int argc, char **argv) // Register dump state function when we got mad after a segfault sigsegv_set_dump_state(sigsegv_dump_state); - // Read RAM size - RAMSize = PrefsFindInt32("ramsize"); - if (RAMSize <= 1000) { - RAMSize *= 1024 * 1024; - } - RAMSize &= 0xfff00000; // Round down to 1MB boundary - if (RAMSize < 1024*1024) { - WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 1024*1024; - } - - // Initialize VM system - vm_init(); - - // Create areas for Mac RAM and ROM - uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000); - if (ram_rom_area == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - RAMBaseHost = ram_rom_area; - ROMBaseHost = RAMBaseHost + RAMSize; - -#if USE_SCRATCHMEM_SUBTERFUGE - // Allocate scratch memory - ScratchMem = (uint8 *)vm_acquire(SCRATCH_MEM_SIZE); - if (ScratchMem == VM_MAP_FAILED) { - ErrorAlert(STR_NO_MEM_ERR); - QuitEmulator(); - } - ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block -#endif - -#if DIRECT_ADDRESSING - // RAMBaseMac shall always be zero - MEMBaseDiff = (uintptr)RAMBaseHost; - RAMBaseMac = 0; - ROMBaseMac = Host2MacAddr(ROMBaseHost); -#endif - D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); - D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); - - // Get rom file path from preferences - const char* rom_path = PrefsFindString("rom"); - - // Load Mac ROM - HANDLE rom_fh = CreateFile((rom_path != NULL) ? rom_path : ROM_FILE_NAME, - GENERIC_READ, - FILE_SHARE_READ, NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (rom_fh == INVALID_HANDLE_VALUE) { - ErrorAlert(STR_NO_ROM_FILE_ERR); - QuitEmulator(); - } - printf(GetString(STR_READING_ROM_FILE)); - ROMSize = GetFileSize(rom_fh, NULL); - if (ROMSize != 64*1024 && ROMSize != 128*1024 && ROMSize != 256*1024 && ROMSize != 512*1024 && ROMSize != 1024*1024) { - ErrorAlert(STR_ROM_SIZE_ERR); - CloseHandle(rom_fh); - QuitEmulator(); - } - DWORD bytes_read; - if (ReadFile(rom_fh, ROMBaseHost, ROMSize, &bytes_read, NULL) == 0 || bytes_read != ROMSize) { - ErrorAlert(STR_ROM_FILE_READ_ERR); - CloseHandle(rom_fh); - QuitEmulator(); - } - // Initialize native timers timer_init(); @@ -421,8 +317,7 @@ int main(int argc, char **argv) * Quit emulator */ -void QuitEmulator(void) -{ +void QuitEmulator(void){ D(bug("QuitEmulator\n")); // Exit 680x0 emulation @@ -443,27 +338,6 @@ void QuitEmulator(void) // Deinitialize everything ExitAll(); - // Free ROM/RAM areas - if (RAMBaseHost != VM_MAP_FAILED) { - vm_release(RAMBaseHost, RAMSize); - RAMBaseHost = NULL; - } - if (ROMBaseHost != VM_MAP_FAILED) { - vm_release(ROMBaseHost, 0x100000); - ROMBaseHost = NULL; - } - -#if USE_SCRATCHMEM_SUBTERFUGE - // Delete scratch memory area - if (ScratchMem != (uint8 *)VM_MAP_FAILED) { - vm_release((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE); - ScratchMem = NULL; - } -#endif - - // Exit VM wrappers - vm_exit(); - // Exit system routines SysExit(); @@ -473,21 +347,6 @@ void QuitEmulator(void) exit(0); } - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size) -{ -#if USE_JIT - if (UseJIT) - flush_icache_range((uint8 *)start, size); -#endif -} - - /* * Mutexes */ diff --git a/BasiliskII/src/include/main.h b/BasiliskII/src/include/main.h index cc3017477..945a0d6fc 100644 --- a/BasiliskII/src/include/main.h +++ b/BasiliskII/src/include/main.h @@ -23,7 +23,6 @@ // CPU type (0 = 68000, 1 = 68010, 2 = 68020, 3 = 68030, 4 = 68040/060) extern int CPUType; -extern bool CPUIs68060; // Flag to distinguish 68040 and 68060 // FPU type (0 = no FPU, 1 = 68881, 2 = 68882) extern int FPUType; diff --git a/BasiliskII/src/main.cpp b/BasiliskII/src/main.cpp index 148fb581c..469a3f284 100644 --- a/BasiliskII/src/main.cpp +++ b/BasiliskII/src/main.cpp @@ -42,30 +42,30 @@ #define DEBUG 0 #include "debug.h" +// CPU and FPU type, addressing mode +int CPUType; +int FPUType; +bool TwentyFourBitAddressing; + #if ENABLE_MON #include "mon.h" -static uint32 mon_read_byte_b2(uintptr adr) -{ +static uint32 mon_read_byte_b2(uintptr adr){ return ReadMacInt8(adr); } -static void mon_write_byte_b2(uintptr adr, uint32 b) -{ +static void mon_write_byte_b2(uintptr adr, uint32 b){ WriteMacInt8(adr, b); } #endif - /* * Initialize everything, returns false on error */ -bool InitAll(const char *vmdir) -{ - // Check ROM version - if (!CheckROM()) { - ErrorAlert(STR_UNSUPPORTED_ROM_TYPE_ERR); +bool InitAll(const char *vmdir){ + // Allocate memory map and load ROM + if (!InitMacMem()) { return false; } @@ -95,7 +95,6 @@ bool InitAll(const char *vmdir) TwentyFourBitAddressing = false; break; } - CPUIs68060 = false; // Load XPRAM XPRAMInit(vmdir); @@ -178,16 +177,16 @@ bool InitAll(const char *vmdir) XPRAM[0x58] = uint8(main_monitor.depth_to_apple_mode(main_monitor.get_current_mode().depth)); XPRAM[0x59] = 0; - // Init 680x0 emulation (this also activates the memory system which is needed for PatchROM()) - if (!Init680x0()) - return false; - // Install ROM patches if (!PatchROM()) { ErrorAlert(STR_UNSUPPORTED_ROM_TYPE_ERR); return false; } + // Init 680x0 emulation (this also activates the memory system which is needed for PatchROM()) + if (!Init680x0()) + return false; + #if ENABLE_MON // Initialize mon mon_init(); @@ -246,6 +245,8 @@ void ExitAll(void) CDROMExit(); DiskExit(); SonyExit(); + + MacMemExit(); } diff --git a/BasiliskII/src/rom_patches.cpp b/BasiliskII/src/rom_patches.cpp index 1fb85e59b..763b9db86 100644 --- a/BasiliskII/src/rom_patches.cpp +++ b/BasiliskII/src/rom_patches.cpp @@ -822,26 +822,22 @@ void PatchAfterStartup(void) #endif } - /* * Check ROM version, returns false if ROM version is not supported */ -bool CheckROM(void) -{ +bool CheckROM(void){ // Read version ROMVersion = ntohs(*(uint16 *)(ROMBaseHost + 8)); #if DIRECT_ADDRESSING - // Real and direct addressing modes require a 32-bit clean ROM + // requires a 32-bit clean ROM return ROMVersion == ROM_VERSION_32; #else - // Virtual addressing mode works with 32-bit clean Mac II ROMs and Classic ROMs return (ROMVersion == ROM_VERSION_CLASSIC) || (ROMVersion == ROM_VERSION_32); #endif } - /* * Install ROM patches, returns false if ROM version is not supported */ diff --git a/BasiliskII/src/rsrc_patches.cpp b/BasiliskII/src/rsrc_patches.cpp index cdff157ee..ccb108214 100644 --- a/BasiliskII/src/rsrc_patches.cpp +++ b/BasiliskII/src/rsrc_patches.cpp @@ -109,7 +109,7 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size) if (base) { p16 = (uint16 *)(p + base); -#if defined(USE_SCRATCHMEM_SUBTERFUGE) +#if USE_SCRATCHMEM_SUBTERFUGE // Set 0x0000 to scratch memory area extern uint8 *ScratchMem; const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); @@ -134,7 +134,7 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size) if (base) { p16 = (uint16 *)(p + base); -#if defined(USE_SCRATCHMEM_SUBTERFUGE) +#if USE_SCRATCHMEM_SUBTERFUGE // Set 0x0000 to scratch memory area extern uint8 *ScratchMem; const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index d6c6d3b17..c815ccb94 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -31,23 +31,39 @@ #include "readcpu.h" #include "newcpu.h" #include "compiler/compemu.h" +#include "vm_alloc.h" +#include "user_strings.h" +#include "debug.h" + +#if DIRECT_ADDRESSING +uintptr MEMBaseDiff = 0; // Global offset between a Mac address and its Host equivalent +#endif // RAM and ROM pointers -uint32 RAMBaseMac = 0; // RAM base (Mac address space) gb-- initializer is important -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM +uint8* RAMBaseHost = 0; // RAM base (host address space) +uint8* ROMBaseHost = 0; // ROM base (host address space) +uint32 RAMBaseMac = 0; // RAM base (Mac address space) +uint32 ROMBaseMac = 0; // ROM base (Mac address space) +uint32 RAMSize = 0; // Size of RAM +uint32 ROMSize = 0; // Size of ROM // Mac frame buffer -uint8 *MacFrameBaseHost; // Frame buffer base (host address space) -uint32 MacFrameSize; // Size of frame buffer +uint8* MacFrameBaseHost; // Frame buffer base (host address space) +uint32 MacFrameSize; // Size of current frame buffer int MacFrameLayout; // Frame buffer layout +uint32 VRAMSize; // Size of VRAM -#if DIRECT_ADDRESSING -uintptr MEMBaseDiff; // Global offset between a Mac address and its Host equivalent +uint32 JITCacheSize=0; + +const char ROM_FILE_NAME[] = "ROM"; +const int MAX_ROM_SIZE = 1024*1024; // 1mb + +#if USE_SCRATCHMEM_SUBTERFUGE +uint8* ScratchMem = NULL; // Scratch memory for Mac ROM writes +int ScratchMemSize = 64*1024; // 64k +#else +int ScratchMemSize = 0; #endif #if USE_JIT @@ -57,20 +73,122 @@ bool UseJIT = false; // From newcpu.cpp extern bool quit_program; +// Create our virtual Macintosh memory map and load ROM +bool InitMacMem(void){ + assert(RAMBaseHost==0); // don't call us twice -/* - * Initialize 680x0 emulation, CheckROM() must have been called first - */ + // Read RAM size + RAMSize = PrefsFindInt32("ramsize"); + if (RAMSize <= 1000) { + RAMSize *= 1024 * 1024; + } + RAMSize &= 0xfff00000; // Round down to 1MB boundary + if (RAMSize < 1024*1024) { + WarningAlert(GetString(STR_SMALL_RAM_WARN)); + RAMSize = 1024*1024; + } + if (RAMSize > 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) + RAMSize = 1023*1024*1024; + + VRAMSize = 16*1024*1024; // 16mb, more than enough for 1920x1440x32 + +#if USE_JIT + JITCacheSize = 1024*PrefsFindInt32("jitcachesize") + 1024; +#endif + + // Initialize VM system + vm_init(); + + // Create our virtual Macintosh memory map + RAMBaseHost = (uint8*)vm_acquire( + RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize, + VM_MAP_DEFAULT | VM_MAP_32BIT); + if (RAMBaseHost == VM_MAP_FAILED) { + ErrorAlert(STR_NO_MEM_ERR); + return false; + } + printf("RAMBaseHost=%p\n",RAMBaseHost); + ROMBaseHost = RAMBaseHost + RAMSize + ScratchMemSize; + printf("ROMBaseHost=%p\n",ROMBaseHost); + MacFrameBaseHost = ROMBaseHost + MAX_ROM_SIZE; + printf("MacFrameBaseHost=%p\n",MacFrameBaseHost); + +#if USE_SCRATCHMEM_SUBTERFUGE + // points to middle of scratch memory + ScratchMem = RAMBaseHost + RAMSize + ScratchMemSize/2; + printf("ScratchMem=%p\n",ScratchMem); +#endif + + // Get rom file path from preferences + const char *rom_path = PrefsFindString("rom"); + + // Load Mac ROM +#ifdef WIN32 + HANDLE rom_fh = CreateFile( + rom_path ? rom_path : ROM_FILE_NAME, + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (rom_fh == INVALID_HANDLE_VALUE) { + ErrorAlert(STR_NO_ROM_FILE_ERR); + return false; + } +#else + int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY); + if (rom_fd < 0) { + ErrorAlert(STR_NO_ROM_FILE_ERR); + return false; + } +#endif + printf("%s", GetString(STR_READING_ROM_FILE)); +#ifdef WIN32 + ROMSize = GetFileSize(rom_fh, NULL); +#else + ROMSize = lseek(rom_fd, 0, SEEK_END); +#endif + switch(ROMSize){ + case 64*1024: + case 128*1024: + case 256*1024: + case 512*1024: + case MAX_ROM_SIZE: + break; + default: + ErrorAlert(STR_ROM_SIZE_ERR); +#ifdef WIN32 + CloseHandle(rom_fh); +#else + close(rom_fd); +#endif + return false; + } +#ifdef WIN32 + DWORD bytes_read; + if (ReadFile(rom_fh, ROMBaseHost, ROMSize, &bytes_read, NULL) == 0 || bytes_read != ROMSize) { +#else + lseek(rom_fd, 0, SEEK_SET); + if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) { +#endif + ErrorAlert(STR_ROM_FILE_READ_ERR); +#ifdef WIN32 + CloseHandle(rom_fh); +#else + close(rom_fd); +#endif + return false; + } + + if (!CheckROM()) { + ErrorAlert(STR_UNSUPPORTED_ROM_TYPE_ERR); + return false; + } -bool Init680x0(void){ #if DIRECT_ADDRESSING // Mac address space = host address space minus constant offset (MEMBaseDiff) - // NOTE: MEMBaseDiff is set up in main_unix.cpp/main() - RAMBaseMac = 0; + MEMBaseDiff = (uintptr)RAMBaseHost; ROMBaseMac = Host2MacAddr(ROMBaseHost); #else // Initialize UAE memory banks - RAMBaseMac = 0; switch (ROMVersion) { case ROM_VERSION_64K: case ROM_VERSION_PLUS: @@ -88,12 +206,32 @@ bool Init680x0(void){ } memory_init(); #endif + D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); + D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); + + return true; +} + +void MacMemExit(void){ + assert(RAMBaseHost); + vm_release(RAMBaseHost, + RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize); + RAMBaseHost = NULL; + ROMBaseHost = NULL; + //Exit VM wrappers + vm_exit(); +} + +/* + * Initialize 680x0 emulation, CheckROM() must have been called first + */ +bool Init680x0(void){ init_m68k(); #if USE_JIT UseJIT = compiler_use_jit(); if (UseJIT) - compiler_init(); + compiler_init(MacFrameBaseHost + VRAMSize); #endif return true; } @@ -112,16 +250,6 @@ void Exit680x0(void) exit_m68k(); } -/* - * Initialize memory mapping of frame buffer (called upon video mode change) - */ - -void InitFrameBufferMapping(void){ -#if !DIRECT_ADDRESSING - memory_init(); -#endif -} - /* * Reset and start 680x0 emulation (doesn't return) */ diff --git a/BasiliskII/src/uae_cpu/compiler/compemu.h b/BasiliskII/src/uae_cpu/compiler/compemu.h index 9a612fb21..daad5b209 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu.h +++ b/BasiliskII/src/uae_cpu/compiler/compemu.h @@ -139,7 +139,7 @@ union cacheline { /* Functions exposed to newcpu, or to what was moved from newcpu.c to * compemu_support.c */ -extern void compiler_init(void); +extern void compiler_init(void*); extern void compiler_exit(void); extern bool compiler_use_jit(void); extern void init_comp(void); diff --git a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp index 1186d8dda..04f990ea3 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp +++ b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp @@ -5003,12 +5003,13 @@ static inline const char *str_on_off(bool b) return b ? "on" : "off"; } -void compiler_init(void) -{ +void compiler_init(void* buf){ static bool initialized = false; if (initialized) return; + compiled_code=(uint8*)buf; + #if JIT_DEBUG // JIT debug mode ? JITDebug = PrefsFindBool("jitdebug"); @@ -5065,24 +5066,11 @@ void compiler_init(void) #endif } -void compiler_exit(void) -{ +void compiler_exit(void){ #if PROFILE_COMPILE_TIME emul_end_time = clock(); #endif - // Deallocate translation cache - if (compiled_code) { - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } - - // Deallocate popallspace - if (popallspace) { - vm_release(popallspace, POPALLSPACE_SIZE); - popallspace = 0; - } - #if PROFILE_COMPILE_TIME write_log("### Compile Block statistics\n"); write_log("Number of calls to compile_block : %d\n", compile_count); @@ -5673,79 +5661,20 @@ uae_u32 get_jitted_size(void) const int CODE_ALLOC_MAX_ATTEMPTS = 10; const int CODE_ALLOC_BOUNDARIES = 128 * 1024; // 128 KB -static uint8 *do_alloc_code(uint32 size, int depth) -{ -#if defined(__linux__) && 0 - /* - This is a really awful hack that is known to work on Linux at - least. - - The trick here is to make sure the allocated cache is nearby - code segment, and more precisely in the positive half of a - 32-bit address space. i.e. addr < 0x80000000. Actually, it - turned out that a 32-bit binary run on AMD64 yields a cache - allocated around 0xa0000000, thus causing some troubles when - translating addresses from m68k to x86. - */ - static uint8 * code_base = NULL; - if (code_base == NULL) { - uintptr page_size = getpagesize(); - uintptr boundaries = CODE_ALLOC_BOUNDARIES; - if (boundaries < page_size) - boundaries = page_size; - code_base = (uint8 *)sbrk(0); - for (int attempts = 0; attempts < CODE_ALLOC_MAX_ATTEMPTS; attempts++) { - if (vm_acquire_fixed(code_base, size) == 0) { - uint8 *code = code_base; - code_base += size; - return code; - } - code_base += boundaries; - } - return NULL; - } - - if (vm_acquire_fixed(code_base, size) == 0) { - uint8 *code = code_base; - code_base += size; - return code; - } - - if (depth >= CODE_ALLOC_MAX_ATTEMPTS) - return NULL; - - return do_alloc_code(size, depth + 1); -#else - uint8 *code = (uint8 *)vm_acquire(size); - return code == VM_MAP_FAILED ? NULL : code; -#endif -} - -static inline uint8 *alloc_code(uint32 size) -{ - uint8 *ptr = do_alloc_code(size, 0); +static inline uint8 *alloc_code(uint32 size){ + uint8 *ptr = (uint8 *)vm_acquire(size); + ptr == VM_MAP_FAILED ? NULL : ptr; /* allocated code must fit in 32-bit boundaries */ - assert((uintptr)ptr <= 0xffffffff); + assert((size_t)ptr<0xffffffffL); return ptr; } -void alloc_cache(void) -{ - if (compiled_code) { - flush_icache_hard(6); - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } +void alloc_cache(void){ + assert(compiled_code); if (cache_size == 0) return; - while (!compiled_code && cache_size) { - if ((compiled_code = alloc_code(cache_size * 1024)) == NULL) { - compiled_code = 0; - cache_size /= 2; - } - } vm_protect(compiled_code, cache_size * 1024, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE); if (compiled_code) { @@ -5997,14 +5926,10 @@ static __inline__ void match_states(blockinfo* bi) } } -static __inline__ void create_popalls(void) -{ +static void create_popalls(void){ int i,r; - if ((popallspace = alloc_code(POPALLSPACE_SIZE)) == NULL) { - write_log("FATAL: Could not allocate popallspace!\n"); - abort(); - } + popallspace = compiled_code + cache_size*1024; vm_protect(popallspace, POPALLSPACE_SIZE, VM_PAGE_READ | VM_PAGE_WRITE); int stack_space = STACK_OFFSET; @@ -6320,8 +6245,8 @@ void build_comp(void) write_log(" : supposedly %d compileable opcodes!\n",count); /* Initialise state */ - create_popalls(); alloc_cache(); + create_popalls(); reset_lists(); for (i=0;i ROMBaseMac ? ROMBaseMac : RAMSize; + // RAM must not overlap ROM + assert(RAMSize> 16, ram_size >> 16); + map_banks(&ram24_bank, RAMBaseMac >> 16, RAMSize >> 16); map_banks(&rom24_bank, ROMBaseMac >> 16, ROMSize >> 16); // Map frame buffer at end of RAM. map_banks(&fram24_bank, ((RAMBaseMac + ram_size) >> 16) - 1, 1); } else { - map_banks(&ram_bank, RAMBaseMac >> 16, ram_size >> 16); + map_banks(&ram_bank, RAMBaseMac >> 16, RAMSize >> 16); map_banks(&rom_bank, ROMBaseMac >> 16, ROMSize >> 16); // Map frame buffer From 2e2f2a6b4672114fda3511e1991f0b460ceff00f Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 12 Jun 2021 15:16:59 -0700 Subject: [PATCH 12/24] Make Basilisk II (mostly) 64bit clean --- BasiliskII/src/CrossPlatform/video_vosf.h | 64 +++++++-------- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 62 ++++----------- BasiliskII/src/Unix/main_unix.cpp | 41 +++------- BasiliskII/src/Unix/sysdeps.h | 2 + BasiliskII/src/main.cpp | 10 +-- BasiliskII/src/uae_cpu/basilisk_glue.cpp | 78 +++++++++++-------- .../src/uae_cpu/compiler/codegen_x86.cpp | 5 +- BasiliskII/src/uae_cpu/compiler/compemu.h | 4 +- .../src/uae_cpu/compiler/compemu_support.cpp | 49 ++++-------- BasiliskII/src/uae_cpu/cpu_emulation.h | 11 ++- BasiliskII/src/uae_cpu/memory.cpp | 16 ++-- BasiliskII/src/uae_cpu/memory.h | 4 +- 12 files changed, 138 insertions(+), 208 deletions(-) diff --git a/BasiliskII/src/CrossPlatform/video_vosf.h b/BasiliskII/src/CrossPlatform/video_vosf.h index ff5412bec..b01725026 100644 --- a/BasiliskII/src/CrossPlatform/video_vosf.h +++ b/BasiliskII/src/CrossPlatform/video_vosf.h @@ -78,7 +78,7 @@ extern void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects) #endif // Prototypes -static void vosf_do_set_dirty_area(uintptr first, uintptr last); +static void vosf_do_set_dirty_area(const size_t, const size_t); static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_width, unsigned screen_height, unsigned bytes_per_row); // Variables for Video on SEGV support @@ -89,17 +89,17 @@ struct ScreenPageInfo { }; struct ScreenInfo { - uintptr memStart; // Start address aligned to page boundary - uint32 memLength; // Length of the memory addressed by the screen pages - - uintptr pageSize; // Size of a page - int pageBits; // Shift count to get the page number - uint32 pageCount; // Number of pages allocated to the screen - + uint8* memStart; // Start address aligned to page boundary + int memLength; // Length of the memory addressed by the screen pages + + int pageSize; // Size of a page + int pageBits; // Shift count to get the page number + int pageCount; // Number of pages allocated to the screen + + char* dirtyPages; // Table of flags set if page was altered + ScreenPageInfo* pageInfo; // Table of mappings page -> Mac scanlines bool dirty; // Flag: set if the frame buffer was touched bool very_dirty; // Flag: set if the frame buffer was completely modified (e.g. colormap changes) - char * dirtyPages; // Table of flags set if page was altered - ScreenPageInfo * pageInfo; // Table of mappings page -> Mac scanlines }; static ScreenInfo mainBuffer; @@ -251,7 +251,7 @@ static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faul for (uint32 p = 0; p < mainBuffer.pageCount; p++) { uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize)); if (accel) - vosf_do_set_dirty_area((uintptr)addr, (uintptr)addr + mainBuffer.pageSize - 1); + vosf_do_set_dirty_area((size_t)addr, (size_t)addr + mainBuffer.pageSize - 1); else addr[0] = 0; // Trigger Screen_fault_handler() } @@ -268,7 +268,7 @@ static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faul if (n_page_faults_p) *n_page_faults_p = n_page_faults; - D(bug("Triggered %d page faults in %ld usec (%.1f usec per fault)\n", n_page_faults, duration, double(duration) / double(n_page_faults))); + D(bug("Triggered %d page faults in %ld usec (%.1f usec per fault)\n", n_page_faults, (long int)duration, double(duration) / double(n_page_faults))); return ((duration / n_tries) < (VOSF_PROFITABLE_THRESHOLD * (frame_skip ? frame_skip : 1))); } @@ -286,7 +286,7 @@ static bool video_vosf_init(MONITOR_INIT){ // Must be page aligned (use page_extend) assert(is_page_aligned((size_t)MacFrameBaseHost)); assert(is_page_aligned(the_buffer_size)); - mainBuffer.memStart = (uintptr)MacFrameBaseHost; + mainBuffer.memStart = MacFrameBaseHost; mainBuffer.memLength = the_buffer_size; mainBuffer.pageSize = page_size; @@ -353,16 +353,14 @@ static void video_vosf_exit(void) } } - /* * Update VOSF state with specified dirty area */ -static void vosf_do_set_dirty_area(uintptr first, uintptr last) -{ - const int first_page = (first - mainBuffer.memStart) >> mainBuffer.pageBits; - const int last_page = (last - mainBuffer.memStart) >> mainBuffer.pageBits; - uint8 *addr = (uint8 *)(first & ~(mainBuffer.pageSize - 1)); +static void vosf_do_set_dirty_area(const size_t first, const size_t last){ + const int first_page = ((size_t)first - (size_t)mainBuffer.memStart) >> mainBuffer.pageBits; + const int last_page = ((size_t)last - (size_t)mainBuffer.memStart) >> mainBuffer.pageBits; + uint8* addr = (uint8*)((size_t)first & ~((size_t)mainBuffer.pageSize - 1)); for (int i = first_page; i <= last_page; i++) { if (PFLAG_ISCLEAR(i)) { PFLAG_SET(i); @@ -392,26 +390,26 @@ static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_widt if (bytes_per_row >= screen_width) { const int bytes_per_pixel = bytes_per_row / screen_width; if (bytes_per_row <= mainBuffer.pageSize) { - const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel; - const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel; + const size_t a0 = (size_t)mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel; + const size_t a1 = (size_t)mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel; vosf_do_set_dirty_area(a0, a1); } else { for (int j = y; j < y + h; j++) { - const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel; - const uintptr a1 = a0 + (w - 1) * bytes_per_pixel; + const size_t a0 = (size_t)mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel; + const size_t a1 = a0 + (w - 1) * bytes_per_pixel; vosf_do_set_dirty_area(a0, a1); } } } else { const int pixels_per_byte = screen_width / bytes_per_row; if (bytes_per_row <= mainBuffer.pageSize) { - const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte; - const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte; + const size_t a0 = (size_t)mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte; + const size_t a1 = (size_t)mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte; vosf_do_set_dirty_area(a0, a1); } else { for (int j = y; j < y + h; j++) { - const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte; - const uintptr a1 = mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte; + const size_t a0 = (size_t)mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte; + const size_t a1 = (size_t)mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte; vosf_do_set_dirty_area(a0, a1); } } @@ -420,25 +418,23 @@ static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_widt UNLOCK_VOSF; } - /* * Screen fault handler */ -bool Screen_fault_handler(sigsegv_info_t *sip) -{ - const uintptr addr = (uintptr)sigsegv_get_fault_address(sip); +bool Screen_fault_handler(sigsegv_info_t* sip){ + const size_t addr = (size_t)sigsegv_get_fault_address(sip); /* Someone attempted to write to the frame buffer. Make it writeable * now so that the data could actually be written to. It will be made * read-only back in one of the screen update_*() functions. */ - if (((uintptr)addr - mainBuffer.memStart) < mainBuffer.memLength) { - const int page = ((uintptr)addr - mainBuffer.memStart) >> mainBuffer.pageBits; + if ((addr - (size_t)mainBuffer.memStart) < mainBuffer.memLength) { + const int page = (addr - (size_t)mainBuffer.memStart) >> mainBuffer.pageBits; LOCK_VOSF; if (PFLAG_ISCLEAR(page)) { PFLAG_SET(page); - vm_protect((char *)(addr & ~(mainBuffer.pageSize - 1)), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); + vm_protect((char*)(addr & ~(mainBuffer.pageSize - 1)), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); } mainBuffer.dirty = true; UNLOCK_VOSF; diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index cb30a3be9..7beb229b2 100755 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -61,21 +61,14 @@ typedef UINT_PTR vm_uintptr_t; typedef unsigned long vm_uintptr_t; #endif -/* We want MAP_32BIT, if available, for SheepShaver and BasiliskII - because the emulated target is 32-bit and this helps to allocate - memory so that branches could be resolved more easily (32-bit - displacement to code in .text), on AMD64 for example. */ +/* FIXME: make JIT 64bit clean */ #if defined(__hpux) #define MAP_32BIT MAP_ADDR32 #endif #ifndef MAP_32BIT #define MAP_32BIT 0 #endif -#ifdef __FreeBSD__ -#define FORCE_MAP_32BIT MAP_FIXED -#else #define FORCE_MAP_32BIT MAP_32BIT -#endif #ifndef MAP_ANON #define MAP_ANON 0 #endif @@ -83,41 +76,16 @@ typedef unsigned long vm_uintptr_t; #define MAP_ANONYMOUS 0 #endif -/* NOTE: on linux MAP_32BIT is only implemented on AMD64 - it is a null op on all other architectures - thus the MAP_BASE setting below is the only thing - ensuring low addresses on aarch64 for example */ -#define MAP_EXTRA_FLAGS (MAP_32BIT) - #ifdef HAVE_MMAP_VM -#if (defined(__linux__) && defined(__i386__)) || defined(__FreeBSD__) || HAVE_LINKER_SCRIPT -/* Force a reasonnable address below 0x80000000 on x86 so that we - don't get addresses above when the program is run on AMD64. - NOTE: this is empirically determined on Linux/x86. */ -#define MAP_BASE 0x10000000 -#elif DIRECT_ADDRESSING -/* linux does not implement any useful fallback behavior - such as allocating the next available address - and the first 4k-64k of address space is marked unavailable - for security reasons (see https://wiki.debian.org/mmap_min_addr) - so we must start requesting after the first page - or we get a high 64bit address that will crash direct addressing - - leaving NULL unmapped is a good idea anyway for debugging reasons */ -#define MAP_BASE 0x00010000 -#else -#define MAP_BASE 0x00000000 -#endif -static char * next_address = (char *)MAP_BASE; #ifdef HAVE_MMAP_ANON -#define map_flags (MAP_ANON | MAP_EXTRA_FLAGS) +#define map_flags (MAP_ANON) #define zero_fd -1 #else #ifdef HAVE_MMAP_ANONYMOUS -#define map_flags (MAP_ANONYMOUS | MAP_EXTRA_FLAGS) +#define map_flags (MAP_ANONYMOUS) #define zero_fd -1 #else -#define map_flags (MAP_EXTRA_FLAGS) +#define map_flags (0) static int zero_fd = -1; #endif #endif @@ -126,8 +94,7 @@ static int zero_fd = -1; /* Translate generic VM map flags to host values. */ #ifdef HAVE_MMAP_VM -static int translate_map_flags(int vm_flags) -{ +static int translate_map_flags(int vm_flags){ int flags = 0; if (vm_flags & VM_MAP_SHARED) flags |= MAP_SHARED; @@ -238,8 +205,8 @@ void vm_exit(void) and default protection bits are read / write. The return value is the actual mapping address chosen or VM_MAP_FAILED for errors. */ -void * vm_acquire(size_t size, int options){ - void * addr; +void* vm_acquire(size_t size, int options){ + void* addr=NULL; errno = 0; #ifndef HAVE_VM_WRITE_WATCH @@ -258,19 +225,16 @@ void * vm_acquire(size_t size, int options){ int fd = zero_fd; int the_map_flags = translate_map_flags(options) | map_flags; - if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED) + printf("mmap addr=%p size=%p flags=%p\n",addr,size,the_map_flags); + if ((addr = mmap(addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0))==(void*)MAP_FAILED) return VM_MAP_FAILED; - printf("next=%p got=%p size=%p\n",next_address,addr,size); - -#if DIRECT_ADDRESSING - // If MAP_32BIT and MAP_BASE fail to ensure - // a 32-bit address crash now instead of later. - // FIXME: make everything 64-bit clean and tear this all out. + printf("mmap got=%p\n",addr); + + // If MAP_32BIT fails to ensure a 32bit address, crash now instead of later. + // FIXME: Make JIT 64bit clean and tear all this VM_MAP_32BIT hackery out. if(sizeof(void *) > 4 && (options & VM_MAP_32BIT)) assert((size_t)addr<0xffffffffL); -#endif - next_address = (char *)addr + size; #elif defined(HAVE_WIN32_VM) int alloc_type = MEM_RESERVE | MEM_COMMIT; if (options & VM_MAP_WRITE_WATCH) diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index bf829c02f..0b2cbcad2 100755 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -171,8 +171,7 @@ static sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip) * Dump state when everything went wrong after a SEGV */ -static void sigsegv_dump_state(sigsegv_info_t *sip) -{ +static void sigsegv_dump_state(sigsegv_info_t *sip){ const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip); const sigsegv_address_t fault_instruction = sigsegv_get_fault_instruction_address(sip); fprintf(stderr, "Caught SIGSEGV at address %p", fault_address); @@ -199,7 +198,6 @@ static void sigsegv_dump_state(sigsegv_info_t *sip) QuitEmulator(); } - /* * Update virtual clock and trigger interrupts if necessary */ @@ -404,6 +402,14 @@ int main(int argc, char **argv){ } } + // Init system routines + SysInit(); + + // Show preferences editor + if (!gui_connection && !PrefsFindBool("nogui")) + if (!PrefsEditor()) + QuitEmulator(); + #ifdef USE_SDL // Initialize SDL system int sdl_flags = 0; @@ -435,14 +441,6 @@ int main(int argc, char **argv){ #endif - // Init system routines - SysInit(); - - // Show preferences editor - if (!gui_connection && !PrefsFindBool("nogui")) - if (!PrefsEditor()) - QuitEmulator(); - // Install the handler for SIGSEGV if (!sigsegv_install_handler(sigsegv_handler)) { sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIGSEGV", strerror(errno)); @@ -463,9 +461,6 @@ int main(int argc, char **argv){ QuitEmulator(); D(bug("Initialization complete\n")); - D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); - D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); - #ifdef ENABLE_MON // Setup SIGINT handler to enter mon sigemptyset(&sigint_sa.sa_mask); @@ -618,24 +613,6 @@ void QuitEmulator(void) exit(0); } - -/* - * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 - * or a dynamically recompiling emulator) - */ - -void FlushCodeCache(void *start, uint32 size){ -#if USE_JIT - if (UseJIT) -#ifdef UPDATE_UAE - flush_icache(); -#else - flush_icache_range((uint8 *)start, size); -#endif -#endif -} - - /* * SIGINT handler, enters mon */ diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index 4e330ad53..4f0481d9a 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -33,6 +33,8 @@ # include #endif +#include + #include #include #include diff --git a/BasiliskII/src/main.cpp b/BasiliskII/src/main.cpp index 469a3f284..37484db6a 100644 --- a/BasiliskII/src/main.cpp +++ b/BasiliskII/src/main.cpp @@ -42,11 +42,6 @@ #define DEBUG 0 #include "debug.h" -// CPU and FPU type, addressing mode -int CPUType; -int FPUType; -bool TwentyFourBitAddressing; - #if ENABLE_MON #include "mon.h" @@ -59,6 +54,11 @@ static void mon_write_byte_b2(uintptr adr, uint32 b){ } #endif +// CPU and FPU type, addressing mode +int CPUType; +int FPUType; +bool TwentyFourBitAddressing; + /* * Initialize everything, returns false on error */ diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index c815ccb94..700d5d43e 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -37,22 +37,22 @@ #include "debug.h" #if DIRECT_ADDRESSING -uintptr MEMBaseDiff = 0; // Global offset between a Mac address and its Host equivalent +size_t MEMBaseDiff = 0; // Global offset between a Mac address and its Host equivalent #endif // RAM and ROM pointers -uint8* RAMBaseHost = 0; // RAM base (host address space) -uint8* ROMBaseHost = 0; // ROM base (host address space) -uint32 RAMBaseMac = 0; // RAM base (Mac address space) -uint32 ROMBaseMac = 0; // ROM base (Mac address space) -uint32 RAMSize = 0; // Size of RAM -uint32 ROMSize = 0; // Size of ROM +uint8* RAMBaseHost = 0; // RAM base (host address space) +uint8* ROMBaseHost = 0; // ROM base (host address space) +const uint32 RAMBaseMac = 0; // RAM base (Mac address space) +uint32 ROMBaseMac = 0; // ROM base (Mac address space) +uint32 RAMSize = 0; // Size of RAM +uint32 ROMSize = 0; // Size of ROM // Mac frame buffer -uint8* MacFrameBaseHost; // Frame buffer base (host address space) -uint32 MacFrameSize; // Size of current frame buffer -int MacFrameLayout; // Frame buffer layout -uint32 VRAMSize; // Size of VRAM +uint8* MacFrameBaseHost = 0; // Frame buffer base (host address space) +uint32 MacFrameSize = 0; // Size of current frame buffer +int MacFrameLayout = 0; // Frame buffer layout +uint32 VRAMSize = 0; // Size of VRAM uint32 JITCacheSize=0; @@ -66,10 +66,6 @@ int ScratchMemSize = 64*1024; // 64k int ScratchMemSize = 0; #endif -#if USE_JIT -bool UseJIT = false; -#endif - // From newcpu.cpp extern bool quit_program; @@ -93,7 +89,8 @@ bool InitMacMem(void){ VRAMSize = 16*1024*1024; // 16mb, more than enough for 1920x1440x32 #if USE_JIT - JITCacheSize = 1024*PrefsFindInt32("jitcachesize") + 1024; + JITCacheSize = compiler_get_jit_cache_size(); + printf("JITCacheSize=%p\n",JITCacheSize); #endif // Initialize VM system @@ -102,7 +99,11 @@ bool InitMacMem(void){ // Create our virtual Macintosh memory map RAMBaseHost = (uint8*)vm_acquire( RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize, - VM_MAP_DEFAULT | VM_MAP_32BIT); +#if USE_JIT + // FIXME: JIT is not 64bit clean + ((JITCacheSize>0)?VM_MAP_32BIT:0)| +#endif + VM_MAP_DEFAULT); if (RAMBaseHost == VM_MAP_FAILED) { ErrorAlert(STR_NO_MEM_ERR); return false; @@ -167,7 +168,7 @@ bool InitMacMem(void){ if (ReadFile(rom_fh, ROMBaseHost, ROMSize, &bytes_read, NULL) == 0 || bytes_read != ROMSize) { #else lseek(rom_fd, 0, SEEK_SET); - if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) { + if (read(rom_fd, ROMBaseHost, ROMSize) != ROMSize) { #endif ErrorAlert(STR_ROM_FILE_READ_ERR); #ifdef WIN32 @@ -185,7 +186,7 @@ bool InitMacMem(void){ #if DIRECT_ADDRESSING // Mac address space = host address space minus constant offset (MEMBaseDiff) - MEMBaseDiff = (uintptr)RAMBaseHost; + MEMBaseDiff = (size_t)RAMBaseHost; ROMBaseMac = Host2MacAddr(ROMBaseHost); #else // Initialize UAE memory banks @@ -229,23 +230,20 @@ void MacMemExit(void){ bool Init680x0(void){ init_m68k(); #if USE_JIT - UseJIT = compiler_use_jit(); - if (UseJIT) - compiler_init(MacFrameBaseHost + VRAMSize); + if(JITCacheSize>0) + compiler_init(MacFrameBaseHost + VRAMSize, JITCacheSize); // put JIT cache after VRAM #endif return true; } - /* * Deinitialize 680x0 emulation */ -void Exit680x0(void) -{ +void Exit680x0(void){ #if USE_JIT - if (UseJIT) - compiler_exit(); + if(JITCacheSize>0) + compiler_exit(); #endif exit_m68k(); } @@ -254,18 +252,16 @@ void Exit680x0(void) * Reset and start 680x0 emulation (doesn't return) */ -void Start680x0(void) -{ +void Start680x0(void){ m68k_reset(); #if USE_JIT - if (UseJIT) - m68k_compile_execute(); - else + if (JITCacheSize>0) + m68k_compile_execute(); + else #endif m68k_execute(); } - /* * Trigger interrupt */ @@ -383,3 +379,19 @@ void Execute68k(uint32 addr, struct M68kRegisters *r) r->a[i] = m68k_areg(regs, i); quit_program = false; } + +#if USE_JIT +extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp +#endif + +/* + * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 + * or a dynamically recompiling emulator) + */ + +void FlushCodeCache(void *start, uint32 size){ +#if USE_JIT + if (JITCacheSize>0) + flush_icache_range((uint8 *)start, size); +#endif +} diff --git a/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp b/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp index f03c4f3cf..e78212c94 100644 --- a/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp +++ b/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp @@ -3841,10 +3841,9 @@ x86_get_cpu_vendor(struct cpuinfo_x86 *c) } static void -cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx) -{ +cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx){ const int CPUID_SPACE = 4096; - uae_u8* cpuid_space = (uae_u8 *)vm_acquire(CPUID_SPACE); + uae_u8* cpuid_space = (uae_u8 *)vm_acquire(CPUID_SPACE,VM_MAP_DEFAULT|VM_MAP_32BIT); if (cpuid_space == VM_MAP_FAILED) abort(); vm_protect(cpuid_space, CPUID_SPACE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE); diff --git a/BasiliskII/src/uae_cpu/compiler/compemu.h b/BasiliskII/src/uae_cpu/compiler/compemu.h index daad5b209..ce1014a65 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu.h +++ b/BasiliskII/src/uae_cpu/compiler/compemu.h @@ -139,9 +139,9 @@ union cacheline { /* Functions exposed to newcpu, or to what was moved from newcpu.c to * compemu_support.c */ -extern void compiler_init(void*); +extern void compiler_init(void*,int); extern void compiler_exit(void); -extern bool compiler_use_jit(void); +extern uint32 compiler_get_jit_cache_size(void); extern void init_comp(void); extern void flush(int save_regs); extern void small_flush(int save_regs); diff --git a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp index 04f990ea3..ae8f7ab47 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp +++ b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp @@ -5003,12 +5003,13 @@ static inline const char *str_on_off(bool b) return b ? "on" : "off"; } -void compiler_init(void* buf){ +void compiler_init(void* buf, int JITCacheSize){ static bool initialized = false; if (initialized) return; compiled_code=(uint8*)buf; + cache_size=JITCacheSize; #if JIT_DEBUG // JIT debug mode ? @@ -5025,10 +5026,6 @@ void compiler_init(void* buf){ #endif write_log(" : compile FPU instructions : %s\n", !avoid_fpu ? "yes" : "no"); - // Get size of the translation cache (in KB) - cache_size = PrefsFindInt32("jitcachesize"); - write_log(" : requested translation cache size : %d KB\n", cache_size); - // Initialize target CPU (check for features, e.g. CMOV, rat stalls) raw_init_cpu(); setzflg_uses_bsf = target_check_bsf(); @@ -5123,25 +5120,29 @@ void compiler_exit(void){ #endif } -bool compiler_use_jit(void) -{ +// Return bytes needed for JIT cache +uint32 compiler_get_jit_cache_size(void){ // Check for the "jit" prefs item if (!PrefsFindBool("jit")) - return false; + return 0; // Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB - if (PrefsFindInt32("jitcachesize") < MIN_CACHE_SIZE) { + uint32 JITCacheSize=PrefsFindInt32("jitcachesize"); + if (JITCacheSize < MIN_CACHE_SIZE) { write_log(" : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE); - return false; + return 0; } - + +#if 0 // Enable JIT for 68020+ emulation only if (CPUType < 2) { write_log(" : JIT is not supported in 680%d0 emulation mode, disabling.\n", CPUType); - return false; + return 0; } +#endif - return true; + write_log(" : translation cache size : %d KB\n", JITCacheSize); + return (1024*JITCacheSize) + POPALLSPACE_SIZE; } void init_comp(void) @@ -5635,10 +5636,6 @@ void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp) forget_about(tmp); } - - - - void set_cache_state(int enabled) { if (enabled!=letit) @@ -5658,35 +5655,19 @@ uae_u32 get_jitted_size(void) return 0; } -const int CODE_ALLOC_MAX_ATTEMPTS = 10; -const int CODE_ALLOC_BOUNDARIES = 128 * 1024; // 128 KB - -static inline uint8 *alloc_code(uint32 size){ - uint8 *ptr = (uint8 *)vm_acquire(size); - ptr == VM_MAP_FAILED ? NULL : ptr; - /* allocated code must fit in 32-bit boundaries */ - assert((size_t)ptr<0xffffffffL); - return ptr; -} - void alloc_cache(void){ assert(compiled_code); - - if (cache_size == 0) - return; + assert(cache_size); vm_protect(compiled_code, cache_size * 1024, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE); if (compiled_code) { - write_log(" : actual translation cache size : %d KB at 0x%08X\n", cache_size, compiled_code); max_compile_start = compiled_code + cache_size*1024 - BYTES_PER_INST; current_compile_p = compiled_code; current_cache_size = 0; } } - - extern void op_illg_1 (uae_u32 opcode) REGPARAM; static void calc_checksum(blockinfo* bi, uae_u32* c1, uae_u32* c2) diff --git a/BasiliskII/src/uae_cpu/cpu_emulation.h b/BasiliskII/src/uae_cpu/cpu_emulation.h index af17ad2cc..b1713d45c 100644 --- a/BasiliskII/src/uae_cpu/cpu_emulation.h +++ b/BasiliskII/src/uae_cpu/cpu_emulation.h @@ -23,18 +23,17 @@ #include - /* * Memory system */ // RAM and ROM pointers (allocated and set by main_*.cpp) -extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0 -extern uint8 *RAMBaseHost; // RAM base (host address space) +extern const uint32 RAMBaseMac; // RAM base (Mac address space) +extern uint8* RAMBaseHost; // RAM base (host address space) extern uint32 RAMSize; // Size of RAM extern uint32 ROMBaseMac; // ROM base (Mac address space) -extern uint8 *ROMBaseHost; // ROM base (host address space) +extern uint8* ROMBaseHost; // ROM base (host address space) extern uint32 ROMSize; // Size of ROM extern uint32 VRAMSize; // Size of VRAM @@ -42,8 +41,8 @@ extern uint32 VRAMSize; // Size of VRAM // If we are not using direct addressing, the Mac frame buffer gets // mapped to this location. The memory must be allocated by VideoInit(). // If multiple monitors are used, they must share the frame buffer -const uint32 MacFrameBaseMac = 0xa0000000; -extern uint8 *MacFrameBaseHost; // Frame buffer base (host address space) +const uint32 MacFrameBaseMac = 0xa0000000; +extern uint8* MacFrameBaseHost; // Frame buffer base (host address space) extern uint32 MacFrameSize; // Size of frame buffer #endif extern int MacFrameLayout; // Frame buffer layout (see defines below) diff --git a/BasiliskII/src/uae_cpu/memory.cpp b/BasiliskII/src/uae_cpu/memory.cpp index 955e0a607..5863ab4da 100644 --- a/BasiliskII/src/uae_cpu/memory.cpp +++ b/BasiliskII/src/uae_cpu/memory.cpp @@ -136,7 +136,7 @@ static void REGPARAM2 ram_wput(uaecptr, uae_u32) REGPARAM; static void REGPARAM2 ram_bput(uaecptr, uae_u32) REGPARAM; static uae_u8 *REGPARAM2 ram_xlate(uaecptr addr) REGPARAM; -static uintptr RAMBaseDiff; // RAMBaseHost - RAMBaseMac +static size_t RAMBaseDiff; // RAMBaseHost - RAMBaseMac uae_u32 REGPARAM2 ram_lget(uaecptr addr) { @@ -244,7 +244,7 @@ static void REGPARAM2 rom_wput(uaecptr, uae_u32) REGPARAM; static void REGPARAM2 rom_bput(uaecptr, uae_u32) REGPARAM; static uae_u8 *REGPARAM2 rom_xlate(uaecptr addr) REGPARAM; -static uintptr ROMBaseDiff; // ROMBaseHost - ROMBaseMac +static size_t ROMBaseDiff; // ROMBaseHost - ROMBaseMac uae_u32 REGPARAM2 rom_lget(uaecptr addr) { @@ -343,7 +343,7 @@ static void REGPARAM2 frame_host_888_lput(uaecptr, uae_u32) REGPARAM; static uae_u8 *REGPARAM2 frame_xlate(uaecptr addr) REGPARAM; -static uintptr FrameBaseDiff; // MacFrameBaseHost - MacFrameBaseMac +static size_t FrameBaseDiff; // MacFrameBaseHost - MacFrameBaseMac uae_u32 REGPARAM2 frame_direct_lget(uaecptr addr) { @@ -585,12 +585,12 @@ void memory_init(void){ for(long i=0; i<65536; i++) put_mem_bank(i<<16, &dummy_bank); - // RAM must not overlap ROM - assert(RAMSize ROMBaseMac ? ROMBaseMac : RAMSize; - RAMBaseDiff = (uintptr)RAMBaseHost - (uintptr)RAMBaseMac; - ROMBaseDiff = (uintptr)ROMBaseHost - (uintptr)ROMBaseMac; - FrameBaseDiff = (uintptr)MacFrameBaseHost - (uintptr)MacFrameBaseMac; + RAMBaseDiff = (size_t)RAMBaseHost - RAMBaseMac; + ROMBaseDiff = (size_t)ROMBaseHost - ROMBaseMac; + FrameBaseDiff = (size_t)MacFrameBaseHost - MacFrameBaseMac; // Map RAM, ROM and display if (TwentyFourBitAddressing) { diff --git a/BasiliskII/src/uae_cpu/memory.h b/BasiliskII/src/uae_cpu/memory.h index d78981660..8a3da5f32 100644 --- a/BasiliskII/src/uae_cpu/memory.h +++ b/BasiliskII/src/uae_cpu/memory.h @@ -118,7 +118,7 @@ extern void byteput(uaecptr addr, uae_u32 b); #endif /* !DIRECT_ADDRESSING */ #if DIRECT_ADDRESSING -extern uintptr MEMBaseDiff; +extern size_t MEMBaseDiff; static __inline__ uae_u8 *do_get_real_address(uaecptr addr) { @@ -126,7 +126,7 @@ static __inline__ uae_u8 *do_get_real_address(uaecptr addr) } static __inline__ uae_u32 do_get_virtual_address(uae_u8 *addr) { - return (uintptr)addr - MEMBaseDiff; + return (size_t)addr - MEMBaseDiff; } static __inline__ uae_u32 get_long(uaecptr addr) { From 856a58ef61392173fa95f0dfcb26637ef8617ba7 Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 12 Jun 2021 18:09:24 -0700 Subject: [PATCH 13/24] Remove debug --- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 2 -- BasiliskII/src/uae_cpu/basilisk_glue.cpp | 5 ----- 2 files changed, 7 deletions(-) diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index 7beb229b2..c85835905 100755 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -225,10 +225,8 @@ void* vm_acquire(size_t size, int options){ int fd = zero_fd; int the_map_flags = translate_map_flags(options) | map_flags; - printf("mmap addr=%p size=%p flags=%p\n",addr,size,the_map_flags); if ((addr = mmap(addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0))==(void*)MAP_FAILED) return VM_MAP_FAILED; - printf("mmap got=%p\n",addr); // If MAP_32BIT fails to ensure a 32bit address, crash now instead of later. // FIXME: Make JIT 64bit clean and tear all this VM_MAP_32BIT hackery out. diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index 700d5d43e..680f15359 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -90,7 +90,6 @@ bool InitMacMem(void){ #if USE_JIT JITCacheSize = compiler_get_jit_cache_size(); - printf("JITCacheSize=%p\n",JITCacheSize); #endif // Initialize VM system @@ -108,16 +107,12 @@ bool InitMacMem(void){ ErrorAlert(STR_NO_MEM_ERR); return false; } - printf("RAMBaseHost=%p\n",RAMBaseHost); ROMBaseHost = RAMBaseHost + RAMSize + ScratchMemSize; - printf("ROMBaseHost=%p\n",ROMBaseHost); MacFrameBaseHost = ROMBaseHost + MAX_ROM_SIZE; - printf("MacFrameBaseHost=%p\n",MacFrameBaseHost); #if USE_SCRATCHMEM_SUBTERFUGE // points to middle of scratch memory ScratchMem = RAMBaseHost + RAMSize + ScratchMemSize/2; - printf("ScratchMem=%p\n",ScratchMem); #endif // Get rom file path from preferences From b0ef509c082db29dc0e689e4ad45d26699427fad Mon Sep 17 00:00:00 2001 From: Seg Date: Wed, 16 Jun 2021 21:58:14 -0700 Subject: [PATCH 14/24] Remove legacy APIs from SheepShaver --- SheepShaver/src/Unix/Irix/audio_irix.cpp | 1 - SheepShaver/src/Unix/audio_oss_esd.cpp | 1 - SheepShaver/src/Unix/configure.ac | 89 +- SheepShaver/src/Unix/main_unix.cpp | 71 +- SheepShaver/src/Unix/prefs_editor_gtk.cpp | 10 +- SheepShaver/src/Unix/video_x.cpp | 2584 --------------------- 6 files changed, 8 insertions(+), 2748 deletions(-) delete mode 120000 SheepShaver/src/Unix/Irix/audio_irix.cpp delete mode 120000 SheepShaver/src/Unix/audio_oss_esd.cpp delete mode 100644 SheepShaver/src/Unix/video_x.cpp diff --git a/SheepShaver/src/Unix/Irix/audio_irix.cpp b/SheepShaver/src/Unix/Irix/audio_irix.cpp deleted file mode 120000 index 2e7ef88f4..000000000 --- a/SheepShaver/src/Unix/Irix/audio_irix.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../../BasiliskII/src/Unix/Irix/audio_irix.cpp \ No newline at end of file diff --git a/SheepShaver/src/Unix/audio_oss_esd.cpp b/SheepShaver/src/Unix/audio_oss_esd.cpp deleted file mode 120000 index acf070c11..000000000 --- a/SheepShaver/src/Unix/audio_oss_esd.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/Unix/audio_oss_esd.cpp \ No newline at end of file diff --git a/SheepShaver/src/Unix/configure.ac b/SheepShaver/src/Unix/configure.ac index a8d1a007a..c65217eb5 100755 --- a/SheepShaver/src/Unix/configure.ac +++ b/SheepShaver/src/Unix/configure.ac @@ -31,12 +31,8 @@ esac dnl Options. AC_ARG_ENABLE(jit, [ --enable-jit enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes]) AC_ARG_ENABLE(ppc-emulator, [ --enable-ppc-emulator use the selected PowerPC emulator [default=auto]], [WANT_EMULATED_PPC=$enableval], [WANT_EMULATED_PPC=auto]) -AC_ARG_ENABLE(fbdev-dga, [ --enable-fbdev-dga use direct frame buffer access via /dev/fb0 [default=yes]], [WANT_FBDEV_DGA=$enableval], [WANT_FBDEV_DGA=yes]) -AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) -AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=no]], [WANT_VOSF=$enableval], [WANT_VOSF=no]) AC_ARG_ENABLE(standalone-gui,[ --enable-standalone-gui enable a standalone GUI prefs editor [default=no]], [WANT_STANDALONE_GUI=$enableval], [WANT_STANDALONE_GUI=no]) -AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes]) AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [case "$withval" in gtk1) WANT_GTK="gtk";; @@ -177,9 +173,6 @@ dnl Do we need SDL? WANT_SDL=no if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then WANT_SDL=yes - WANT_XF86_DGA=no - WANT_XF86_VIDMODE=no - WANT_FBDEV_DGA=no SDL_SUPPORT="$SDL_SUPPORT video" fi if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then @@ -254,19 +247,6 @@ else SDL_SUPPORT="none" fi -dnl We need X11, if not using SDL. -if [[ "x$WANT_SDL_VIDEO" != "xyes" ]]; then - AC_PATH_XTRA - if [[ "x$no_x" = "xyes" ]]; then - AC_MSG_ERROR([You need X11 to run SheepShaver.]) - fi - CFLAGS="$CFLAGS $X_CFLAGS" - CXXFLAGS="$CXXFLAGS $X_CFLAGS" - LIBS="$LIBS $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS" -fi - - - dnl We need pthreads on non-PowerPC systems. Try libpthread first, then libc_r (FreeBSD), then PTL. HAVE_PTHREADS=yes case $EMULATED_PPC:$target_os in @@ -302,38 +282,6 @@ if [[ "x$HAVE_PTHREADS" = "xyes" ]]; then AC_DEFINE(HAVE_PTHREADS, 1, [Define if pthreads are available.]) fi -dnl We use FBDev DGA if possible. -if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then - AC_CHECK_HEADER(linux/fb.h, [ - AC_DEFINE(ENABLE_FBDEV_DGA, 1, [Define if using Linux fbdev extension.]) - ], [ - AC_MSG_WARN([Could not find Linux FBDev extension, ignoring --enable-fbdev-dga.]) - WANT_FBDEV_DGA=no - ]) -fi - -dnl We use XFree86 DGA if possible. -if [[ "x$WANT_XF86_DGA" = "xyes" ]]; then - AC_CHECK_LIB(Xxf86dga, XF86DGAQueryExtension, [ - AC_DEFINE(ENABLE_XF86_DGA, 1, [Define if using XFree86 DGA extension.]) - LIBS="$LIBS -lXxf86dga" - ], [ - AC_MSG_WARN([Could not find XFree86 DGA extension, ignoring --enable-xf86-dga.]) - WANT_XF86_DGA=no - ]) -fi - -dnl We use XFree86 VidMode if possible. -if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then - AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, [ - AC_DEFINE(ENABLE_XF86_VIDMODE, 1, [Define if using XFree86 DGA extension.]) - LIBS="$LIBS -lXxf86vm" - ], [ - AC_MSG_WARN([Could not find XFree86 VidMode extension, ignoring --enable-xf86-vidmode.]) - WANT_XF86_VIDMODE=no - ]) -fi - dnl We use GTK+ if possible. UISRCS=../dummy/prefs_editor_dummy.cpp case "x$WANT_GTK" in @@ -383,20 +331,6 @@ if [[ "$WANT_GTK" = "no" ]]; then fi AC_SUBST(STANDALONE_GUI, [$WANT_STANDALONE_GUI]) -dnl We use ESD if possible. -if [[ "x$WANT_ESD" = "xyes" ]]; then - WANT_ESD=no - AM_PATH_ESD(0.2.8, [ - AC_DEFINE(ENABLE_ESD, 1, [Define is using ESD.]) - CFLAGS="$CFLAGS $ESD_CFLAGS" - CXXFLAGS="$CXXFLAGS $ESD_CFLAGS" - LIBS="$LIBS $ESD_LIBS" - WANT_ESD=yes - ], [ - AC_MSG_WARN([Could not find ESD, disabling ESD support.]) - ]) -fi - dnl We use 64-bit file size support if possible. AC_SYS_LARGEFILE @@ -637,7 +571,6 @@ EXTRASYSSRCS= case "$target_os" in linux*) ETHERSRC=ether_unix.cpp - AUDIOSRC=audio_oss_esd.cpp SCSISRC=Linux/scsi_linux.cpp if [[ "x$EMULATED_PPC" = "xno" ]]; then EXTRASYSSRCS="paranoia.cpp Linux/sheepthreads.c ppc_asm.S" @@ -667,27 +600,11 @@ darwin*) CPPFLAGS="$CPPFLAGS -I../MacOSX/Launcher" fi fi - if [[ "x$WANT_ESD" = "xno" -a "x$ac_cv_framework_CoreAudio" = "xyes" -a "x$WANT_SDL_AUDIO" = "xno" ]]; then + if [[ "x$ac_cv_framework_CoreAudio" = "xyes" -a "x$WANT_SDL_AUDIO" = "xno" ]]; then AUDIOSRC="../MacOSX/audio_macosx.cpp ../MacOSX/AudioBackEnd.cpp ../MacOSX/AudioDevice.cpp ../MacOSX/MacOSX_sound_if.cpp" OSX_CORE_AUDIO="-DOSX_CORE_AUDIO" fi ;; -irix*) - AUDIOSRC=Irix/audio_irix.cpp - LIBS="$LIBS -laudio" - WANT_ESD=no - - dnl Check if our compiler supports -IPA (MIPSPro) - HAVE_IPA=no - ocflags="$CFLAGS" - CFLAGS=`echo " $CFLAGS -IPA" | sed -e "s/ -g //g"` - AC_MSG_CHECKING(if "-IPA" works) - dnl Do a test compile of an empty function - AC_TRY_COMPILE([#if defined __GNUC__ - # error GCC does not support IPA yet - #endif],, [AC_MSG_RESULT(yes); HAVE_IPA=yes], AC_MSG_RESULT(no)) - CFLAGS="$ocflags" - ;; esac dnl BINCUE @@ -1744,13 +1661,9 @@ echo SDL support ...................... : $SDL_SUPPORT echo SDL major-version ................ : $WANT_SDL_VERSION_MAJOR echo BINCUE support ................... : $have_bincue echo LIBVHD support ................... : $have_libvhd -echo FBDev DGA support ................ : $WANT_FBDEV_DGA -echo XFree86 DGA support .............. : $WANT_XF86_DGA -echo XFree86 VidMode support .......... : $WANT_XF86_VIDMODE echo Using PowerPC emulator ........... : $EMULATED_PPC echo Enable JIT compiler .............. : $WANT_JIT echo Enable video on SEGV signals ..... : $WANT_VOSF -echo ESD sound support ................ : $WANT_ESD echo GTK user interface ............... : $WANT_GTK echo mon debugger support ............. : $WANT_MON echo Addressing mode .................. : $WANT_ADDRESSING_MODE diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index 94bb47862..0771f5671 100755 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -125,21 +125,8 @@ #include #endif -#ifndef USE_SDL_VIDEO -#include -#endif - #ifdef ENABLE_GTK #include -#if !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND) -#include -#endif -#endif - -#ifdef ENABLE_XF86_DGA -#include -#include -#include #endif #ifdef ENABLE_MON @@ -199,14 +186,6 @@ uint8 gZeroPage[0x3000], gKernelData[0x2000]; #endif // Global variables -#ifndef USE_SDL_VIDEO -char *x_display_name = NULL; // X11 display name -Display *x_display = NULL; // X11 display handle -#ifdef X11_LOCK_TYPE -X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT; // X11 display lock -#endif -#endif - static int zero_fd = 0; // FD of /dev/zero static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped static bool rom_area_mapped = false; // Flag: Mac ROM mmap()ped @@ -680,8 +659,7 @@ static bool install_signal_handlers(void) static std::string sdl_vmdir; -static bool init_sdl() -{ +static bool init_sdl(){ int sdl_flags = 0; #ifdef USE_SDL_VIDEO sdl_flags |= SDL_INIT_VIDEO; @@ -727,11 +705,7 @@ static bool init_sdl() } #endif -int main(int argc, char **argv) -{ -#if defined(ENABLE_GTK) && !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND) - XInitThreads(); -#endif +int main(int argc, char **argv){ char str[256]; bool memory_mapped_from_zero, ram_rom_areas_contiguous; const char *vmdir = NULL; @@ -782,12 +756,6 @@ int main(int argc, char **argv) argv[i] = NULL; } else if (strcmp(argv[i], "--help") == 0) { usage(argv[0]); -#ifndef USE_SDL_VIDEO - } else if (strcmp(argv[i], "--display") == 0) { - i++; - if (i < argc) - x_display_name = strdup(argv[i]); -#endif } else if (strcmp(argv[i], "--gui-connection") == 0) { argv[i++] = NULL; if (i < argc) { @@ -858,22 +826,6 @@ int main(int argc, char **argv) } } -#ifndef USE_SDL_VIDEO - // Open display - x_display = XOpenDisplay(x_display_name); - if (x_display == NULL) { - char str[256]; - sprintf(str, GetString(STR_NO_XSERVER_ERR), XDisplayName(x_display_name)); - ErrorAlert(str); - goto quit; - } - -#if defined(ENABLE_XF86_DGA) && !defined(ENABLE_MON) - // Fork out, so we can return from fullscreen mode when things get ugly - XF86DGAForkApp(DefaultScreen(x_display)); -#endif -#endif - #ifdef ENABLE_MON // Initialize mon mon_init(); @@ -1200,12 +1152,6 @@ static void Quit(void) mon_exit(); #endif - // Close X11 server connection -#ifndef USE_SDL_VIDEO - if (x_display) - XCloseDisplay(x_display); -#endif - // Notify GUI we are about to leave if (gui_connection) { if (rpc_method_invoke(gui_connection, RPC_METHOD_EXIT, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR) @@ -2303,20 +2249,18 @@ void display_alert(int title_id, int prefix_id, int button_id, const char *text) } #endif - /* * Display error alert */ -void ErrorAlert(const char *text) -{ +void ErrorAlert(const char *text){ if (gui_connection) { if (rpc_method_invoke(gui_connection, RPC_METHOD_ERROR_ALERT, RPC_TYPE_STRING, text, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR && rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR) return; } #if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO) - if (PrefsFindBool("nogui") || x_display == NULL) { + if (PrefsFindBool("nogui")) { printf(GetString(STR_SHELL_ERROR_PREFIX), text); return; } @@ -2327,20 +2271,18 @@ void ErrorAlert(const char *text) #endif } - /* * Display warning alert */ -void WarningAlert(const char *text) -{ +void WarningAlert(const char *text){ if (gui_connection) { if (rpc_method_invoke(gui_connection, RPC_METHOD_WARNING_ALERT, RPC_TYPE_STRING, text, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR && rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR) return; } #if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO) - if (PrefsFindBool("nogui") || x_display == NULL) { + if (PrefsFindBool("nogui")) { printf(GetString(STR_SHELL_WARNING_PREFIX), text); return; } @@ -2350,7 +2292,6 @@ void WarningAlert(const char *text) #endif } - /* * Display choice alert */ diff --git a/SheepShaver/src/Unix/prefs_editor_gtk.cpp b/SheepShaver/src/Unix/prefs_editor_gtk.cpp index b092e8241..81b16f14b 100644 --- a/SheepShaver/src/Unix/prefs_editor_gtk.cpp +++ b/SheepShaver/src/Unix/prefs_editor_gtk.cpp @@ -711,7 +711,6 @@ static GtkWidget *w_frameskip, *w_display_x, *w_display_y; static GtkWidget *l_frameskip, *l_display_x, *l_display_y; static int display_type; static int dis_width, dis_height; -static bool is_fbdev_dga_mode = false; static GtkWidget *w_dspdevice_file, *w_mixerdevice_file; @@ -772,8 +771,7 @@ static void tb_nosound(GtkWidget *widget) } // Read and convert graphics preferences -static void parse_graphics_prefs(void) -{ +static void parse_graphics_prefs(void){ display_type = DISPLAY_WINDOW; dis_width = 640; dis_height = 480; @@ -784,12 +782,6 @@ static void parse_graphics_prefs(void) display_type = DISPLAY_WINDOW; else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2) display_type = DISPLAY_SCREEN; -#ifdef ENABLE_FBDEV_DGA - else if (sscanf(str, "fbdev/%d/%d", &dis_width, &dis_height) == 2) { - is_fbdev_dga_mode = true; - display_type = DISPLAY_SCREEN; - } -#endif } else { uint32 window_modes = PrefsFindInt32("windowmodes"); diff --git a/SheepShaver/src/Unix/video_x.cpp b/SheepShaver/src/Unix/video_x.cpp deleted file mode 100644 index f73747402..000000000 --- a/SheepShaver/src/Unix/video_x.cpp +++ /dev/null @@ -1,2584 +0,0 @@ -/* - * video_x.cpp - Video/graphics emulation, X11 specific stuff - * - * SheepShaver (C) Marc Hellwig and Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * The Ctrl key works like a qualifier for special actions: - * Ctrl-Tab = suspend DGA mode - * Ctrl-Esc = emergency quit - * Ctrl-F1 = mount floppy - * Ctrl-F5 = grab mouse (in windowed mode) - */ - -#include "sysdeps.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef ENABLE_FBDEV_DGA -# include -# include -#endif - -#ifdef ENABLE_XF86_DGA -# include -#endif - -#ifdef ENABLE_XF86_VIDMODE -# include -#endif - -#ifdef ENABLE_FBDEV_DGA -# include -#endif - -#include "main.h" -#include "adb.h" -#include "prefs.h" -#include "user_strings.h" -#include "about_window.h" -#include "video.h" -#include "video_defs.h" -#include "video_blit.h" - -#define DEBUG 0 -#include "debug.h" - -#ifndef NO_STD_NAMESPACE -using std::sort; -#endif - - -// Constants -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; -static const bool hw_mac_cursor_accl = true; // Flag: Enable MacOS to X11 copy of cursor? - -// Global variables -static int32 frame_skip; -static int16 mouse_wheel_mode; -static int16 mouse_wheel_lines; -static bool redraw_thread_active = false; // Flag: Redraw thread installed -static pthread_attr_t redraw_thread_attr; // Redraw thread attributes -static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread -static pthread_t redraw_thread; // Redraw thread - -static volatile bool thread_stop_req = false; -static sem_t thread_stop_ack; -static sem_t thread_resume_req; - -static bool local_X11; // Flag: X server running on local machine? -static bool has_dga = false; // Flag: Video DGA capable -static bool has_vidmode = false; // Flag: VidMode extension available - -#ifdef ENABLE_VOSF -static bool use_vosf = true; // Flag: VOSF enabled -#else -static const bool use_vosf = false; // VOSF not possible -#endif - -static bool palette_changed = false; // Flag: Palette changed, redraw thread must update palette -static bool ctrl_down = false; // Flag: Ctrl key pressed -static bool caps_on = false; // Flag: Caps Lock on -static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread -static volatile bool quit_full_screen_ack = false; // Acknowledge for quit_full_screen -static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread - -static bool emul_suspended = false; // Flag: emulator suspended -static Window suspend_win; // "Suspend" window -static void *fb_save = NULL; // Saved frame buffer for suspend -static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms -static int keycode_table[256]; // X keycode -> Mac keycode translation table - -// X11 variables -static int screen; // Screen number -static int xdepth; // Depth of X screen -static int depth; // Depth of Mac frame buffer -static Window rootwin, the_win; // Root window and our window -static int num_depths = 0; // Number of available X depths -static int *avail_depths = NULL; // List of available X depths -static VisualFormat visualFormat; -static XVisualInfo visualInfo; -static Visual *vis; -static int color_class; -static int rshift, rloss, gshift, gloss, bshift, bloss; // Pixel format of DirectColor/TrueColor modes -static Colormap cmap[2]; // Two colormaps (DGA) for 8-bit mode -static XColor x_palette[256]; // Color palette to be used as CLUT and gamma table -static int orig_accel_numer, orig_accel_denom, orig_threshold; // Original mouse acceleration - -static XColor black, white; -static unsigned long black_pixel, white_pixel; -static int eventmask; -static const int win_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | ExposureMask | StructureNotifyMask; -static const int dga_eventmask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask; - -// Variables for window mode -static GC the_gc; -static XImage *img = NULL; -static XShmSegmentInfo shminfo; -static XImage *cursor_image, *cursor_mask_image; -static Pixmap cursor_map, cursor_mask_map; -static Cursor mac_cursor; -static GC cursor_gc, cursor_mask_gc; -static bool cursor_changed = false; // Flag: Cursor changed, window_func must update cursor -static bool have_shm = false; // Flag: SHM present and usable -static uint8 *the_buffer = NULL; // Pointer to Mac frame buffer -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer -static uint32 the_buffer_size; // Size of allocated the_buffer - -// Variables for DGA mode -static bool is_fbdev_dga_mode = false; // Flag: Use FBDev DGA mode? -static int current_dga_cmap; - -#ifdef ENABLE_FBDEV_DGA -static int fb_dev_fd = -1; // Handle to fb device name -static struct fb_fix_screeninfo fb_finfo; // Fixed info -static struct fb_var_screeninfo fb_vinfo; // Variable info -static struct fb_var_screeninfo fb_orig_vinfo; // Variable info to restore later -static struct fb_cmap fb_oldcmap; // Colormap to restore later -#endif - -#ifdef ENABLE_XF86_VIDMODE -// Variables for XF86 VidMode support -static XF86VidModeModeInfo **x_video_modes; // Array of all available modes -static int num_x_video_modes; -#endif - -// Mutex to protect palette -#if defined(HAVE_PTHREADS) -static pthread_mutex_t x_palette_lock = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_PALETTE pthread_mutex_lock(&x_palette_lock) -#define UNLOCK_PALETTE pthread_mutex_unlock(&x_palette_lock) -#elif defined(HAVE_SPINLOCKS) -static spinlock_t x_palette_lock = SPIN_LOCK_UNLOCKED; -#define LOCK_PALETTE spin_lock(&x_palette_lock) -#define UNLOCK_PALETTE spin_unlock(&x_palette_lock) -#else -#define LOCK_PALETTE -#define UNLOCK_PALETTE -#endif - -// Mutex to protect frame buffer -#if defined(HAVE_PTHREADS) -static pthread_mutex_t frame_buffer_lock = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_FRAME_BUFFER pthread_mutex_lock(&frame_buffer_lock); -#define UNLOCK_FRAME_BUFFER pthread_mutex_unlock(&frame_buffer_lock); -#elif defined(HAVE_SPINLOCKS) -static spinlock_t frame_buffer_lock = SPIN_LOCK_UNLOCKED; -#define LOCK_FRAME_BUFFER spin_lock(&frame_buffer_lock) -#define UNLOCK_FRAME_BUFFER spin_unlock(&frame_buffer_lock) -#else -#define LOCK_FRAME_BUFFER -#define UNLOCK_FRAME_BUFFER -#endif - - -// Prototypes -static void *redraw_func(void *arg); - - -// From main_unix.cpp -extern char *x_display_name; -extern Display *x_display; - -// From sys_unix.cpp -extern void SysMountFirstFloppy(void); - -// From clip_unix.cpp -extern void ClipboardSelectionClear(XSelectionClearEvent *); -extern void ClipboardSelectionRequest(XSelectionRequestEvent *); - - -// Video acceleration through SIGSEGV -#ifdef ENABLE_VOSF -# include "video_vosf.h" -#endif - - -/* - * Utility functions - */ - -// Get current video mode -static inline int get_current_mode(void) -{ - return VModes[cur_mode].viAppleMode; -} - -// Find palette size for given color depth -static int palette_size(int mode) -{ - switch (mode) { - case APPLE_1_BIT: return 2; - case APPLE_2_BIT: return 4; - case APPLE_4_BIT: return 16; - case APPLE_8_BIT: return 256; - case APPLE_16_BIT: return 32; - case APPLE_32_BIT: return 256; - default: return 0; - } -} - -// Return bits per pixel for requested depth -static inline int bytes_per_pixel(int depth) -{ - int bpp; - switch (depth) { - case 8: - bpp = 1; - break; - case 15: case 16: - bpp = 2; - break; - case 24: case 32: - bpp = 4; - break; - default: - abort(); - } - return bpp; -} - -// Map video_mode depth ID to numerical depth value -static inline int depth_of_video_mode(int mode) -{ - int depth; - switch (mode) { - case APPLE_1_BIT: - depth = 1; - break; - case APPLE_2_BIT: - depth = 2; - break; - case APPLE_4_BIT: - depth = 4; - break; - case APPLE_8_BIT: - depth = 8; - break; - case APPLE_16_BIT: - depth = 16; - break; - case APPLE_32_BIT: - depth = 32; - break; - default: - abort(); - } - return depth; -} - -// Map RGB color to pixel value (this only works in TrueColor/DirectColor visuals) -static inline uint32 map_rgb(uint8 red, uint8 green, uint8 blue) -{ - return ((red >> rloss) << rshift) | ((green >> gloss) << gshift) | ((blue >> bloss) << bshift); -} - - -// Do we have a visual for handling the specified Mac depth? If so, set the -// global variables "xdepth", "visualInfo", "vis" and "color_class". -static bool find_visual_for_depth(int depth) -{ - D(bug("have_visual_for_depth(%d)\n", depth_of_video_mode(depth))); - - // 1-bit works always and uses default visual - if (depth == APPLE_1_BIT) { - vis = DefaultVisual(x_display, screen); - visualInfo.visualid = XVisualIDFromVisual(vis); - int num = 0; - XVisualInfo *vi = XGetVisualInfo(x_display, VisualIDMask, &visualInfo, &num); - visualInfo = vi[0]; - XFree(vi); - xdepth = visualInfo.depth; - color_class = visualInfo.c_class; - D(bug(" found visual ID 0x%02x, depth %d\n", visualInfo.visualid, xdepth)); - return true; - } - - // Calculate minimum and maximum supported X depth - int min_depth = 1, max_depth = 32; - switch (depth) { -#ifdef ENABLE_VOSF - case APPLE_2_BIT: - case APPLE_4_BIT: // VOSF blitters can convert 2/4/8-bit -> 8/16/32-bit - case APPLE_8_BIT: - min_depth = 8; - max_depth = 32; - break; -#else - case APPLE_2_BIT: - case APPLE_4_BIT: // 2/4-bit requires VOSF blitters - return false; - case APPLE_8_BIT: // 8-bit without VOSF requires an 8-bit visual - min_depth = 8; - max_depth = 8; - break; -#endif - case APPLE_16_BIT: // 16-bit requires a 15/16-bit visual - min_depth = 15; - max_depth = 16; - break; - case APPLE_32_BIT: // 32-bit requires a 24/32-bit visual - min_depth = 24; - max_depth = 32; - break; - } - D(bug(" minimum required X depth is %d, maximum supported X depth is %d\n", min_depth, max_depth)); - - // Try to find a visual for one of the color depths - bool visual_found = false; - for (int i=0; i max_depth) - continue; - - // Determine best color class for this depth - switch (xdepth) { - case 1: // Try StaticGray or StaticColor - if (XMatchVisualInfo(x_display, screen, xdepth, StaticGray, &visualInfo) - || XMatchVisualInfo(x_display, screen, xdepth, StaticColor, &visualInfo)) - visual_found = true; - break; - case 8: // Need PseudoColor - if (XMatchVisualInfo(x_display, screen, xdepth, PseudoColor, &visualInfo)) - visual_found = true; - break; - case 15: - case 16: - case 24: - case 32: // Try DirectColor first, as this will allow gamma correction - if (XMatchVisualInfo(x_display, screen, xdepth, DirectColor, &visualInfo) - || XMatchVisualInfo(x_display, screen, xdepth, TrueColor, &visualInfo)) - visual_found = true; - break; - default: - D(bug(" not a supported depth\n")); - break; - } - } - if (!visual_found) - return false; - - // Visual was found - vis = visualInfo.visual; - color_class = visualInfo.c_class; - D(bug(" found visual ID 0x%02x, depth %d, class ", visualInfo.visualid, xdepth)); -#if DEBUG - switch (color_class) { - case StaticGray: D(bug("StaticGray\n")); break; - case GrayScale: D(bug("GrayScale\n")); break; - case StaticColor: D(bug("StaticColor\n")); break; - case PseudoColor: D(bug("PseudoColor\n")); break; - case TrueColor: D(bug("TrueColor\n")); break; - case DirectColor: D(bug("DirectColor\n")); break; - } -#endif - return true; -} - - -/* - * Open display (window or fullscreen) - */ - -// Set window name and class -static void set_window_name(Window w, int name) -{ - const char *str = GetString(name); - XStoreName(x_display, w, str); - XSetIconName(x_display, w, str); - - XClassHint *hints; - hints = XAllocClassHint(); - if (hints) { - hints->res_name = "SheepShaver"; - hints->res_class = "SheepShaver"; - XSetClassHint(x_display, w, hints); - XFree(hints); - } -} - -// Set window input focus flag -static void set_window_focus(Window w) -{ - XWMHints *hints = XAllocWMHints(); - if (hints) { - hints->input = True; - hints->initial_state = NormalState; - hints->flags = InputHint | StateHint; - XSetWMHints(x_display, w, hints); - XFree(hints); - } -} - -// Set WM_DELETE_WINDOW protocol on window (preventing it from being destroyed by the WM when clicking on the "close" widget) -static Atom WM_DELETE_WINDOW = (Atom)0; -static void set_window_delete_protocol(Window w) -{ - WM_DELETE_WINDOW = XInternAtom(x_display, "WM_DELETE_WINDOW", false); - XSetWMProtocols(x_display, w, &WM_DELETE_WINDOW, 1); -} - -// Wait until window is mapped/unmapped -static void wait_mapped(Window w) -{ - XEvent e; - do { - XMaskEvent(x_display, StructureNotifyMask, &e); - } while ((e.type != MapNotify) || (e.xmap.event != w)); -} - -static void wait_unmapped(Window w) -{ - XEvent e; - do { - XMaskEvent(x_display, StructureNotifyMask, &e); - } while ((e.type != UnmapNotify) || (e.xmap.event != w)); -} - -// Disable mouse acceleration -static void disable_mouse_accel(void) -{ - XChangePointerControl(x_display, True, False, 1, 1, 0); -} - -// Restore mouse acceleration to original value -static void restore_mouse_accel(void) -{ - XChangePointerControl(x_display, True, True, orig_accel_numer, orig_accel_denom, orig_threshold); -} - -// Trap SHM errors -static bool shm_error = false; -static int (*old_error_handler)(Display *, XErrorEvent *); - -static int error_handler(Display *d, XErrorEvent *e) -{ - if (e->error_code == BadAccess) { - shm_error = true; - return 0; - } else - return old_error_handler(d, e); -} - -// Open window -static bool open_window(int width, int height) -{ - int aligned_width = (width + 15) & ~15; - int aligned_height = (height + 15) & ~15; - - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = win_eventmask; - wattr.background_pixel = (vis == DefaultVisual(x_display, screen) ? black_pixel : 0); - wattr.border_pixel = 0; - wattr.backing_store = NotUseful; - wattr.colormap = (depth == 1 ? DefaultColormap(x_display, screen) : cmap[0]); - the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel | CWBorderPixel | CWBackingStore | CWColormap, &wattr); - - // Set window name/class - set_window_name(the_win, STR_WINDOW_TITLE); - - // Indicate that we want keyboard input - set_window_focus(the_win); - - // Set delete protocol property - set_window_delete_protocol(the_win); - - // Make window unresizable - XSizeHints *hints; - if ((hints = XAllocSizeHints()) != NULL) { - hints->min_width = width; - hints->max_width = width; - hints->min_height = height; - hints->max_height = height; - hints->flags = PMinSize | PMaxSize; - XSetWMNormalHints(x_display, the_win, hints); - XFree((char *)hints); - } - - // Show window - XMapWindow(x_display, the_win); - wait_mapped(the_win); - - // 1-bit mode is big-endian; if the X server is little-endian, we can't - // use SHM because that doesn't allow changing the image byte order - bool need_msb_image = (depth == 1 && XImageByteOrder(x_display) == LSBFirst); - - // Try to create and attach SHM image - have_shm = false; - if (local_X11 && !need_msb_image && XShmQueryExtension(x_display)) { - - // Create SHM image ("height + 2" for safety) - img = XShmCreateImage(x_display, vis, depth == 1 ? 1 : xdepth, depth == 1 ? XYBitmap : ZPixmap, 0, &shminfo, width, height); - shminfo.shmid = shmget(IPC_PRIVATE, (aligned_height + 2) * img->bytes_per_line, IPC_CREAT | 0777); - D(bug(" shm image created\n")); - the_buffer_copy = (uint8 *)shmat(shminfo.shmid, 0, 0); - shminfo.shmaddr = img->data = (char *)the_buffer_copy; - shminfo.readOnly = False; - - // Try to attach SHM image, catching errors - shm_error = false; - old_error_handler = XSetErrorHandler(error_handler); - XShmAttach(x_display, &shminfo); - XSync(x_display, false); - XSetErrorHandler(old_error_handler); - if (shm_error) { - shmdt(shminfo.shmaddr); - XDestroyImage(img); - shminfo.shmid = -1; - } else { - have_shm = true; - shmctl(shminfo.shmid, IPC_RMID, 0); - } - D(bug(" shm image attached\n")); - } - - // Create normal X image if SHM doesn't work ("height + 2" for safety) - if (!have_shm) { - int bytes_per_row = depth == 1 ? aligned_width/8 : TrivialBytesPerRow(aligned_width, DepthModeForPixelDepth(xdepth)); - the_buffer_copy = (uint8 *)malloc((aligned_height + 2) * bytes_per_row); - img = XCreateImage(x_display, vis, depth == 1 ? 1 : xdepth, depth == 1 ? XYBitmap : ZPixmap, 0, (char *)the_buffer_copy, aligned_width, aligned_height, 32, bytes_per_row); - D(bug(" X image created\n")); - } - - // 1-Bit mode is big-endian - if (need_msb_image) { - img->byte_order = MSBFirst; - img->bitmap_bit_order = MSBFirst; - } - -#ifdef ENABLE_VOSF - use_vosf = true; - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer_copy; - the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line); - the_buffer = (uint8 *)vm_acquire(the_buffer_size); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); -#else - // Allocate memory for frame buffer - the_buffer = (uint8 *)malloc((aligned_height + 2) * img->bytes_per_line); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); -#endif - screen_base = Host2MacAddr(the_buffer); - - // Create GC - the_gc = XCreateGC(x_display, the_win, 0, 0); - XSetState(x_display, the_gc, black_pixel, white_pixel, GXcopy, AllPlanes); - - // Create cursor - if (hw_mac_cursor_accl) { - cursor_image = XCreateImage(x_display, vis, 1, XYPixmap, 0, (char *)MacCursor + 4, 16, 16, 16, 2); - cursor_image->byte_order = MSBFirst; - cursor_image->bitmap_bit_order = MSBFirst; - cursor_mask_image = XCreateImage(x_display, vis, 1, XYPixmap, 0, (char *)MacCursor + 36, 16, 16, 16, 2); - cursor_mask_image->byte_order = MSBFirst; - cursor_mask_image->bitmap_bit_order = MSBFirst; - cursor_map = XCreatePixmap(x_display, the_win, 16, 16, 1); - cursor_mask_map = XCreatePixmap(x_display, the_win, 16, 16, 1); - cursor_gc = XCreateGC(x_display, cursor_map, 0, 0); - cursor_mask_gc = XCreateGC(x_display, cursor_mask_map, 0, 0); - mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, 0, 0); - cursor_changed = false; - } - - // Create no_cursor - else { - mac_cursor = XCreatePixmapCursor(x_display, - XCreatePixmap(x_display, the_win, 1, 1, 1), - XCreatePixmap(x_display, the_win, 1, 1, 1), - &black, &white, 0, 0); - XDefineCursor(x_display, the_win, mac_cursor); - } - - // Init blitting routines - bool native_byte_order; -#ifdef WORDS_BIGENDIAN - native_byte_order = (XImageByteOrder(x_display) == MSBFirst); -#else - native_byte_order = (XImageByteOrder(x_display) == LSBFirst); -#endif -#ifdef ENABLE_VOSF - Screen_blitter_init(visualFormat, native_byte_order, depth); -#endif - - // Set bytes per row - XSync(x_display, false); - return true; -} - -// Open FBDev DGA display -static bool open_fbdev_dga(int width, int height) -{ -#ifdef ENABLE_FBDEV_DGA -#ifdef ENABLE_XF86_VIDMODE - // Switch to best mode - if (has_vidmode) { - int best = -1; - for (int i = 0; i < num_x_video_modes; i++) { - if (x_video_modes[i]->hdisplay == width && x_video_modes[i]->vdisplay == height) { - best = i; - break; - } - }; - assert(best != -1); - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[best]); - XF86VidModeSetViewPort(x_display, screen, 0, 0); - D(bug("[fbdev] VideoMode %d: %d x %d @ %d\n", best, - x_video_modes[best]->hdisplay, x_video_modes[best]->vdisplay, - 1000 * x_video_modes[best]->dotclock / (x_video_modes[best]->htotal * x_video_modes[best]->vtotal))); - } -#endif - - if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo) != 0) { - D(bug("[fbdev] Can't get FSCREENINFO: %s\n", strerror(errno))); - return false; - } - D(bug("[fbdev] Device ID: %s\n", fb_finfo.id)); - D(bug("[fbdev] smem_start: %p [%d bytes]\n", fb_finfo.smem_start, fb_finfo.smem_len)); - - int fb_type = fb_finfo.type; - const char *fb_type_str = NULL; - switch (fb_type) { - case FB_TYPE_PACKED_PIXELS: fb_type_str = "Packed Pixels"; break; - case FB_TYPE_PLANES: fb_type_str = "Non interleaved planes"; break; - case FB_TYPE_INTERLEAVED_PLANES: fb_type_str = "Interleaved planes"; break; - case FB_TYPE_TEXT: fb_type_str = "Text/attributes"; break; - case FB_TYPE_VGA_PLANES: fb_type_str = "EGA/VGA planes"; break; - default: fb_type_str = ""; break; - } - D(bug("[fbdev] type: %s\n", fb_type_str)); - - if (fb_type != FB_TYPE_PACKED_PIXELS) { - D(bug("[fbdev] type '%s' not supported\n", fb_type_str)); - return false; - } - - int fb_visual = fb_finfo.visual; - const char *fb_visual_str; - switch (fb_visual) { - case FB_VISUAL_MONO01: fb_visual_str = "Monochrome 1=Black 0=White"; break; - case FB_VISUAL_MONO10: fb_visual_str = "Monochrome 1=While 0=Black"; break; - case FB_VISUAL_TRUECOLOR: fb_visual_str = "True color"; break; - case FB_VISUAL_PSEUDOCOLOR: fb_visual_str = "Pseudo color (like atari)"; break; - case FB_VISUAL_DIRECTCOLOR: fb_visual_str = "Direct color"; break; - case FB_VISUAL_STATIC_PSEUDOCOLOR: fb_visual_str = "Pseudo color readonly"; break; - default: fb_visual_str = ""; break; - } - D(bug("[fbdev] visual: %s\n", fb_visual_str)); - - if (fb_visual != FB_VISUAL_TRUECOLOR && fb_visual != FB_VISUAL_DIRECTCOLOR) { - D(bug("[fbdev] visual '%s' not supported\n", fb_visual_str)); - return false; - } - - // Map frame buffer - the_buffer = (uint8 *)mmap(NULL, fb_finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb_dev_fd, 0); - if (the_buffer == MAP_FAILED) { - D(bug("[fbdev] Can't mmap /dev/fb0: %s\n", strerror(errno))); - return false; - } - - // Set absolute mouse mode - ADBSetRelMouseMode(false); - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = dga_eventmask; - wattr.override_redirect = True; - the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, DefaultVisual(x_display, screen), - CWEventMask | CWOverrideRedirect, &wattr); - - // Show window - XMapRaised(x_display, the_win); - wait_mapped(the_win); - - // Grab mouse and keyboard - XGrabKeyboard(x_display, the_win, True, - GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, the_win, True, - PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, the_win, None, CurrentTime); - disable_mouse_accel(); - - // Create no_cursor - mac_cursor = XCreatePixmapCursor(x_display, - XCreatePixmap(x_display, the_win, 1, 1, 1), - XCreatePixmap(x_display, the_win, 1, 1, 1), - &black, &white, 0, 0); - XDefineCursor(x_display, the_win, mac_cursor); - - // Init blitting routines - int bytes_per_row = TrivialBytesPerRow((width + 7) & ~7, DepthModeForPixelDepth(depth)); -#if ENABLE_VOSF - // Extract current screen color masks (we are in True Color mode) - VisualFormat visualFormat; - visualFormat.depth = xdepth = DefaultDepth(x_display, screen); - XMatchVisualInfo(x_display, screen, xdepth, TrueColor, &visualInfo); - assert(visualFormat.depth == visualInfo.depth); - visualFormat.Rmask = visualInfo.red_mask; - visualFormat.Gmask = visualInfo.green_mask; - visualFormat.Bmask = visualInfo.blue_mask; - D(bug("[fbdev] %d bpp, (%08x,%08x,%08x)\n", - visualFormat.depth, - visualFormat.Rmask, visualFormat.Gmask, visualFormat.Bmask)); - D(bug("[fbdev] Mac depth %d bpp\n", depth)); - - // Screen_blitter_init() returns TRUE if VOSF is mandatory - // i.e. the framebuffer update function is not Blit_Copy_Raw -#ifdef WORDS_BIGENDIAN - const bool native_byte_order = (XImageByteOrder(x_display) == MSBFirst); -#else - const bool native_byte_order = (XImageByteOrder(x_display) == LSBFirst); -#endif - Screen_blitter_init(visualFormat, native_byte_order, depth); - - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - use_vosf = true; - the_host_buffer = the_buffer; - the_buffer_size = page_extend((height + 2) * bytes_per_row); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - the_buffer = (uint8 *)vm_acquire(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); -#endif - - // Set frame buffer base - D(bug("the_buffer = %p, use_vosf = %d\n", the_buffer, use_vosf)); - screen_base = Host2MacAddr(the_buffer); - VModes[cur_mode].viRowBytes = bytes_per_row; - return true; -#else - ErrorAlert("SheepShaver has been compiled with DGA support disabled."); - return false; -#endif -} - -// Open XF86 DGA display (!! should use X11 VidMode extensions to set mode) -static bool open_xf86_dga(int width, int height) -{ - if (is_fbdev_dga_mode) - return false; - -#ifdef ENABLE_XF86_DGA - // Set relative mouse mode - ADBSetRelMouseMode(true); - - // Create window - XSetWindowAttributes wattr; - wattr.event_mask = eventmask = dga_eventmask; - wattr.override_redirect = True; - wattr.colormap = (depth == 1 ? DefaultColormap(x_display, screen) : cmap[0]); - the_win = XCreateWindow(x_display, rootwin, 0, 0, width, height, 0, xdepth, - InputOutput, vis, CWEventMask | CWOverrideRedirect | - (color_class == DirectColor ? CWColormap : 0), &wattr); - - // Show window - XMapRaised(x_display, the_win); - wait_mapped(the_win); - -#ifdef ENABLE_XF86_VIDMODE - // Switch to best mode - if (has_vidmode) { - int best = 0; - for (int i=1; ihdisplay >= width && x_video_modes[i]->vdisplay >= height && - x_video_modes[i]->hdisplay <= x_video_modes[best]->hdisplay && x_video_modes[i]->vdisplay <= x_video_modes[best]->vdisplay) { - best = i; - } - } - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[best]); - XF86VidModeSetViewPort(x_display, screen, 0, 0); - } -#endif - - // Establish direct screen connection - XMoveResizeWindow(x_display, the_win, 0, 0, width, height); - XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0); - XGrabKeyboard(x_display, rootwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, rootwin, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); - - int v_width, v_bank, v_size; - XF86DGAGetVideo(x_display, screen, (char **)&the_buffer, &v_width, &v_bank, &v_size); - XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse); - XF86DGASetViewPort(x_display, screen, 0, 0); - XF86DGASetVidPage(x_display, screen, 0); - - // Set colormap - if (!IsDirectMode(get_current_mode())) { - XSetWindowColormap(x_display, the_win, cmap[current_dga_cmap = 0]); - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); - } - XSync(x_display, false); - - // Init blitting routines - int bytes_per_row = TrivialBytesPerRow((v_width + 7) & ~7, DepthModeForPixelDepth(depth)); -#if ENABLE_VOSF - bool native_byte_order; -#ifdef WORDS_BIGENDIAN - native_byte_order = (XImageByteOrder(x_display) == MSBFirst); -#else - native_byte_order = (XImageByteOrder(x_display) == LSBFirst); -#endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING - // Screen_blitter_init() returns TRUE if VOSF is mandatory - // i.e. the framebuffer update function is not Blit_Copy_Raw - use_vosf = Screen_blitter_init(visualFormat, native_byte_order, depth); - - if (use_vosf) { - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_host_buffer = the_buffer; - the_buffer_size = page_extend((height + 2) * bytes_per_row); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - the_buffer = (uint8 *)vm_acquire(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); - } -#else - use_vosf = false; -#endif -#endif - - // Set frame buffer base - D(bug("the_buffer = %p, use_vosf = %d\n", the_buffer, use_vosf)); - screen_base = Host2MacAddr(the_buffer); - VModes[cur_mode].viRowBytes = bytes_per_row; - return true; -#else - ErrorAlert("SheepShaver has been compiled with DGA support disabled."); - return false; -#endif -} - -// Open DGA display -static bool open_dga(int width, int height) -{ - bool display_open; - - display_open = open_xf86_dga(width, height); -#ifdef ENABLE_FBDEV_DGA - // Try to fallback to FBDev DGA mode - if (!display_open) { - is_fbdev_dga_mode = true; - display_open = open_fbdev_dga(width, height); - } -#endif - - // Common DGA display initialization - if (display_open) { - - // Fake image to get display bounds in the refresh function - if ((img = (XImage *)malloc(sizeof(*img))) == NULL) - return false; - img->width = DisplayWidth(x_display, screen); - img->height = DisplayHeight(x_display, screen); - img->depth = is_fbdev_dga_mode ? xdepth : depth; - img->bytes_per_line = TrivialBytesPerRow(img->width, DepthModeForPixelDepth(img->depth)); - } - - return display_open; -} - -static bool open_display(void) -{ - D(bug("open_display()\n")); - const VideoInfo &mode = VModes[cur_mode]; - - // Get original mouse acceleration - XGetPointerControl(x_display, &orig_accel_numer, &orig_accel_denom, &orig_threshold); - - // Find best available X visual - if (!find_visual_for_depth(mode.viAppleMode)) { - ErrorAlert(GetString(STR_NO_XVISUAL_ERR)); - return false; - } - - // Build up visualFormat structure - visualFormat.fullscreen = (display_type == DIS_SCREEN); - visualFormat.depth = visualInfo.depth; - visualFormat.Rmask = visualInfo.red_mask; - visualFormat.Gmask = visualInfo.green_mask; - visualFormat.Bmask = visualInfo.blue_mask; - - // Create color maps - if (color_class == PseudoColor || color_class == DirectColor) { - cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocAll); - cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocAll); - } else { - cmap[0] = XCreateColormap(x_display, rootwin, vis, AllocNone); - cmap[1] = XCreateColormap(x_display, rootwin, vis, AllocNone); - } - - // Find pixel format of direct modes - if (color_class == DirectColor || color_class == TrueColor) { - rshift = gshift = bshift = 0; - rloss = gloss = bloss = 8; - uint32 mask; - for (mask=vis->red_mask; !(mask&1); mask>>=1) - ++rshift; - for (; mask&1; mask>>=1) - --rloss; - for (mask=vis->green_mask; !(mask&1); mask>>=1) - ++gshift; - for (; mask&1; mask>>=1) - --gloss; - for (mask=vis->blue_mask; !(mask&1); mask>>=1) - ++bshift; - for (; mask&1; mask>>=1) - --bloss; - } - - // Preset palette pixel values for CLUT or gamma table - if (color_class == DirectColor) { - int num = vis->map_entries; - for (int i=0; imap_entries : 256); - for (int i=0; i16/32 expand map - if (!IsDirectMode(get_current_mode()) && xdepth > 8) - for (int i=0; i<256; i++) - ExpandMap[i] = map_rgb(i, i, i); -#endif - - // Create display of requested type - display_type = mode.viType; - depth = depth_of_video_mode(mode.viAppleMode); - - bool display_open; - switch (display_type) { - case DIS_SCREEN: - display_open = open_dga(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize); - break; - case DIS_WINDOW: - display_open = open_window(VModes[cur_mode].viXsize, VModes[cur_mode].viYsize); - break; - default: - display_open = false; - break; - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Initialize the VOSF system - LOCK_VOSF; - if (!video_vosf_init()) { - ErrorAlert(GetString(STR_VOSF_INIT_ERR)); - UNLOCK_VOSF; - return false; - } - UNLOCK_VOSF; - } -#endif - - // Zero screen buffers, viRowBytes is initialized at this stage - if (display_open) { - memset(the_buffer, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - } - return display_open; -} - - -/* - * Close display - */ - -// Close window -static void close_window(void) -{ - if (have_shm) { - XShmDetach(x_display, &shminfo); -#ifdef ENABLE_VOSF - the_host_buffer = NULL; // don't free() in driver_base dtor -#else - the_buffer_copy = NULL; // don't free() in driver_base dtor -#endif - } - if (img) { - if (!have_shm) - img->data = NULL; - XDestroyImage(img); - } - if (have_shm) { - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); - } - if (the_gc) - XFreeGC(x_display, the_gc); - - XFlush(x_display); - XSync(x_display, false); -} - -// Close FBDev mode -static void close_fbdev_dga(void) -{ -#ifdef ENABLE_FBDEV_DGA - uint8 *fb_base; - if (!use_vosf) - fb_base = the_buffer; -#ifdef ENABLE_VOSF - else - fb_base = the_host_buffer; -#endif - munmap(fb_base, fb_finfo.smem_len); -#endif -} - -// Close XF86 DGA mode -static void close_xf86_dga(void) -{ -#ifdef ENABLE_XF86_DGA - XF86DGADirectVideo(x_display, screen, 0); -#endif -} - -// Close DGA mode -static void close_dga(void) -{ - if (is_fbdev_dga_mode) - close_fbdev_dga(); - else - close_xf86_dga(); - - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); - -#ifdef ENABLE_XF86_VIDMODE - if (has_vidmode) - XF86VidModeSwitchToMode(x_display, screen, x_video_modes[0]); -#endif - - // Release fake image (it's not a normal XImage!) - free(img); - img = NULL; - - if (!use_vosf) { - // don't free() the screen buffer in driver_base dtor - the_buffer = NULL; - } -#ifdef ENABLE_VOSF - else { - // don't free() the screen buffer in driver_base dtor - the_host_buffer = NULL; - } -#endif -} - -static void close_display(void) -{ - if (display_type == DIS_SCREEN) - close_dga(); - else if (display_type == DIS_WINDOW) - close_window(); - - // Close window - if (the_win) { - XUnmapWindow(x_display, the_win); - wait_unmapped(the_win); - XDestroyWindow(x_display, the_win); - } - - // Free colormaps - if (cmap[0]) { - XFreeColormap(x_display, cmap[0]); - cmap[0] = 0; - } - if (cmap[1]) { - XFreeColormap(x_display, cmap[1]); - cmap[1] = 0; - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - // Free frame buffer(s) - if (!use_vosf) { - if (the_buffer_copy) { - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#ifdef ENABLE_VOSF - else { - // the_buffer shall always be mapped through vm_acquire() so that we can vm_protect() it at will - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release(the_buffer, the_buffer_size); - the_buffer = NULL; - } - if (the_host_buffer) { - D(bug(" freeing the_host_buffer at %p\n", the_host_buffer)); - free(the_host_buffer); - the_host_buffer = NULL; - } - if (the_buffer_copy) { - D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#endif - - // Restore mouse acceleration - restore_mouse_accel(); -} - - -/* - * Initialization - */ - -// Init keycode translation table -static void keycode_init(void) -{ - bool use_kc = PrefsFindBool("keycodes"); - if (use_kc) { - - // Get keycode file path from preferences - const char *kc_path = PrefsFindString("keycodefile"); - - // Open keycode table - FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); - if (f == NULL) { - char str[256]; - sprintf(str, GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); - WarningAlert(str); - return; - } - - // Default translation table - for (int i=0; i<256; i++) - keycode_table[i] = -1; - - // Search for server vendor string, then read keycodes - const char *vendor = ServerVendor(x_display); - // Force use of MacX mappings on MacOS X with Apple's X server - int dummy; - if (XQueryExtension(x_display, "Apple-DRI", &dummy, &dummy, &dummy)) - vendor = "MacX"; - bool vendor_found = false; - char line[256]; - while (fgets(line, 255, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - - // Comments begin with "#" or ";" - if (line[0] == '#' || line[0] == ';' || line[0] == 0) - continue; - - if (vendor_found) { - // Read keycode - int x_code, mac_code; - if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) - keycode_table[x_code & 0xff] = mac_code; - else - break; - } else { - // Search for vendor string - if (strstr(vendor, line) == vendor) - vendor_found = true; - } - } - - // Keycode file completely read - fclose(f); - use_keycodes = vendor_found; - - // Vendor not found? Then display warning - if (!vendor_found) { - char str[256]; - sprintf(str, GetString(STR_KEYCODE_VENDOR_WARN), vendor, kc_path ? kc_path : KEYCODE_FILE_NAME); - WarningAlert(str); - return; - } - } -} - -// Find Apple mode matching best specified dimensions -static int find_apple_resolution(int xsize, int ysize) -{ - int apple_id; - if (xsize < 800) - apple_id = APPLE_640x480; - else if (xsize < 1024) - apple_id = APPLE_800x600; - else if (xsize < 1152) - apple_id = APPLE_1024x768; - else if (xsize < 1280) { - if (ysize < 900) - apple_id = APPLE_1152x768; - else - apple_id = APPLE_1152x900; - } - else if (xsize < 1600) - apple_id = APPLE_1280x1024; - else - apple_id = APPLE_1600x1200; - return apple_id; -} - -// Find mode in list of supported modes -static int find_mode(int apple_mode, int apple_id, int type) -{ - for (VideoInfo *p = VModes; p->viType != DIS_INVALID; p++) { - if (p->viType == type && p->viAppleID == apple_id && p->viAppleMode == apple_mode) - return p - VModes; - } - return -1; -} - -// Add custom video mode -static void add_custom_mode(VideoInfo *&p, int type, uint32 x, uint32 y, int apple_mode, int apple_id) -{ - p->viType = type; - p->viXsize = x; - p->viYsize = y; - p->viRowBytes = TrivialBytesPerRow(p->viXsize, apple_mode); - p->viAppleMode = apple_mode; - p->viAppleID = apple_id; - p++; -} - -// Add mode to list of supported modes -static void add_mode(VideoInfo *&p, uint32 allow, uint32 test, int apple_mode, int apple_id, int type) -{ - if (allow & test) { - uint32 x = 0, y = 0; - switch (apple_id) { - case APPLE_W_640x480: - case APPLE_640x480: - x = 640; - y = 480; - break; - case APPLE_W_800x600: - case APPLE_800x600: - x = 800; - y = 600; - break; - case APPLE_1024x768: - x = 1024; - y = 768; - break; - case APPLE_1152x768: - x = 1152; - y = 768; - break; - case APPLE_1152x900: - x = 1152; - y = 900; - break; - case APPLE_1280x1024: - x = 1280; - y = 1024; - break; - case APPLE_1600x1200: - x = 1600; - y = 1200; - break; - } - add_custom_mode(p, type, x, y, apple_mode, apple_id); - } -} - -// Add standard list of windowed modes for given color depth -static void add_window_modes(VideoInfo *&p, int window_modes, int mode) -{ - add_mode(p, window_modes, 1, mode, APPLE_W_640x480, DIS_WINDOW); - add_mode(p, window_modes, 2, mode, APPLE_W_800x600, DIS_WINDOW); -} - -static bool has_mode(int x, int y) -{ -#ifdef ENABLE_XF86_VIDMODE - if (has_vidmode) { - for (int i=0; ihdisplay == x && x_video_modes[i]->vdisplay == y) - return true; - return false; - } -#endif - return DisplayWidth(x_display, screen) >= x && DisplayHeight(x_display, screen) >= y; -} - -bool VideoInit(void) -{ -#ifdef ENABLE_VOSF - // Zero the mainBuffer structure - mainBuffer.dirtyPages = NULL; - mainBuffer.pageInfo = NULL; -#endif - - // Check if X server runs on local machine - local_X11 = (strncmp(XDisplayName(x_display_name), ":", 1) == 0) - || (strncmp(XDisplayName(x_display_name), "/", 1) == 0) - || (strncmp(XDisplayName(x_display_name), "unix:", 5) == 0); - - // Init keycode translation - keycode_init(); - - // Read frame skip prefs - frame_skip = PrefsFindInt32("frameskip"); - if (frame_skip == 0) - frame_skip = 1; - - // Read mouse wheel prefs - mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); - mouse_wheel_lines = PrefsFindInt32("mousewheellines"); - - // Init variables - private_data = NULL; - video_activated = true; - - // Find screen and root window - screen = XDefaultScreen(x_display); - rootwin = XRootWindow(x_display, screen); - - // Get sorted list of available depths - avail_depths = XListDepths(x_display, screen, &num_depths); - if (avail_depths == NULL) { - ErrorAlert(GetString(STR_UNSUPP_DEPTH_ERR)); - return false; - } - sort(avail_depths, avail_depths + num_depths); - - // Get screen depth - xdepth = DefaultDepth(x_display, screen); - -#ifdef ENABLE_XF86_DGA - // DGA available? - int event_base, error_base; - is_fbdev_dga_mode = false; - if (local_X11 && XF86DGAQueryExtension(x_display, &event_base, &error_base)) { - int dga_flags = 0; - XF86DGAQueryDirectVideo(x_display, screen, &dga_flags); - has_dga = dga_flags & XF86DGADirectPresent; -#if defined(__linux__) - // Check r/w permission on /dev/mem for DGA mode to work - if (has_dga && access("/dev/mem", R_OK | W_OK) != 0) - has_dga = false; -#endif - } else - has_dga = false; -#endif - -#ifdef ENABLE_XF86_VIDMODE - // VidMode available? - int vm_event_base, vm_error_base; - has_vidmode = XF86VidModeQueryExtension(x_display, &vm_event_base, &vm_error_base); - if (has_vidmode) { - int vm_major_version, vm_minor_version; - XF86VidModeQueryVersion(x_display, &vm_major_version, &vm_minor_version); - D(bug("VidMode extension %d.%d available\n", vm_major_version, vm_minor_version)); - XF86VidModeGetAllModeLines(x_display, screen, &num_x_video_modes, &x_video_modes); - } -#endif - -#ifdef ENABLE_FBDEV_DGA - // FBDev available? - bool has_fbdev_dga = false; - if (local_X11) { - if ((fb_dev_fd = open("/dev/fb0", O_RDWR)) > 0) { - if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo) != 0) - close(fb_dev_fd); - else { - has_fbdev_dga = true; - if (!has_dga) { - // Fallback to FBDev DGA mode if XF86 DGA is not possible - has_dga = true; - is_fbdev_dga_mode = true; - } - fb_orig_vinfo = fb_vinfo; - D(bug("Frame buffer device initial resolution: %dx%dx%d\n", fb_vinfo.xres, fb_vinfo.yres, fb_vinfo.bits_per_pixel)); - } - } - } -#endif - - // Find black and white colors - XParseColor(x_display, DefaultColormap(x_display, screen), "rgb:00/00/00", &black); - XAllocColor(x_display, DefaultColormap(x_display, screen), &black); - XParseColor(x_display, DefaultColormap(x_display, screen), "rgb:ff/ff/ff", &white); - XAllocColor(x_display, DefaultColormap(x_display, screen), &white); - black_pixel = BlackPixel(x_display, screen); - white_pixel = WhitePixel(x_display, screen); - - // Mac screen depth follows X depth (for now) - int default_mode = APPLE_8_BIT; - switch (DefaultDepth(x_display, screen)) { - case 1: - default_mode = APPLE_1_BIT; - break; - case 8: - default_mode = APPLE_8_BIT; - break; - case 15: case 16: - default_mode = APPLE_16_BIT; - break; - case 24: case 32: - default_mode = APPLE_32_BIT; - break; - } - - // Get screen mode from preferences - const char *mode_str = PrefsFindString("screen"); - int default_width = 640, default_height = 480; - if (mode_str) { - display_type = DIS_INVALID; - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) - display_type = DIS_WINDOW; -#ifdef ENABLE_XF86_DGA - else if (has_dga && sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) - display_type = DIS_SCREEN; -#endif -#ifdef ENABLE_FBDEV_DGA - else if (has_fbdev_dga && sscanf(mode_str, "fbdev/%d/%d", &default_width, &default_height) == 2) { - is_fbdev_dga_mode = true; - display_type = DIS_SCREEN; - } -#endif - if (display_type == DIS_INVALID) { - D(bug("Invalid screen mode specified, defaulting to old modes selection\n")); - mode_str = NULL; - } - else { - if (default_width <= 0) - default_width = DisplayWidth(x_display, screen); - else if (default_width > DisplayWidth(x_display, screen)) - default_width = DisplayWidth(x_display, screen); - if (default_height <= 0) - default_height = DisplayHeight(x_display, screen); - else if (default_height > DisplayHeight(x_display, screen)) - default_height = DisplayHeight(x_display, screen); - } - } - - // Construct video mode table - uint32 window_modes = PrefsFindInt32("windowmodes"); - uint32 screen_modes = PrefsFindInt32("screenmodes"); - if (!has_dga) - screen_modes = 0; - if (mode_str) - window_modes = screen_modes = 0; - else if (window_modes == 0 && screen_modes == 0) - window_modes |= 3; // Allow at least 640x480 and 800x600 window modes - - VideoInfo *p = VModes; - if (mode_str) { - if (display_type == DIS_WINDOW) { - for (unsigned int d = APPLE_1_BIT; d <= APPLE_32_BIT; d++) { - if (find_visual_for_depth(d)) { - if (default_width > 640 && default_height > 480) - add_mode(p, 3, 1, d, APPLE_W_640x480, DIS_WINDOW); - if (default_width > 800 && default_height > 600) - add_mode(p, 3, 2, d, APPLE_W_800x600, DIS_WINDOW); - add_custom_mode(p, display_type, default_width, default_height, d, APPLE_CUSTOM); - } - } -#ifdef ENABLE_VOSF - } else if (display_type == DIS_SCREEN && is_fbdev_dga_mode) { - for (unsigned int d = APPLE_1_BIT; d <= default_mode; d++) - if (find_visual_for_depth(d)) - add_custom_mode(p, display_type, default_width, default_height, d, APPLE_CUSTOM); -#endif - } else - add_custom_mode(p, display_type, default_width, default_height, default_mode, APPLE_CUSTOM); - - // Add extra VidMode capable modes - if (display_type == DIS_SCREEN) { - struct { - int w; - int h; - int apple_id; - } - video_modes[] = { - { 640, 480, APPLE_640x480 }, - { 800, 600, APPLE_800x600 }, - { 1024, 768, APPLE_1024x768 }, - { 1152, 768, APPLE_1152x768 }, - { 1152, 900, APPLE_1152x900 }, - { 1280, 1024, APPLE_1280x1024 }, - { 1600, 1200, APPLE_1600x1200 }, - { 0, } - }; - - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (w >= default_width || h >= default_height) - continue; - if (has_mode(w, h)) { -#ifdef ENABLE_VOSF - if (is_fbdev_dga_mode) { - for (unsigned int d = APPLE_1_BIT; d <= default_mode; d++) - if (find_visual_for_depth(d)) - add_custom_mode(p, display_type, w, h, d, video_modes[i].apple_id); - } else -#endif - add_custom_mode(p, display_type, w, h, default_mode, video_modes[i].apple_id); - } - } - } - } else if (window_modes) { - for (unsigned int d = APPLE_1_BIT; d <= APPLE_32_BIT; d++) - if (find_visual_for_depth(d)) - add_window_modes(p, window_modes, d); - } else if (has_vidmode) { - if (has_mode(640, 480)) - add_mode(p, screen_modes, 1, default_mode, APPLE_640x480, DIS_SCREEN); - if (has_mode(800, 600)) - add_mode(p, screen_modes, 2, default_mode, APPLE_800x600, DIS_SCREEN); - if (has_mode(1024, 768)) - add_mode(p, screen_modes, 4, default_mode, APPLE_1024x768, DIS_SCREEN); - if (has_mode(1152, 768)) - add_mode(p, screen_modes, 64, default_mode, APPLE_1152x768, DIS_SCREEN); - if (has_mode(1152, 900)) - add_mode(p, screen_modes, 8, default_mode, APPLE_1152x900, DIS_SCREEN); - if (has_mode(1280, 1024)) - add_mode(p, screen_modes, 16, default_mode, APPLE_1280x1024, DIS_SCREEN); - if (has_mode(1600, 1200)) - add_mode(p, screen_modes, 32, default_mode, APPLE_1600x1200, DIS_SCREEN); - } else if (screen_modes) { - int xsize = DisplayWidth(x_display, screen); - int ysize = DisplayHeight(x_display, screen); - int apple_id = find_apple_resolution(xsize, ysize); - p->viType = DIS_SCREEN; - p->viRowBytes = 0; - p->viXsize = xsize; - p->viYsize = ysize; - p->viAppleMode = default_mode; - p->viAppleID = apple_id; - p++; - } - p->viType = DIS_INVALID; // End marker - p->viRowBytes = 0; - p->viXsize = p->viYsize = 0; - p->viAppleMode = 0; - p->viAppleID = 0; - - // Find default mode (window 640x480) - cur_mode = -1; - if (has_dga && screen_modes) { - int screen_width = DisplayWidth(x_display, screen); - int screen_height = DisplayHeight(x_display, screen); - int apple_id = find_apple_resolution(screen_width, screen_height); - if (apple_id != -1) - cur_mode = find_mode(default_mode, apple_id, DIS_SCREEN); - } else if (has_dga && mode_str) - cur_mode = find_mode(default_mode, APPLE_CUSTOM, DIS_SCREEN); - - if (cur_mode == -1) { - // pick up first windowed mode available - for (VideoInfo *p = VModes; p->viType != DIS_INVALID; p++) { - if (p->viType == DIS_WINDOW && p->viAppleMode == default_mode) { - cur_mode = p - VModes; - break; - } - } - } - assert(cur_mode != -1); - -#if DEBUG - D(bug("Available video modes:\n")); - for (p = VModes; p->viType != DIS_INVALID; p++) { - int bits = depth_of_video_mode(p->viAppleMode); - D(bug(" %dx%d (ID %02x), %d colors\n", p->viXsize, p->viYsize, p->viAppleID, 1 << bits)); - } -#endif - - // Open window/screen - if (!open_display()) { - ErrorAlert(GetString(STR_OPEN_WINDOW_ERR)); - return false; - } - -#if 0 - // Ignore errors from now on - XSetErrorHandler(ignore_errors); -#endif - - // Lock down frame buffer - XSync(x_display, false); - LOCK_FRAME_BUFFER; - - // Start periodic thread - XSync(x_display, false); - if (sem_init(&thread_stop_ack, 0, 0) < 0) - return false; - if (sem_init(&thread_resume_req, 0, 0) < 0) - return false; - Set_pthread_attr(&redraw_thread_attr, 0); - redraw_thread_cancel = false; - redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0); - D(bug("Redraw thread installed (%ld)\n", redraw_thread)); - return true; -} - - -/* - * Deinitialization - */ - -void VideoExit(void) -{ - // Stop redraw thread - if (redraw_thread_active) { - redraw_thread_cancel = true; - pthread_cancel(redraw_thread); - pthread_join(redraw_thread, NULL); - sem_destroy(&thread_stop_ack); - sem_destroy(&thread_resume_req); - redraw_thread_active = false; - } - - // Unlock frame buffer - UNLOCK_FRAME_BUFFER; - XSync(x_display, false); - D(bug(" frame buffer unlocked\n")); - -#ifdef ENABLE_VOSF - if (use_vosf) { - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - // Close window and server connection - if (x_display != NULL) { - XSync(x_display, false); - close_display(); - XFlush(x_display); - XSync(x_display, false); - } - -#ifdef ENABLE_FBDEV_DGA - // Close framebuffer device - if (fb_dev_fd >= 0) { - close(fb_dev_fd); - fb_dev_fd = -1; - } -#endif -} - - -/* - * Suspend/resume emulator - */ - -static void suspend_emul(void) -{ - if (display_type == DIS_SCREEN) { - // Release ctrl key - ADBKeyUp(0x36); - ctrl_down = false; - - // Lock frame buffer (this will stop the MacOS thread) - LOCK_FRAME_BUFFER; - - // Save frame buffer - fb_save = malloc(VModes[cur_mode].viYsize * VModes[cur_mode].viRowBytes); - if (fb_save) - Mac2Host_memcpy(fb_save, screen_base, VModes[cur_mode].viYsize * VModes[cur_mode].viRowBytes); - - // Close full screen display -#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA) -#ifdef ENABLE_XF86_DGA - if (!is_fbdev_dga_mode) - XF86DGADirectVideo(x_display, screen, 0); -#endif - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); -#endif - restore_mouse_accel(); - XUnmapWindow(x_display, the_win); - wait_unmapped(the_win); - XSync(x_display, false); - - // Open "suspend" window - XSetWindowAttributes wattr; - wattr.event_mask = KeyPressMask; - wattr.background_pixel = (vis == DefaultVisual(x_display, screen) ? black_pixel : 0); - wattr.backing_store = Always; - wattr.colormap = (depth == 1 ? DefaultColormap(x_display, screen) : cmap[0]); - - suspend_win = XCreateWindow(x_display, rootwin, 0, 0, 512, 1, 0, xdepth, - InputOutput, vis, CWEventMask | CWBackPixel | CWBackingStore | CWColormap, &wattr); - set_window_name(suspend_win, STR_SUSPEND_WINDOW_TITLE); - set_window_focus(suspend_win); - XMapWindow(x_display, suspend_win); - emul_suspended = true; - } -} - -static void resume_emul(void) -{ - // Close "suspend" window - XDestroyWindow(x_display, suspend_win); - XSync(x_display, false); - - // Reopen full screen display - XMapRaised(x_display, the_win); - wait_mapped(the_win); - XWarpPointer(x_display, None, rootwin, 0, 0, 0, 0, 0, 0); - Window w = is_fbdev_dga_mode ? the_win : rootwin; - XGrabKeyboard(x_display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); - XGrabPointer(x_display, w, True, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, is_fbdev_dga_mode ? w : None, None, CurrentTime); - disable_mouse_accel(); -#ifdef ENABLE_XF86_DGA - if (!is_fbdev_dga_mode) { - XF86DGADirectVideo(x_display, screen, XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse); - XF86DGASetViewPort(x_display, screen, 0, 0); - } -#endif - XSync(x_display, false); - - // the_buffer already contains the data to restore. i.e. since a temporary - // frame buffer is used when VOSF is actually used, fb_save is therefore - // not necessary. -#ifdef ENABLE_VOSF - if (use_vosf) { - LOCK_VOSF; - PFLAG_SET_ALL; - memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - UNLOCK_VOSF; - } -#endif - - // Restore frame buffer - if (fb_save) { -#ifdef ENABLE_VOSF - // Don't copy fb_save to the temporary frame buffer in VOSF mode - if (!use_vosf) -#endif - Host2Mac_memcpy(screen_base, fb_save, VModes[cur_mode].viYsize * VModes[cur_mode].viRowBytes); - free(fb_save); - fb_save = NULL; - } - - // Unlock frame buffer (and continue MacOS thread) - UNLOCK_FRAME_BUFFER; - emul_suspended = false; -} - - -/* - * Close screen in full-screen mode - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - if (display_type == DIS_SCREEN) { - quit_full_screen = true; - while (!quit_full_screen_ack) ; - } -} - - -/* - * X11 event handling - */ - -// Translate key event to Mac keycode -static int kc_decode(KeySym ks) -{ - switch (ks) { - case XK_A: case XK_a: return 0x00; - case XK_B: case XK_b: return 0x0b; - case XK_C: case XK_c: return 0x08; - case XK_D: case XK_d: return 0x02; - case XK_E: case XK_e: return 0x0e; - case XK_F: case XK_f: return 0x03; - case XK_G: case XK_g: return 0x05; - case XK_H: case XK_h: return 0x04; - case XK_I: case XK_i: return 0x22; - case XK_J: case XK_j: return 0x26; - case XK_K: case XK_k: return 0x28; - case XK_L: case XK_l: return 0x25; - case XK_M: case XK_m: return 0x2e; - case XK_N: case XK_n: return 0x2d; - case XK_O: case XK_o: return 0x1f; - case XK_P: case XK_p: return 0x23; - case XK_Q: case XK_q: return 0x0c; - case XK_R: case XK_r: return 0x0f; - case XK_S: case XK_s: return 0x01; - case XK_T: case XK_t: return 0x11; - case XK_U: case XK_u: return 0x20; - case XK_V: case XK_v: return 0x09; - case XK_W: case XK_w: return 0x0d; - case XK_X: case XK_x: return 0x07; - case XK_Y: case XK_y: return 0x10; - case XK_Z: case XK_z: return 0x06; - - case XK_1: case XK_exclam: return 0x12; - case XK_2: case XK_at: return 0x13; - case XK_3: case XK_numbersign: return 0x14; - case XK_4: case XK_dollar: return 0x15; - case XK_5: case XK_percent: return 0x17; - case XK_6: return 0x16; - case XK_7: return 0x1a; - case XK_8: return 0x1c; - case XK_9: return 0x19; - case XK_0: return 0x1d; - - case XK_grave: case XK_asciitilde: return 0x0a; - case XK_minus: case XK_underscore: return 0x1b; - case XK_equal: case XK_plus: return 0x18; - case XK_bracketleft: case XK_braceleft: return 0x21; - case XK_bracketright: case XK_braceright: return 0x1e; - case XK_backslash: case XK_bar: return 0x2a; - case XK_semicolon: case XK_colon: return 0x29; - case XK_apostrophe: case XK_quotedbl: return 0x27; - case XK_comma: case XK_less: return 0x2b; - case XK_period: case XK_greater: return 0x2f; - case XK_slash: case XK_question: return 0x2c; - - case XK_Tab: if (ctrl_down) {suspend_emul(); return -1;} else return 0x30; - case XK_Return: return 0x24; - case XK_space: return 0x31; - case XK_BackSpace: return 0x33; - - case XK_Delete: return 0x75; - case XK_Insert: return 0x72; - case XK_Home: case XK_Help: return 0x73; - case XK_End: return 0x77; -#ifdef __hpux - case XK_Prior: return 0x74; - case XK_Next: return 0x79; -#else - case XK_Page_Up: return 0x74; - case XK_Page_Down: return 0x79; -#endif - - case XK_Control_L: return 0x36; - case XK_Control_R: return 0x36; - case XK_Shift_L: return 0x38; - case XK_Shift_R: return 0x38; - case XK_Alt_L: return 0x37; - case XK_Alt_R: return 0x37; - case XK_Meta_L: return 0x3a; - case XK_Meta_R: return 0x3a; - case XK_Menu: return 0x32; - case XK_Caps_Lock: return 0x39; - case XK_Num_Lock: return 0x47; - - case XK_Up: return 0x3e; - case XK_Down: return 0x3d; - case XK_Left: return 0x3b; - case XK_Right: return 0x3c; - - case XK_Escape: if (ctrl_down) {quit_full_screen = true; emerg_quit = true; return -1;} else return 0x35; - - case XK_F1: if (ctrl_down) {SysMountFirstFloppy(); return -1;} else return 0x7a; - case XK_F2: return 0x78; - case XK_F3: return 0x63; - case XK_F4: return 0x76; - case XK_F5: return 0x60; - case XK_F6: return 0x61; - case XK_F7: return 0x62; - case XK_F8: return 0x64; - case XK_F9: return 0x65; - case XK_F10: return 0x6d; - case XK_F11: return 0x67; - case XK_F12: return 0x6f; - - case XK_Print: return 0x69; - case XK_Scroll_Lock: return 0x6b; - case XK_Pause: return 0x71; - -#if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End) - case XK_KP_0: case XK_KP_Insert: return 0x52; - case XK_KP_1: case XK_KP_End: return 0x53; - case XK_KP_2: case XK_KP_Down: return 0x54; - case XK_KP_3: case XK_KP_Next: return 0x55; - case XK_KP_4: case XK_KP_Left: return 0x56; - case XK_KP_5: case XK_KP_Begin: return 0x57; - case XK_KP_6: case XK_KP_Right: return 0x58; - case XK_KP_7: case XK_KP_Home: return 0x59; - case XK_KP_8: case XK_KP_Up: return 0x5b; - case XK_KP_9: case XK_KP_Prior: return 0x5c; - case XK_KP_Decimal: case XK_KP_Delete: return 0x41; -#else - case XK_KP_0: return 0x52; - case XK_KP_1: return 0x53; - case XK_KP_2: return 0x54; - case XK_KP_3: return 0x55; - case XK_KP_4: return 0x56; - case XK_KP_5: return 0x57; - case XK_KP_6: return 0x58; - case XK_KP_7: return 0x59; - case XK_KP_8: return 0x5b; - case XK_KP_9: return 0x5c; - case XK_KP_Decimal: return 0x41; -#endif - case XK_KP_Add: return 0x45; - case XK_KP_Subtract: return 0x4e; - case XK_KP_Multiply: return 0x43; - case XK_KP_Divide: return 0x4b; - case XK_KP_Enter: return 0x4c; - case XK_KP_Equal: return 0x51; - } - return -1; -} - -static int event2keycode(XKeyEvent &ev, bool key_down) -{ - KeySym ks; - int i = 0; - - do { - ks = XLookupKeysym(&ev, i++); - int as = kc_decode(ks); - if (as >= 0) - return as; - if (as == -2) - return as; - } while (ks != NoSymbol); - - return -1; -} - -static void handle_events(void) -{ - // Handle events - for (;;) { - XEvent event; - - XDisplayLock(); - if (!XCheckMaskEvent(x_display, eventmask, &event)) { - // Handle clipboard events - if (XCheckTypedEvent(x_display, SelectionRequest, &event)) - ClipboardSelectionRequest(&event.xselectionrequest); - else if (XCheckTypedEvent(x_display, SelectionClear, &event)) - ClipboardSelectionClear(&event.xselectionclear); - - // Window "close" widget clicked - else if (XCheckTypedEvent(x_display, ClientMessage, &event)) { - if (event.xclient.format == 32 && event.xclient.data.l[0] == WM_DELETE_WINDOW) { - ADBKeyDown(0x7f); // Power key - ADBKeyUp(0x7f); - } - } - - XDisplayUnlock(); - break; - } - XDisplayUnlock(); - - switch (event.type) { - // Mouse button - case ButtonPress: { - unsigned int button = ((XButtonEvent *)&event)->button; - if (button < 4) - ADBMouseDown(button - 1); - else if (button < 6) { // Wheel mouse - if (mouse_wheel_mode == 0) { - int key = (button == 5) ? 0x79 : 0x74; // Page up/down - ADBKeyDown(key); - ADBKeyUp(key); - } else { - int key = (button == 5) ? 0x3d : 0x3e; // Cursor up/down - for(int i=0; ibutton; - if (button < 4) - ADBMouseUp(button - 1); - break; - } - - // Mouse entered window - case EnterNotify: - if (event.xcrossing.mode != NotifyGrab && event.xcrossing.mode != NotifyUngrab) - ADBMouseMoved(event.xmotion.x, event.xmotion.y); - break; - - // Mouse moved - case MotionNotify: - ADBMouseMoved(event.xmotion.x, event.xmotion.y); - break; - - // Keyboard - case KeyPress: { - int code = -1; - if (use_keycodes) { - if (event2keycode(event.xkey, true) != -2) // This is called to process the hotkeys - code = keycode_table[event.xkey.keycode & 0xff]; - } else - code = event2keycode(event.xkey, true); - if (code >= 0) { - if (!emul_suspended) { - if (code == 0x39) { // Caps Lock pressed - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyDown(code); - if (code == 0x36) - ctrl_down = true; - } else { - if (code == 0x31) - resume_emul(); // Space wakes us up - } - } - break; - } - case KeyRelease: { - int code = -1; - if (use_keycodes) { - if (event2keycode(event.xkey, false) != -2) // This is called to process the hotkeys - code = keycode_table[event.xkey.keycode & 0xff]; - } else - code = event2keycode(event.xkey, false); - if (code >= 0 && code != 0x39) { // Don't propagate Caps Lock releases - ADBKeyUp(code); - if (code == 0x36) - ctrl_down = false; - } - break; - } - - // Hidden parts exposed, force complete refresh - case Expose: -#ifdef ENABLE_VOSF - if (use_vosf) { // VOSF refresh - LOCK_VOSF; - PFLAG_SET_ALL; - memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - UNLOCK_VOSF; - } - else -#endif - memset(the_buffer_copy, 0, VModes[cur_mode].viRowBytes * VModes[cur_mode].viYsize); - break; - } - } -} - - -/* - * Execute video VBL routine - */ - -void VideoVBL(void) -{ - if (emerg_quit) - QuitEmulator(); - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; - - // Execute video VBL - if (private_data != NULL && private_data->interruptsEnabled) - VSLDoInterruptService(private_data->vslServiceID); -} - - -/* - * Change video mode - */ - -int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) -{ - /* return if no mode change */ - if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && - (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; - - /* first find video mode in table */ - for (int i=0; VModes[i].viType != DIS_INVALID; i++) { - if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && - (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { - csSave->saveMode = ReadMacInt16(ParamPtr + csMode); - csSave->saveData = ReadMacInt32(ParamPtr + csData); - csSave->savePage = ReadMacInt16(ParamPtr + csPage); - - // Disable interrupts and pause redraw thread - thread_stop_req = true; - sem_wait(&thread_stop_ack); - thread_stop_req = false; - DisableInterrupt(); - - /* close old display */ - close_display(); - - /* open new display */ - cur_mode = i; - bool ok = open_display(); - - /* opening the screen failed? Then bail out */ - if (!ok) { - ErrorAlert(GetString(STR_FULL_SCREEN_ERR)); - QuitEmulator(); - } - - WriteMacInt32(ParamPtr + csBaseAddr, screen_base); - csSave->saveBaseAddr=screen_base; - csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ - csSave->saveMode=VModes[cur_mode].viAppleMode; - - // Enable interrupts and resume redraw thread - EnableInterrupt(); - sem_post(&thread_resume_req); - return noErr; - } - } - return paramErr; -} - - -/* - * Set color palette - */ - -void video_set_palette(void) -{ - LOCK_PALETTE; - - // Convert colors to XColor array - int mode = get_current_mode(); - int num_in = palette_size(mode); - int num_out = 256; - bool stretch = false; - if (IsDirectMode(mode)) { - // If X is in 565 mode we have to stretch the gamma table from 32 to 64 entries - num_out = vis->map_entries; - stretch = true; - } - XColor *p = x_palette; - for (int i=0; ired = mac_pal[c].red * 0x0101; - p->green = mac_pal[c].green * 0x0101; - p->blue = mac_pal[c].blue * 0x0101; - p++; - } - -#ifdef ENABLE_VOSF - // Recalculate pixel color expansion map - if (!IsDirectMode(mode) && xdepth > 8) { - for (int i=0; i<256; i++) { - int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) - ExpandMap[i] = map_rgb(mac_pal[c].red, mac_pal[c].green, mac_pal[c].blue); - } - - // We have to redraw everything because the interpretation of pixel values changed - LOCK_VOSF; - PFLAG_SET_ALL; - if (display_type == DIS_SCREEN) - PFLAG_SET_VERY_DIRTY; - UNLOCK_VOSF; - } -#endif - - // Tell redraw thread to change palette - palette_changed = true; - - UNLOCK_PALETTE; -} - - -/* - * Can we set the MacOS cursor image into the window? - */ - -bool video_can_change_cursor(void) -{ - return hw_mac_cursor_accl && (display_type != DIS_SCREEN); -} - - -/* - * Set cursor image for window - */ - -void video_set_cursor(void) -{ - cursor_changed = true; -} - - -/* - * Thread for window refresh, event handling and other periodic actions - */ - -static void update_display(void) -{ - // Incremental update code - int wide = 0, high = 0, x1, x2, y1, y2, i, j; - int bytes_per_row = VModes[cur_mode].viRowBytes; - int bytes_per_pixel = VModes[cur_mode].viRowBytes / VModes[cur_mode].viXsize; - uint8 *p, *p2; - - // Check for first line from top and first line from bottom that have changed - y1 = 0; - for (j=0; j=y1; j--) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y2 = j; - break; - } - } - high = y2 - y1 + 1; - - // Check for first column from left and first column from right that have changed - if (high) { - if (depth == 1) { - x1 = VModes[cur_mode].viXsize; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (i=0; i<(x1>>3); i++) { - if (*p != *p2) { - x1 = i << 3; - break; - } - p++; - p2++; - } - } - x2 = x1; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (i=(VModes[cur_mode].viXsize>>3); i>(x2>>3); i--) { - p--; - p2--; - if (*p != *p2) { - x2 = i << 3; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - for (j=y1; j<=y2; j++) { - i = j * bytes_per_row + (x1 >> 3); - memcpy(&the_buffer_copy[i], &the_buffer[i], wide >> 3); - } - } - - } else { - x1 = VModes[cur_mode].viXsize; - for (j=y1; j<=y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (i=0; ix2; i--) { - p -= bytes_per_pixel; - p2 -= bytes_per_pixel; - if (memcmp(p, p2, bytes_per_pixel)) { - x2 = i; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - for (j=y1; j<=y2; j++) { - i = j * bytes_per_row + x1 * bytes_per_pixel; - memcpy(&the_buffer_copy[i], &the_buffer[i], bytes_per_pixel * wide); - } - } - } - } - - // Refresh display - if (high && wide) { - XDisplayLock(); - if (have_shm) - XShmPutImage(x_display, the_win, the_gc, img, x1, y1, x1, y1, wide, high, 0); - else - XPutImage(x_display, the_win, the_gc, img, x1, y1, x1, y1, wide, high); - XDisplayUnlock(); - } -} - -const int VIDEO_REFRESH_HZ = 60; -const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; - -static void handle_palette_changes(void) -{ - LOCK_PALETTE; - - if (palette_changed && !emul_suspended) { - palette_changed = false; - - int mode = get_current_mode(); - if (color_class == PseudoColor || color_class == DirectColor) { - int num = vis->map_entries; - bool set_clut = true; - if (!IsDirectMode(mode) && color_class == DirectColor) { - if (display_type == DIS_WINDOW) - set_clut = false; // Indexed mode on true color screen, don't set CLUT - } - - if (set_clut) { - XDisplayLock(); - XStoreColors(x_display, cmap[0], x_palette, num); - XStoreColors(x_display, cmap[1], x_palette, num); - XSync(x_display, false); - XDisplayUnlock(); - } - } - -#ifdef ENABLE_XF86_DGA - if (display_type == DIS_SCREEN && !is_fbdev_dga_mode) { - current_dga_cmap ^= 1; - if (!IsDirectMode(mode) && cmap[current_dga_cmap]) - XF86DGAInstallColormap(x_display, screen, cmap[current_dga_cmap]); - } -#endif - } - - UNLOCK_PALETTE; -} - -static void *redraw_func(void *arg) -{ - int fd = ConnectionNumber(x_display); - - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; - - while (!redraw_thread_cancel) { - - // Pause if requested (during video mode switches) - if (thread_stop_req) { - sem_post(&thread_stop_ack); - sem_wait(&thread_resume_req); - } - - int64 delay = next - GetTicks_usec(); - if (delay < -VIDEO_REFRESH_DELAY) { - - // We are lagging far behind, so we reset the delay mechanism - next = GetTicks_usec(); - - } else if (delay <= 0) { - - // Delay expired, refresh display - next += VIDEO_REFRESH_DELAY; - ticks++; - - // Handle X11 events - handle_events(); - - // Quit DGA mode if requested - if (quit_full_screen) { - quit_full_screen = false; - if (display_type == DIS_SCREEN) { - XDisplayLock(); -#if defined(ENABLE_XF86_DGA) || defined(ENABLE_FBDEV_DGA) -#ifdef ENABLE_XF86_DGA - if (!is_fbdev_dga_mode) - XF86DGADirectVideo(x_display, screen, 0); -#endif - XUngrabPointer(x_display, CurrentTime); - XUngrabKeyboard(x_display, CurrentTime); - XUnmapWindow(x_display, the_win); - wait_unmapped(the_win); - XDestroyWindow(x_display, the_win); -#endif - XSync(x_display, false); - XDisplayUnlock(); - quit_full_screen_ack = true; - return NULL; - } - } - - // Refresh display and set cursor image in window mode - static int tick_counter = 0; - if (display_type == DIS_WINDOW) { - tick_counter++; - if (tick_counter >= frame_skip) { - tick_counter = 0; - - // Update display -#ifdef ENABLE_VOSF - if (use_vosf) { - XDisplayLock(); - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_window_vosf(); - UNLOCK_VOSF; - XSync(x_display, false); // Let the server catch up - } - XDisplayUnlock(); - } - else -#endif - update_display(); - - // Set new cursor image if it was changed - if (hw_mac_cursor_accl && cursor_changed) { - cursor_changed = false; - uint8 *x_data = (uint8 *)cursor_image->data; - uint8 *x_mask = (uint8 *)cursor_mask_image->data; - for (int i = 0; i < 32; i++) { - x_mask[i] = MacCursor[4 + i] | MacCursor[36 + i]; - x_data[i] = MacCursor[4 + i]; - } - XDisplayLock(); - XFreeCursor(x_display, mac_cursor); - XPutImage(x_display, cursor_map, cursor_gc, cursor_image, 0, 0, 0, 0, 16, 16); - XPutImage(x_display, cursor_mask_map, cursor_mask_gc, cursor_mask_image, 0, 0, 0, 0, 16, 16); - mac_cursor = XCreatePixmapCursor(x_display, cursor_map, cursor_mask_map, &black, &white, MacCursor[2], MacCursor[3]); - XDefineCursor(x_display, the_win, mac_cursor); - XDisplayUnlock(); - } - } - } -#ifdef ENABLE_VOSF - else if (use_vosf) { - // Update display (VOSF variant) - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_dga_vosf(); - UNLOCK_VOSF; - } - } - } -#endif - - // Set new palette if it was changed - handle_palette_changes(); - - } else { - - // No display refresh pending, check for X events - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = delay; - if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) - handle_events(); - } - } - return NULL; -} - - -/* - * Record dirty area from NQD - */ - -void video_set_dirty_area(int x, int y, int w, int h) -{ - VideoInfo const & mode = VModes[cur_mode]; - const int screen_width = VIDEO_MODE_X; - const int screen_height = VIDEO_MODE_Y; - const int bytes_per_row = VIDEO_MODE_ROW_BYTES; - -#ifdef ENABLE_VOSF - if (use_vosf) { - vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); - return; - } -#endif - - // XXX handle dirty bounding boxes for non-VOSF modes -} From 876e4cfdd873bc43948528b770071188dfd60b84 Mon Sep 17 00:00:00 2001 From: Seg Date: Wed, 16 Jun 2021 22:55:27 -0700 Subject: [PATCH 15/24] Sync SheepShaver with BII SDL changes --- SheepShaver/Makefile | 4 +- SheepShaver/src/CrossPlatform/video_vosf.h | 687 +---- SheepShaver/src/SDL | 1 + SheepShaver/src/SDL/video_sdl.cpp | 2340 ---------------- SheepShaver/src/SDL/video_sdl2.cpp | 2869 -------------------- SheepShaver/src/Unix/main_unix.cpp | 44 +- SheepShaver/src/Windows/main_windows.cpp | 52 +- SheepShaver/src/include/cpu_emulation.h | 2 + 8 files changed, 57 insertions(+), 5942 deletions(-) mode change 100644 => 120000 SheepShaver/src/CrossPlatform/video_vosf.h create mode 120000 SheepShaver/src/SDL delete mode 100644 SheepShaver/src/SDL/video_sdl.cpp delete mode 100644 SheepShaver/src/SDL/video_sdl2.cpp diff --git a/SheepShaver/Makefile b/SheepShaver/Makefile index e5a036de3..cfc9e217b 100644 --- a/SheepShaver/Makefile +++ b/SheepShaver/Makefile @@ -61,8 +61,8 @@ links: include/timer.h include/xpram.h \ CrossPlatform/sigsegv.h \ CrossPlatform/video_blit.h CrossPlatform/video_blit.cpp \ - SDL/SDLMain.h SDL/SDLMain.m SDL/audio_sdl.cpp SDL/keycodes \ - SDL/prefs_sdl.cpp SDL/xpram_sdl.cpp \ + CrossPlatform/video_vosf.h \ + SDL \ Unix/vhd_unix.cpp \ Unix/extfs_unix.cpp Unix/serial_unix.cpp \ Unix/sshpty.h Unix/sshpty.c Unix/strlcpy.h Unix/strlcpy.c \ diff --git a/SheepShaver/src/CrossPlatform/video_vosf.h b/SheepShaver/src/CrossPlatform/video_vosf.h deleted file mode 100644 index f1d2f3add..000000000 --- a/SheepShaver/src/CrossPlatform/video_vosf.h +++ /dev/null @@ -1,686 +0,0 @@ -/* - * video_vosf.h - Video/graphics emulation, video on SEGV signals support - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef VIDEO_VOSF_H -#define VIDEO_VOSF_H - -// Note: this file must be #include'd only in video_x.cpp -#ifdef ENABLE_VOSF - -#include "sigsegv.h" -#include "vm_alloc.h" -#ifdef _WIN32 -#include "util_windows.h" -#endif - -// Import SDL-backend-specific functions -#ifdef USE_SDL_VIDEO -extern void update_sdl_video(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h); -extern void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects); -#endif - -// Glue for SDL and X11 support -#ifdef TEST_VOSF_PERFORMANCE -#define MONITOR_INIT /* nothing */ -#else -#ifdef USE_SDL_VIDEO -#define MONITOR_INIT SDL_monitor_desc &monitor -#define VIDEO_DRV_WIN_INIT driver_base *drv -#define VIDEO_DRV_DGA_INIT driver_base *drv -#define VIDEO_DRV_LOCK_PIXELS SDL_VIDEO_LOCK_SURFACE(drv->s) -#define VIDEO_DRV_UNLOCK_PIXELS SDL_VIDEO_UNLOCK_SURFACE(drv->s) -#define VIDEO_DRV_DEPTH drv->s->format->BitsPerPixel -#define VIDEO_DRV_WIDTH drv->s->w -#define VIDEO_DRV_HEIGHT drv->s->h -#define VIDEO_DRV_ROW_BYTES drv->s->pitch -#else -#ifdef SHEEPSHAVER -#define MONITOR_INIT /* nothing */ -#define VIDEO_DRV_WIN_INIT /* nothing */ -#define VIDEO_DRV_DGA_INIT /* nothing */ -#define VIDEO_DRV_WINDOW the_win -#define VIDEO_DRV_GC the_gc -#define VIDEO_DRV_IMAGE img -#define VIDEO_DRV_HAVE_SHM have_shm -#else -#define MONITOR_INIT X11_monitor_desc &monitor -#define VIDEO_DRV_WIN_INIT driver_window *drv -#define VIDEO_DRV_DGA_INIT driver_dga *drv -#define VIDEO_DRV_WINDOW drv->w -#define VIDEO_DRV_GC drv->gc -#define VIDEO_DRV_IMAGE drv->img -#define VIDEO_DRV_HAVE_SHM drv->have_shm -#endif -#define VIDEO_DRV_LOCK_PIXELS /* nothing */ -#define VIDEO_DRV_UNLOCK_PIXELS /* nothing */ -#define VIDEO_DRV_DEPTH VIDEO_DRV_IMAGE->depth -#define VIDEO_DRV_WIDTH VIDEO_DRV_IMAGE->width -#define VIDEO_DRV_HEIGHT VIDEO_DRV_IMAGE->height -#define VIDEO_DRV_ROW_BYTES VIDEO_DRV_IMAGE->bytes_per_line -#endif -#endif - -// Prototypes -static void vosf_do_set_dirty_area(uintptr first, uintptr last); -static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_width, unsigned screen_height, unsigned bytes_per_row); - -// Variables for Video on SEGV support -static uint8 *the_host_buffer; // Host frame buffer in VOSF mode - -struct ScreenPageInfo { - unsigned top, bottom; // Mapping between this virtual page and Mac scanlines -}; - -struct ScreenInfo { - uintptr memStart; // Start address aligned to page boundary - uint32 memLength; // Length of the memory addressed by the screen pages - - uintptr pageSize; // Size of a page - int pageBits; // Shift count to get the page number - uint32 pageCount; // Number of pages allocated to the screen - - bool dirty; // Flag: set if the frame buffer was touched - bool very_dirty; // Flag: set if the frame buffer was completely modified (e.g. colormap changes) - char * dirtyPages; // Table of flags set if page was altered - ScreenPageInfo * pageInfo; // Table of mappings page -> Mac scanlines -}; - -static ScreenInfo mainBuffer; - -#define PFLAG_SET_VALUE 0x00 -#define PFLAG_CLEAR_VALUE 0x01 -#define PFLAG_SET_VALUE_4 0x00000000 -#define PFLAG_CLEAR_VALUE_4 0x01010101 -#define PFLAG_SET(page) mainBuffer.dirtyPages[page] = PFLAG_SET_VALUE -#define PFLAG_CLEAR(page) mainBuffer.dirtyPages[page] = PFLAG_CLEAR_VALUE -#define PFLAG_ISSET(page) (mainBuffer.dirtyPages[page] == PFLAG_SET_VALUE) -#define PFLAG_ISCLEAR(page) (mainBuffer.dirtyPages[page] != PFLAG_SET_VALUE) - -#ifdef UNALIGNED_PROFITABLE -# define PFLAG_ISSET_4(page) (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_SET_VALUE_4) -# define PFLAG_ISCLEAR_4(page) (*((uint32 *)(mainBuffer.dirtyPages + (page))) == PFLAG_CLEAR_VALUE_4) -#else -# define PFLAG_ISSET_4(page) \ - PFLAG_ISSET(page ) && PFLAG_ISSET(page+1) \ - && PFLAG_ISSET(page+2) && PFLAG_ISSET(page+3) -# define PFLAG_ISCLEAR_4(page) \ - PFLAG_ISCLEAR(page ) && PFLAG_ISCLEAR(page+1) \ - && PFLAG_ISCLEAR(page+2) && PFLAG_ISCLEAR(page+3) -#endif - -// Set the selected page range [ first_page, last_page [ into the SET state -#define PFLAG_SET_RANGE(first_page, last_page) \ - memset(mainBuffer.dirtyPages + (first_page), PFLAG_SET_VALUE, \ - (last_page) - (first_page)) - -// Set the selected page range [ first_page, last_page [ into the CLEAR state -#define PFLAG_CLEAR_RANGE(first_page, last_page) \ - memset(mainBuffer.dirtyPages + (first_page), PFLAG_CLEAR_VALUE, \ - (last_page) - (first_page)) - -#define PFLAG_SET_ALL do { \ - PFLAG_SET_RANGE(0, mainBuffer.pageCount); \ - mainBuffer.dirty = true; \ -} while (0) - -#define PFLAG_CLEAR_ALL do { \ - PFLAG_CLEAR_RANGE(0, mainBuffer.pageCount); \ - mainBuffer.dirty = false; \ - mainBuffer.very_dirty = false; \ -} while (0) - -#define PFLAG_SET_VERY_DIRTY do { \ - mainBuffer.very_dirty = true; \ -} while (0) - -// Set the following macro definition to 1 if your system -// provides a really fast strchr() implementation -//#define HAVE_FAST_STRCHR 0 - -static inline unsigned find_next_page_set(unsigned page) -{ -#if HAVE_FAST_STRCHR - char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_SET_VALUE); - return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount; -#else - while (PFLAG_ISCLEAR_4(page)) - page += 4; - while (PFLAG_ISCLEAR(page)) - page++; - return page; -#endif -} - -static inline unsigned find_next_page_clear(unsigned page) -{ -#if HAVE_FAST_STRCHR - char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_CLEAR_VALUE); - return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount; -#else - while (PFLAG_ISSET_4(page)) - page += 4; - while (PFLAG_ISSET(page)) - page++; - return page; -#endif -} - -#if defined(HAVE_PTHREADS) -static pthread_mutex_t vosf_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect frame buffer (dirtyPages in fact) -#define LOCK_VOSF pthread_mutex_lock(&vosf_lock); -#define UNLOCK_VOSF pthread_mutex_unlock(&vosf_lock); -#elif defined(_WIN32) -static mutex_t vosf_lock; // Mutex to protect frame buffer (dirtyPages in fact) -#define LOCK_VOSF vosf_lock.lock(); -#define UNLOCK_VOSF vosf_lock.unlock(); -#elif defined(HAVE_SPINLOCKS) -static spinlock_t vosf_lock = SPIN_LOCK_UNLOCKED; // Mutex to protect frame buffer (dirtyPages in fact) -#define LOCK_VOSF spin_lock(&vosf_lock) -#define UNLOCK_VOSF spin_unlock(&vosf_lock) -#else -#define LOCK_VOSF -#define UNLOCK_VOSF -#endif - -static int log_base_2(uint32 x) -{ - uint32 mask = 0x80000000; - int l = 31; - while (l >= 0 && (x & mask) == 0) { - mask >>= 1; - l--; - } - return l; -} - -// Extend size to page boundary -static uint32 page_extend(uint32 size) -{ - const uint32 page_size = vm_get_page_size(); - const uint32 page_mask = page_size - 1; - return (size + page_mask) & ~page_mask; -} - - -/* - * Check if VOSF acceleration is profitable on this platform - */ - -#ifndef VOSF_PROFITABLE_TRIES -#define VOSF_PROFITABLE_TRIES VOSF_PROFITABLE_TRIES_DFL -#endif -const int VOSF_PROFITABLE_TRIES_DFL = 3; // Make 3 attempts for full screen update -const int VOSF_PROFITABLE_THRESHOLD = 16667/2; // 60 Hz (half of the quantum) - -static bool video_vosf_profitable(uint32 *duration_p = NULL, uint32 *n_page_faults_p = NULL) -{ - uint32 duration = 0; - uint32 n_tries = VOSF_PROFITABLE_TRIES; - const uint32 n_page_faults = mainBuffer.pageCount * n_tries; - -#ifdef SHEEPSHAVER - const bool accel = PrefsFindBool("gfxaccel"); -#else - const bool accel = false; -#endif - - for (uint32 i = 0; i < n_tries; i++) { - uint64 start = GetTicks_usec(); - for (uint32 p = 0; p < mainBuffer.pageCount; p++) { - uint8 *addr = (uint8 *)(mainBuffer.memStart + (p * mainBuffer.pageSize)); - if (accel) - vosf_do_set_dirty_area((uintptr)addr, (uintptr)addr + mainBuffer.pageSize - 1); - else - addr[0] = 0; // Trigger Screen_fault_handler() - } - duration += uint32(GetTicks_usec() - start); - - PFLAG_CLEAR_ALL; - mainBuffer.dirty = false; - if (vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ) != 0) - return false; - } - - if (duration_p) - *duration_p = duration; - if (n_page_faults_p) - *n_page_faults_p = n_page_faults; - - D(bug("Triggered %d page faults in %ld usec (%.1f usec per fault)\n", n_page_faults, duration, double(duration) / double(n_page_faults))); - return ((duration / n_tries) < (VOSF_PROFITABLE_THRESHOLD * (frame_skip ? frame_skip : 1))); -} - - -/* - * Initialize the VOSF system (mainBuffer structure, SIGSEGV handler) - */ - -static bool video_vosf_init(MONITOR_INIT) -{ - VIDEO_MODE_INIT_MONITOR; - - const uintptr page_size = vm_get_page_size(); - const uintptr page_mask = page_size - 1; - - // Round up frame buffer base to page boundary - mainBuffer.memStart = (((uintptr) the_buffer) + page_mask) & ~page_mask; - - // The frame buffer size shall already be aligned to page boundary (use page_extend) - mainBuffer.memLength = the_buffer_size; - - mainBuffer.pageSize = page_size; - mainBuffer.pageBits = log_base_2(mainBuffer.pageSize); - mainBuffer.pageCount = (mainBuffer.memLength + page_mask)/mainBuffer.pageSize; - - // The "2" more bytes requested are a safety net to insure the - // loops in the update routines will terminate. - // See "How can we deal with array overrun conditions ?" hereunder for further details. - mainBuffer.dirtyPages = (char *) malloc(mainBuffer.pageCount + 2); - if (mainBuffer.dirtyPages == NULL) - return false; - - PFLAG_CLEAR_ALL; - PFLAG_CLEAR(mainBuffer.pageCount); - PFLAG_SET(mainBuffer.pageCount+1); - - // Allocate and fill in pageInfo with start and end (inclusive) row in number of bytes - mainBuffer.pageInfo = (ScreenPageInfo *) malloc(mainBuffer.pageCount * sizeof(ScreenPageInfo)); - if (mainBuffer.pageInfo == NULL) - return false; - - uint32 a = 0; - for (unsigned i = 0; i < mainBuffer.pageCount; i++) { - unsigned y1 = a / VIDEO_MODE_ROW_BYTES; - if (y1 >= VIDEO_MODE_Y) - y1 = VIDEO_MODE_Y - 1; - - unsigned y2 = (a + mainBuffer.pageSize) / VIDEO_MODE_ROW_BYTES; - if (y2 >= VIDEO_MODE_Y) - y2 = VIDEO_MODE_Y - 1; - - mainBuffer.pageInfo[i].top = y1; - mainBuffer.pageInfo[i].bottom = y2; - - a += mainBuffer.pageSize; - if (a > mainBuffer.memLength) - a = mainBuffer.memLength; - } - - // We can now write-protect the frame buffer - if (vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ) != 0) - return false; - - // The frame buffer is sane, i.e. there is no write to it yet - mainBuffer.dirty = false; - return true; -} - - -/* - * Deinitialize VOSF system - */ - -static void video_vosf_exit(void) -{ - if (mainBuffer.pageInfo) { - free(mainBuffer.pageInfo); - mainBuffer.pageInfo = NULL; - } - if (mainBuffer.dirtyPages) { - free(mainBuffer.dirtyPages); - mainBuffer.dirtyPages = NULL; - } -} - - -/* - * Update VOSF state with specified dirty area - */ - -static void vosf_do_set_dirty_area(uintptr first, uintptr last) -{ - const int first_page = (first - mainBuffer.memStart) >> mainBuffer.pageBits; - const int last_page = (last - mainBuffer.memStart) >> mainBuffer.pageBits; - uint8 *addr = (uint8 *)(first & ~(mainBuffer.pageSize - 1)); - for (int i = first_page; i <= last_page; i++) { - if (PFLAG_ISCLEAR(i)) { - PFLAG_SET(i); - vm_protect(addr, mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); - } - addr += mainBuffer.pageSize; - } -} - -static void vosf_set_dirty_area(int x, int y, int w, int h, unsigned screen_width, unsigned screen_height, unsigned bytes_per_row) -{ - if (x < 0) { - w -= -x; - x = 0; - } - if (y < 0) { - h -= -y; - y = 0; - } - if (w <= 0 || h <= 0) - return; - if (unsigned(x + w) > screen_width) - w -= unsigned(x + w) - screen_width; - if (unsigned(y + h) > screen_height) - h -= unsigned(y + h) - screen_height; - LOCK_VOSF; - if (bytes_per_row >= screen_width) { - const int bytes_per_pixel = bytes_per_row / screen_width; - if (bytes_per_row <= mainBuffer.pageSize) { - const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x * bytes_per_pixel; - const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) * bytes_per_pixel; - vosf_do_set_dirty_area(a0, a1); - } else { - for (int j = y; j < y + h; j++) { - const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x * bytes_per_pixel; - const uintptr a1 = a0 + (w - 1) * bytes_per_pixel; - vosf_do_set_dirty_area(a0, a1); - } - } - } else { - const int pixels_per_byte = screen_width / bytes_per_row; - if (bytes_per_row <= mainBuffer.pageSize) { - const uintptr a0 = mainBuffer.memStart + y * bytes_per_row + x / pixels_per_byte; - const uintptr a1 = mainBuffer.memStart + (y + h - 1) * bytes_per_row + (x + w - 1) / pixels_per_byte; - vosf_do_set_dirty_area(a0, a1); - } else { - for (int j = y; j < y + h; j++) { - const uintptr a0 = mainBuffer.memStart + j * bytes_per_row + x / pixels_per_byte; - const uintptr a1 = mainBuffer.memStart + j * bytes_per_row + (x + w - 1) / pixels_per_byte; - vosf_do_set_dirty_area(a0, a1); - } - } - } - mainBuffer.dirty = true; - UNLOCK_VOSF; -} - - -/* - * Screen fault handler - */ - -bool Screen_fault_handler(sigsegv_info_t *sip) -{ - const uintptr addr = (uintptr)sigsegv_get_fault_address(sip); - - /* Someone attempted to write to the frame buffer. Make it writeable - * now so that the data could actually be written to. It will be made - * read-only back in one of the screen update_*() functions. - */ - if (((uintptr)addr - mainBuffer.memStart) < mainBuffer.memLength) { - const int page = ((uintptr)addr - mainBuffer.memStart) >> mainBuffer.pageBits; - LOCK_VOSF; - if (PFLAG_ISCLEAR(page)) { - PFLAG_SET(page); - vm_protect((char *)(addr & ~(mainBuffer.pageSize - 1)), mainBuffer.pageSize, VM_PAGE_READ | VM_PAGE_WRITE); - } - mainBuffer.dirty = true; - UNLOCK_VOSF; - return true; - } - - /* Otherwise, we don't know how to handle the fault, let it crash */ - return false; -} - - -/* - * Update display for Windowed mode and VOSF - */ - -/* How can we deal with array overrun conditions ? - - The state of the framebuffer pages that have been touched are maintained - in the dirtyPages[] table. That table is (pageCount + 2) bytes long. - -Terminology - - "Last Page" denotes the pageCount-nth page, i.e. dirtyPages[pageCount - 1]. - "CLEAR Page Guard" refers to the page following the Last Page but is always - in the CLEAR state. "SET Page Guard" refers to the page following the CLEAR - Page Guard but is always in the SET state. - -Rough process - - The update routines must determine which pages have to be blitted to the - screen. This job consists in finding the first_page that was touched. - i.e. find the next page that is SET. Then, finding how many pages were - touched starting from first_page. i.e. find the next page that is CLEAR. - -There are two cases to check: - - - Last Page is CLEAR: find_next_page_set() will reach the SET Page Guard - but it is beyond the valid pageCount value. Therefore, we exit from the - update routine. - - - Last Page is SET: first_page equals (pageCount - 1) and - find_next_page_clear() will reach the CLEAR Page Guard. We blit the last - page to the screen. On the next iteration, page equals pageCount and - find_next_page_set() will reach the SET Page Guard. We still safely exit - from the update routine because the SET Page Guard position is greater - than pageCount. -*/ - -#ifndef TEST_VOSF_PERFORMANCE -static void update_display_window_vosf(VIDEO_DRV_WIN_INIT) -{ - VIDEO_MODE_INIT; - - unsigned page = 0; - for (;;) { - const unsigned first_page = find_next_page_set(page); - if (first_page >= mainBuffer.pageCount) - break; - - page = find_next_page_clear(first_page); - PFLAG_CLEAR_RANGE(first_page, page); - - // Make the dirty pages read-only again - const int32 offset = first_page << mainBuffer.pageBits; - const uint32 length = (page - first_page) << mainBuffer.pageBits; - vm_protect((char *)mainBuffer.memStart + offset, length, VM_PAGE_READ); - - // There is at least one line to update - const int y1 = mainBuffer.pageInfo[first_page].top; - const int y2 = mainBuffer.pageInfo[page - 1].bottom; - const int height = y2 - y1 + 1; - - // Update the_host_buffer - VIDEO_DRV_LOCK_PIXELS; - const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; - const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES; - int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j; - for (j = y1; j <= y2; j++) { - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); - i1 += src_bytes_per_row; - i2 += dst_bytes_per_row; - } - VIDEO_DRV_UNLOCK_PIXELS; - -#ifdef USE_SDL_VIDEO - update_sdl_video(drv->s, 0, y1, VIDEO_MODE_X, height); -#else - if (VIDEO_DRV_HAVE_SHM) - XShmPutImage(x_display, VIDEO_DRV_WINDOW, VIDEO_DRV_GC, VIDEO_DRV_IMAGE, 0, y1, 0, y1, VIDEO_MODE_X, height, 0); - else - XPutImage(x_display, VIDEO_DRV_WINDOW, VIDEO_DRV_GC, VIDEO_DRV_IMAGE, 0, y1, 0, y1, VIDEO_MODE_X, height); -#endif - } - mainBuffer.dirty = false; -} -#endif - - -/* - * Update display for DGA mode and VOSF - * (only in Real or Direct Addressing mode) - */ - -#ifndef TEST_VOSF_PERFORMANCE -#if REAL_ADDRESSING || DIRECT_ADDRESSING - -static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) -{ - VIDEO_MODE_INIT; - - // Compute number of bytes per row, take care to virtual screens - const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES; - const int dst_bytes_per_row = TrivialBytesPerRow(VIDEO_MODE_X, DepthModeForPixelDepth(VIDEO_DRV_DEPTH)); - const int scr_bytes_per_row = VIDEO_DRV_ROW_BYTES; - assert(dst_bytes_per_row <= scr_bytes_per_row); - const int scr_bytes_left = scr_bytes_per_row - dst_bytes_per_row; - - // Full screen update requested? - if (mainBuffer.very_dirty) { - PFLAG_CLEAR_ALL; - vm_protect((char *)mainBuffer.memStart, mainBuffer.memLength, VM_PAGE_READ); - memcpy(the_buffer_copy, the_buffer, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); - VIDEO_DRV_LOCK_PIXELS; - int i1 = 0, i2 = 0; - for (uint32_t j = 0; j < VIDEO_MODE_Y; j++) { - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row); - i1 += src_bytes_per_row; - i2 += scr_bytes_per_row; - } -#ifdef USE_SDL_VIDEO - update_sdl_video(drv->s, 0, 0, VIDEO_MODE_X, VIDEO_MODE_Y); -#endif - VIDEO_DRV_UNLOCK_PIXELS; - return; - } - - // Setup partial blitter (use 64-pixel wide chunks) - const uint32 n_pixels = 64; - const uint32 n_chunks = VIDEO_MODE_X / n_pixels; - const uint32 n_pixels_left = VIDEO_MODE_X - (n_chunks * n_pixels); - const uint32 src_chunk_size = TrivialBytesPerRow(n_pixels, VIDEO_MODE_DEPTH); - const uint32 dst_chunk_size = TrivialBytesPerRow(n_pixels, DepthModeForPixelDepth(VIDEO_DRV_DEPTH)); - assert(src_chunk_size * n_chunks <= src_bytes_per_row); - assert(dst_chunk_size * n_chunks <= dst_bytes_per_row); - const uint32 src_chunk_size_left = src_bytes_per_row - (n_chunks * src_chunk_size); - const uint32 dst_chunk_size_left = dst_bytes_per_row - (n_chunks * dst_chunk_size); - - unsigned page = 0; - uint32 last_scanline = uint32(-1); - for (;;) { - const unsigned first_page = find_next_page_set(page); - if (first_page >= mainBuffer.pageCount) - break; - - page = find_next_page_clear(first_page); - PFLAG_CLEAR_RANGE(first_page, page); - - // Make the dirty pages read-only again - const int32 offset = first_page << mainBuffer.pageBits; - const uint32 length = (page - first_page) << mainBuffer.pageBits; - vm_protect((char *)mainBuffer.memStart + offset, length, VM_PAGE_READ); - - // Optimized for scanlines, don't process overlapping lines again - uint32 y1 = mainBuffer.pageInfo[first_page].top; - uint32 y2 = mainBuffer.pageInfo[page - 1].bottom; - if (last_scanline != uint32(-1)) { - if (y1 <= last_scanline && ++y1 >= VIDEO_MODE_Y) - continue; - if (y2 <= last_scanline && ++y2 >= VIDEO_MODE_Y) - continue; - } - last_scanline = y2; - - // Update the_host_buffer and copy of the_buffer, one line at a time - uint32 i1 = y1 * src_bytes_per_row; - uint32 i2 = y1 * scr_bytes_per_row; -#ifdef USE_SDL_VIDEO - int bbi = 0; - SDL_Rect bb[3] = { - { Sint16(VIDEO_MODE_X), Sint16(y1), 0, 0 }, - { Sint16(VIDEO_MODE_X), -1, 0, 0 }, - { Sint16(VIDEO_MODE_X), -1, 0, 0 } - }; -#endif - VIDEO_DRV_LOCK_PIXELS; - for (uint32 j = y1; j <= y2; j++) { - for (uint32 i = 0; i < n_chunks; i++) { - if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size) != 0) { - memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size); - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size); -#ifdef USE_SDL_VIDEO - const int x = i * n_pixels; - if (x < bb[bbi].x) { - if (bb[bbi].w) - bb[bbi].w += bb[bbi].x - x; - else - bb[bbi].w = n_pixels; - bb[bbi].x = x; - } - else if (x >= bb[bbi].x + bb[bbi].w) - bb[bbi].w = x + n_pixels - bb[bbi].x; -#endif - } - i1 += src_chunk_size; - i2 += dst_chunk_size; - } - if (src_chunk_size_left && dst_chunk_size_left) { - if (memcmp(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left) != 0) { - memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left); - Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size_left); - } -#ifdef USE_SDL_VIDEO - const int x = n_chunks * n_pixels; - if (x < bb[bbi].x) { - if (bb[bbi].w) - bb[bbi].w += bb[bbi].x - x; - else - bb[bbi].w = n_pixels_left; - bb[bbi].x = x; - } - else if (x >= bb[bbi].x + bb[bbi].w) - bb[bbi].w = x + n_pixels_left - bb[bbi].x; -#endif - } - i1 += src_chunk_size_left; - i2 += dst_chunk_size_left + scr_bytes_left; -#ifdef USE_SDL_VIDEO - bb[bbi].h++; - if (bb[bbi].w && (j == y1 || j == y2 - 1 || j == y2)) { - bbi++; - assert(bbi <= 3); - if (j != y2) - bb[bbi].y = j + 1; - } -#endif - } -#ifdef USE_SDL_VIDEO - update_sdl_video(drv->s, bbi, bb); -#endif - VIDEO_DRV_UNLOCK_PIXELS; - } - mainBuffer.dirty = false; -} -#endif -#endif - -#endif /* ENABLE_VOSF */ - -#endif /* VIDEO_VOSF_H */ diff --git a/SheepShaver/src/CrossPlatform/video_vosf.h b/SheepShaver/src/CrossPlatform/video_vosf.h new file mode 120000 index 000000000..4c552311a --- /dev/null +++ b/SheepShaver/src/CrossPlatform/video_vosf.h @@ -0,0 +1 @@ +../../../BasiliskII/src/CrossPlatform/video_vosf.h \ No newline at end of file diff --git a/SheepShaver/src/SDL b/SheepShaver/src/SDL new file mode 120000 index 000000000..48cb61ebe --- /dev/null +++ b/SheepShaver/src/SDL @@ -0,0 +1 @@ +../../BasiliskII/src/SDL \ No newline at end of file diff --git a/SheepShaver/src/SDL/video_sdl.cpp b/SheepShaver/src/SDL/video_sdl.cpp deleted file mode 100644 index 395778a00..000000000 --- a/SheepShaver/src/SDL/video_sdl.cpp +++ /dev/null @@ -1,2340 +0,0 @@ -/* - * video_sdl.cpp - Video/graphics emulation, SDL 1.x specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * The Ctrl key works like a qualifier for special actions: - * Ctrl-Tab = suspend DGA mode (TODO) - * Ctrl-Esc = emergency quit - * Ctrl-F1 = mount floppy - * Ctrl-F5 = grab mouse (in windowed mode) - * - * FIXMEs and TODOs: - * - Windows requires an extra mouse event to update the actual cursor image? - * - Ctr-Tab for suspend/resume but how? SDL does not support that for non-Linux - * - Ctrl-Fn doesn't generate SDL_KEYDOWN events (SDL bug?) - * - Mouse acceleration, there is no API in SDL yet for that - * - Force relative mode in Grab mode even if SDL provides absolute coordinates? - * - Gamma tables support is likely to be broken here - * - Events processing is bound to the general emulation thread as SDL requires - * to PumpEvents() within the same thread as the one that called SetVideoMode(). - * Besides, there can't seem to be a way to call SetVideoMode() from a child thread. - * - Backport hw cursor acceleration to Basilisk II? - * - Factor out code - */ - -#include "sysdeps.h" - -#include -#if (SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)) - -#include -#include -#include -#include - -#ifdef WIN32 -#include /* alloca() */ -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "adb.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" -#include "video_defs.h" -#include "video_blit.h" -#include "vm_alloc.h" - -#define DEBUG 0 -#include "debug.h" - -// Supported video modes -using std::vector; -static vector VideoModes; - -// Display types -#ifdef SHEEPSHAVER -enum { - DISPLAY_WINDOW = DIS_WINDOW, // windowed display - DISPLAY_SCREEN = DIS_SCREEN // fullscreen display -}; -extern int display_type; // See enum above -#else -enum { - DISPLAY_WINDOW, // windowed display - DISPLAY_SCREEN // fullscreen display -}; -static int display_type = DISPLAY_WINDOW; // See enum above -#endif - -// Constants -#if defined(WIN32) || __MACOSX__ -const char KEYCODE_FILE_NAME[] = "BasiliskII_keycodes"; -#else -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; -#endif - - -// Global variables -static uint32 frame_skip; // Prefs items -static int16 mouse_wheel_mode; -static int16 mouse_wheel_lines; - -static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) -static uint32 the_buffer_size; // Size of allocated the_buffer - -static bool redraw_thread_active = false; // Flag: Redraw thread installed -#ifndef USE_CPU_EMUL_SERVICES -static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread -static SDL_Thread *redraw_thread = NULL; // Redraw thread -static volatile bool thread_stop_req = false; -static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req -#endif - -#ifdef ENABLE_VOSF -static bool use_vosf = false; // Flag: VOSF enabled -#else -static const bool use_vosf = false; // VOSF not possible -#endif - -static bool ctrl_down = false; // Flag: Ctrl key pressed -static bool caps_on = false; // Flag: Caps Lock on -static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread -static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread -static bool emul_suspended = false; // Flag: Emulator suspended - -static bool classic_mode = false; // Flag: Classic Mac video mode - -static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms -static int keycode_table[256]; // X keycode -> Mac keycode translation table - -// SDL variables -static int screen_depth; // Depth of current screen -static SDL_Cursor *sdl_cursor; // Copy of Mac cursor -static SDL_Color sdl_palette[256]; // Color palette to be used as CLUT and gamma table -static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors -static bool toggle_fullscreen = false; -static const int sdl_eventmask = SDL_MOUSEEVENTMASK | SDL_KEYEVENTMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK | SDL_ACTIVEEVENTMASK; - -static bool mouse_grabbed = false; -static bool mouse_grabbed_window_name_status = false; - -// Mutex to protect SDL events -static SDL_mutex *sdl_events_lock = NULL; -#define LOCK_EVENTS SDL_LockMutex(sdl_events_lock) -#define UNLOCK_EVENTS SDL_UnlockMutex(sdl_events_lock) - -// Mutex to protect palette -static SDL_mutex *sdl_palette_lock = NULL; -#define LOCK_PALETTE SDL_LockMutex(sdl_palette_lock) -#define UNLOCK_PALETTE SDL_UnlockMutex(sdl_palette_lock) - -// Mutex to protect frame buffer -static SDL_mutex *frame_buffer_lock = NULL; -#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock) -#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock) - -// Previously set gamma tables -static uint16 last_gamma_red[256]; -static uint16 last_gamma_green[256]; -static uint16 last_gamma_blue[256]; - -// Video refresh function -static void VideoRefreshInit(void); -static void (*video_refresh)(void); - - -// Prototypes -static int redraw_func(void *arg); - -// From sys_unix.cpp -extern void SysMountFirstFloppy(void); - - -/* - * SDL surface locking glue - */ - -#ifdef ENABLE_VOSF -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ - if ((SURFACE)->flags & (SDL_HWSURFACE | SDL_FULLSCREEN)) \ - the_host_buffer = (uint8 *)(SURFACE)->pixels; \ -} while (0) -#else -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) -#endif - -#define SDL_VIDEO_LOCK_SURFACE(SURFACE) do { \ - if (SDL_MUSTLOCK(SURFACE)) { \ - SDL_LockSurface(SURFACE); \ - SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE); \ - } \ -} while (0) - -#define SDL_VIDEO_UNLOCK_SURFACE(SURFACE) do { \ - if (SDL_MUSTLOCK(SURFACE)) \ - SDL_UnlockSurface(SURFACE); \ -} while (0) - - -/* - * Framebuffer allocation routines - */ - -static void *vm_acquire_framebuffer(uint32 size) -{ - // always try to reallocate framebuffer at the same address - static void *fb = VM_MAP_FAILED; - if (fb != VM_MAP_FAILED) { - if (vm_acquire_fixed(fb, size) < 0) { -#ifndef SHEEPSHAVER - printf("FATAL: Could not reallocate framebuffer at previous address\n"); -#endif - fb = VM_MAP_FAILED; - } - } - if (fb == VM_MAP_FAILED) - fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return fb; -} - -static inline void vm_release_framebuffer(void *fb, uint32 size) -{ - vm_release(fb, size); -} - -static inline int get_customized_color_depth(int default_depth) -{ - int display_color_depth = PrefsFindInt32("displaycolordepth"); - - D(bug("Get displaycolordepth %d\n", display_color_depth)); - - if(0 == display_color_depth) - return default_depth; - else{ - switch (display_color_depth) { - case 8: - return VIDEO_DEPTH_8BIT; - case 15: case 16: - return VIDEO_DEPTH_16BIT; - case 24: case 32: - return VIDEO_DEPTH_32BIT; - default: - return default_depth; - } - } -} - -/* - * Windows message handler - */ - -#ifdef WIN32 -#include -static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL - -extern void SysMediaArrived(void); -extern void SysMediaRemoved(void); -extern HWND GetMainWindowHandle(void); - -static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_DEVICECHANGE: - if (wParam == DBT_DEVICEREMOVECOMPLETE) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaRemoved(); - } - else if (wParam == DBT_DEVICEARRIVAL) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaArrived(); - } - return 0; - - default: - if (sdl_window_proc) - return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} -#endif - - -/* - * SheepShaver glue - */ - -#ifdef SHEEPSHAVER -// Color depth modes type -typedef int video_depth; - -// 1, 2, 4 and 8 bit depths use a color palette -static inline bool IsDirectMode(VIDEO_MODE const & mode) -{ - return IsDirectMode(mode.viAppleMode); -} - -// Abstract base class representing one (possibly virtual) monitor -// ("monitor" = rectangular display with a contiguous frame buffer) -class monitor_desc { -public: - monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) {} - virtual ~monitor_desc() {} - - // Get current Mac frame buffer base address - uint32 get_mac_frame_base(void) const {return screen_base;} - - // Set Mac frame buffer base address (called from switch_to_mode()) - void set_mac_frame_base(uint32 base) {screen_base = base;} - - // Get current video mode - const VIDEO_MODE &get_current_mode(void) const {return VModes[cur_mode];} - - // Called by the video driver to switch the video mode on this display - // (must call set_mac_frame_base()) - virtual void switch_to_current_mode(void) = 0; - - // Called by the video driver to set the color palette (in indexed modes) - // or the gamma table (in direct modes) - virtual void set_palette(uint8 *pal, int num) = 0; -}; - -// Vector of pointers to available monitor descriptions, filled by VideoInit() -static vector VideoMonitors; - -// Find Apple mode matching best specified dimensions -static int find_apple_resolution(int xsize, int ysize) -{ - if (xsize == 640 && ysize == 480) - return APPLE_640x480; - if (xsize == 800 && ysize == 600) - return APPLE_800x600; - if (xsize == 1024 && ysize == 768) - return APPLE_1024x768; - if (xsize == 1152 && ysize == 768) - return APPLE_1152x768; - if (xsize == 1152 && ysize == 900) - return APPLE_1152x900; - if (xsize == 1280 && ysize == 1024) - return APPLE_1280x1024; - if (xsize == 1600 && ysize == 1200) - return APPLE_1600x1200; - return APPLE_CUSTOM; -} - -// Display error alert -static void ErrorAlert(int error) -{ - ErrorAlert(GetString(error)); -} -#endif - - -/* - * monitor_desc subclass for SDL display - */ - -class SDL_monitor_desc : public monitor_desc { -public: - SDL_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~SDL_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * Utility functions - */ - -// Find palette size for given color depth -static int palette_size(int mode) -{ - switch (mode) { - case VIDEO_DEPTH_1BIT: return 2; - case VIDEO_DEPTH_2BIT: return 4; - case VIDEO_DEPTH_4BIT: return 16; - case VIDEO_DEPTH_8BIT: return 256; - case VIDEO_DEPTH_16BIT: return 32; - case VIDEO_DEPTH_32BIT: return 256; - default: return 0; - } -} - -// Map video_mode depth ID to numerical depth value -static int mac_depth_of_video_depth(int video_depth) -{ - int depth = -1; - switch (video_depth) { - case VIDEO_DEPTH_1BIT: - depth = 1; - break; - case VIDEO_DEPTH_2BIT: - depth = 2; - break; - case VIDEO_DEPTH_4BIT: - depth = 4; - break; - case VIDEO_DEPTH_8BIT: - depth = 8; - break; - case VIDEO_DEPTH_16BIT: - depth = 16; - break; - case VIDEO_DEPTH_32BIT: - depth = 32; - break; - default: - abort(); - } - return depth; -} - -// Map video_mode depth ID to SDL screen depth -static int sdl_depth_of_video_depth(int video_depth) -{ - return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth); -} - -// Get screen dimensions -static void sdl_display_dimensions(int &width, int &height) -{ - static int max_width, max_height; - if (max_width == 0 && max_height == 0) { - max_width = 640 ; max_height = 480; - SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); - if (modes && modes != (SDL_Rect **)-1) { - // It turns out that on some implementations, and contrary to the documentation, - // the returned list is not sorted from largest to smallest (e.g. Windows) - for (int i = 0; modes[i] != NULL; i++) { - const int w = modes[i]->w; - const int h = modes[i]->h; - if (w > max_width && h > max_height) { - max_width = w; - max_height = h; - } - } - } - } - width = max_width; - height = max_height; -} - -static inline int sdl_display_width(void) -{ - int width, height; - sdl_display_dimensions(width, height); - return width; -} - -static inline int sdl_display_height(void) -{ - int width, height; - sdl_display_dimensions(width, height); - return height; -} - -// Check whether specified mode is available -static bool has_mode(int type, int width, int height, int depth) -{ - // Filter out out-of-bounds resolutions - if (width > sdl_display_width() || height > sdl_display_height()) - return false; - - // Rely on SDL capabilities - return SDL_VideoModeOK(width, height, - sdl_depth_of_video_depth(depth), - SDL_HWSURFACE | (type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0)) != 0; -} - -// Add mode to list of supported modes -static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) -{ - // Filter out unsupported modes - if (!has_mode(type, width, height, depth)) - return; - - // Fill in VideoMode entry - VIDEO_MODE mode; -#ifdef SHEEPSHAVER - resolution_id = find_apple_resolution(width, height); - mode.viType = type; -#endif - VIDEO_MODE_X = width; - VIDEO_MODE_Y = height; - VIDEO_MODE_RESOLUTION = resolution_id; - VIDEO_MODE_ROW_BYTES = bytes_per_row; - VIDEO_MODE_DEPTH = (video_depth)depth; - VideoModes.push_back(mode); -} - -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - int layout = FLAYOUT_DIRECT; - if (depth == VIDEO_DEPTH_16BIT) - layout = (screen_depth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; - else if (depth == VIDEO_DEPTH_32BIT) - layout = (screen_depth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; - MacFrameLayout = layout; - monitor.set_mac_frame_base(MacFrameBaseMac); - - // Set variables used by UAE memory banking - const VIDEO_MODE &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; - MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - InitFrameBufferMapping(); -#else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); -#endif - D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); -} - -// Set window name and class -static void set_window_name(int name) -{ - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - if (vi && vi->wm_available) { - const char *str = GetString(name); - SDL_WM_SetCaption(str, str); - } -} - -// Set mouse grab mode -static SDL_GrabMode set_grab_mode(SDL_GrabMode mode) -{ - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - return (vi && vi->wm_available ? SDL_WM_GrabInput(mode) : SDL_GRAB_OFF); -} - -// Migrate preferences items (XXX to be handled in MigratePrefs()) -static void migrate_screen_prefs(void) -{ -#ifdef SHEEPSHAVER - // Look-up priorities are: "screen", "screenmodes", "windowmodes". - if (PrefsFindString("screen")) - return; - - uint32 window_modes = PrefsFindInt32("windowmodes"); - uint32 screen_modes = PrefsFindInt32("screenmodes"); - int width = 0, height = 0; - if (screen_modes) { - static const struct { - int id; - int width; - int height; - } - modes[] = { - { 1, 640, 480 }, - { 2, 800, 600 }, - { 4, 1024, 768 }, - { 64, 1152, 768 }, - { 8, 1152, 900 }, - { 16, 1280, 1024 }, - { 32, 1600, 1200 }, - { 0, } - }; - for (int i = 0; modes[i].id != 0; i++) { - if (screen_modes & modes[i].id) { - if (width < modes[i].width && height < modes[i].height) { - width = modes[i].width; - height = modes[i].height; - } - } - } - } else { - if (window_modes & 1) - width = 640, height = 480; - if (window_modes & 2) - width = 800, height = 600; - } - if (width && height) { - char str[32]; - sprintf(str, "%s/%d/%d", screen_modes ? "dga" : "win", width, height); - PrefsReplaceString("screen", str); - } -#endif -} - -void update_sdl_video(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h) -{ - SDL_UpdateRect(screen, x, y, w, h); -} - -void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects) -{ - SDL_UpdateRects(screen, numrects, rects); -} - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(SDL_monitor_desc &m); - ~driver_base(); - - void init(); // One-time init - void set_video_mode(int flags); - void adapt_to_video_mode(); - - void update_palette(void); - void suspend(void) {} - void resume(void) {} - void toggle_mouse_grab(void); - void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } - - void disable_mouse_accel(void); - void restore_mouse_accel(void); - - void grab_mouse(void); - void ungrab_mouse(void); - -public: - SDL_monitor_desc &monitor; // Associated video monitor - const VIDEO_MODE &mode; // Video mode handled by the driver - - bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - SDL_Surface *s; // The surface we draw into -}; - -#ifdef ENABLE_VOSF -static void update_display_window_vosf(driver_base *drv); -#endif -static void update_display_static(driver_base *drv); - -static driver_base *drv = NULL; // Pointer to currently used driver object - -#ifdef ENABLE_VOSF -# include "video_vosf.h" -#endif - -driver_base::driver_base(SDL_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false), s(NULL) -{ - the_buffer = NULL; - the_buffer_copy = NULL; -} - -void driver_base::set_video_mode(int flags) -{ - int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - if ((s = SDL_SetVideoMode(VIDEO_MODE_X, VIDEO_MODE_Y, depth, - SDL_HWSURFACE | flags)) == NULL) - return; -#ifdef ENABLE_VOSF - the_host_buffer = (uint8 *)s->pixels; -#endif -} - -void driver_base::init() -{ - set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); - int aligned_height = (VIDEO_MODE_Y + 15) & ~15; - -#ifdef ENABLE_VOSF - use_vosf = true; - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_buffer_size = page_extend((aligned_height + 2) * s->pitch); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); - - // Check whether we can initialize the VOSF subsystem and it's profitable - if (!video_vosf_init(monitor)) { - WarningAlert(GetString(STR_VOSF_INIT_ERR)); - use_vosf = false; - } - else if (!video_vosf_profitable()) { - video_vosf_exit(); - printf("VOSF acceleration is not profitable on this platform, disabling it\n"); - use_vosf = false; - } - if (!use_vosf) { - free(the_buffer_copy); - vm_release(the_buffer, the_buffer_size); - the_host_buffer = NULL; - } -#endif - if (!use_vosf) { - // Allocate memory for frame buffer - the_buffer_size = (aligned_height + 2) * s->pitch; - the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); - } - - // Set frame buffer base - set_mac_frame_buffer(monitor, VIDEO_MODE_DEPTH); - - adapt_to_video_mode(); -} - -void driver_base::adapt_to_video_mode() { - ADBSetRelMouseMode(false); - - // Init blitting routines - SDL_PixelFormat *f = s->format; - VisualFormat visualFormat; - visualFormat.depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - visualFormat.Rmask = f->Rmask; - visualFormat.Gmask = f->Gmask; - visualFormat.Bmask = f->Bmask; - Screen_blitter_init(visualFormat, true, mac_depth_of_video_depth(VIDEO_MODE_DEPTH)); - - // Load gray ramp to 8->16/32 expand map - if (!IsDirectMode(mode)) - for (int i=0; i<256; i++) - ExpandMap[i] = SDL_MapRGB(f, i, i, i); - - - bool hardware_cursor = false; -#ifdef SHEEPSHAVER - hardware_cursor = video_can_change_cursor(); - if (hardware_cursor) { - // Create cursor - if ((sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, 0, 0)) != NULL) { - SDL_SetCursor(sdl_cursor); - } - } - // Tell the video driver there's a change in cursor type - if (private_data) - private_data->cursorHardware = hardware_cursor; -#endif - // Hide cursor - SDL_ShowCursor(hardware_cursor); - - // Set window name/class - set_window_name(STR_WINDOW_TITLE); - - // Everything went well - init_ok = true; -} - -driver_base::~driver_base() -{ - ungrab_mouse(); - restore_mouse_accel(); - - if (s) - SDL_FreeSurface(s); - - // the_buffer shall always be mapped through vm_acquire_framebuffer() - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release_framebuffer(the_buffer, the_buffer_size); - the_buffer = NULL; - } - - // Free frame buffer(s) - if (!use_vosf) { - if (the_buffer_copy) { - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#ifdef ENABLE_VOSF - else { - if (the_buffer_copy) { - D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); - free(the_buffer_copy); - the_buffer_copy = NULL; - } - - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - SDL_ShowCursor(1); -} - -// Palette has changed -void driver_base::update_palette(void) -{ - const VIDEO_MODE &mode = monitor.get_current_mode(); - - if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) - SDL_SetPalette(s, SDL_PHYSPAL, sdl_palette, 0, 256); -} - -// Disable mouse acceleration -void driver_base::disable_mouse_accel(void) -{ -} - -// Restore mouse acceleration to original value -void driver_base::restore_mouse_accel(void) -{ -} - -// Toggle mouse grab -void driver_base::toggle_mouse_grab(void) -{ - if (mouse_grabbed) - ungrab_mouse(); - else - grab_mouse(); -} - -// Grab mouse, switch to relative mouse mode -void driver_base::grab_mouse(void) -{ - if (!mouse_grabbed) { - SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_ON); - if (new_mode == SDL_GRAB_ON) { - disable_mouse_accel(); - mouse_grabbed = true; - } - } -} - -// Ungrab mouse, switch to absolute mouse mode -void driver_base::ungrab_mouse(void) -{ - if (mouse_grabbed) { - SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_OFF); - if (new_mode == SDL_GRAB_OFF) { - restore_mouse_accel(); - mouse_grabbed = false; - } - } -} - -/* - * Initialization - */ - -// Init keycode translation table -static void keycode_init(void) -{ - bool use_kc = PrefsFindBool("keycodes"); - if (use_kc) { - - // Get keycode file path from preferences - const char *kc_path = PrefsFindString("keycodefile"); - - // Open keycode table - FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); - if (f == NULL) { - char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); - WarningAlert(str); - return; - } - - // Default translation table - for (int i=0; i<256; i++) - keycode_table[i] = -1; - - // Search for server vendor string, then read keycodes - char video_driver[256]; - SDL_VideoDriverName(video_driver, sizeof(video_driver)); - bool video_driver_found = false; - char line[256]; - int n_keys = 0; - while (fgets(line, sizeof(line) - 1, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - - // Comments begin with "#" or ";" - if (line[0] == '#' || line[0] == ';' || line[0] == 0) - continue; - - if (video_driver_found) { - // Skip aliases as long as we have read keycodes yet - // Otherwise, it's another mapping and we have to stop - static const char sdl_str[] = "sdl"; - if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0 && n_keys == 0) - continue; - - // Read keycode - int x_code, mac_code; - if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) - keycode_table[x_code & 0xff] = mac_code, n_keys++; - else - break; - } else { - // Search for SDL video driver string - static const char sdl_str[] = "sdl"; - if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) { - char *p = line + sizeof(sdl_str); - if (strstr(video_driver, p) == video_driver) - video_driver_found = true; - } - } - } - - // Keycode file completely read - fclose(f); - use_keycodes = video_driver_found; - - // Vendor not found? Then display warning - if (!video_driver_found) { - char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver, kc_path ? kc_path : KEYCODE_FILE_NAME); - WarningAlert(str); - return; - } - - D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver, n_keys)); - } -} - -// Open display for current mode -bool SDL_monitor_desc::video_open(void) -{ - D(bug("video_open()\n")); -#if DEBUG - const VIDEO_MODE &mode = get_current_mode(); - D(bug("Current video mode:\n")); - D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f))); -#endif - - // Create display driver object of requested type - drv = new(std::nothrow) driver_base(*this); - if (drv == NULL) - return false; - drv->init(); - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - -#ifdef WIN32 - // Chain in a new message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); -#endif - - // Initialize VideoRefresh function - VideoRefreshInit(); - - // Lock down frame buffer - LOCK_FRAME_BUFFER; - - // Start redraw/input thread -#ifndef USE_CPU_EMUL_SERVICES - redraw_thread_cancel = false; - redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, NULL)) != NULL); - if (!redraw_thread_active) { - printf("FATAL: cannot create redraw thread\n"); - return false; - } -#else - redraw_thread_active = true; -#endif - return true; -} - -#ifdef SHEEPSHAVER -bool VideoInit(void) -{ - const bool classic = false; -#else -bool VideoInit(bool classic) -{ -#endif - classic_mode = classic; - -#ifdef ENABLE_VOSF - // Zero the mainBuffer structure - mainBuffer.dirtyPages = NULL; - mainBuffer.pageInfo = NULL; -#endif - - // Create Mutexes - if ((sdl_events_lock = SDL_CreateMutex()) == NULL) - return false; - if ((sdl_palette_lock = SDL_CreateMutex()) == NULL) - return false; - if ((frame_buffer_lock = SDL_CreateMutex()) == NULL) - return false; - - // Init keycode translation - keycode_init(); - - // Read prefs - frame_skip = PrefsFindInt32("frameskip"); - mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); - mouse_wheel_lines = PrefsFindInt32("mousewheellines"); - - // Get screen mode from preferences - migrate_screen_prefs(); - const char *mode_str = NULL; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width, default_height; - if (classic) { - default_width = 512; - default_height = 384; - } - else { - default_width = 640; - default_height = 480; - } - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_SCREEN; - } - if (default_width <= 0) - default_width = sdl_display_width(); - else if (default_width > sdl_display_width()) - default_width = sdl_display_width(); - if (default_height <= 0) - default_height = sdl_display_height(); - else if (default_height > sdl_display_height()) - default_height = sdl_display_height(); - - // Mac screen depth follows X depth - screen_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; - int default_depth; - switch (screen_depth) { - case 8: - default_depth = VIDEO_DEPTH_8BIT; - break; - case 15: case 16: - default_depth = VIDEO_DEPTH_16BIT; - break; - case 24: case 32: - default_depth = VIDEO_DEPTH_32BIT; - break; - default: - default_depth = VIDEO_DEPTH_1BIT; - break; - } - - // Initialize list of video modes to try - struct { - int w; - int h; - int resolution_id; - } -#ifdef SHEEPSHAVER - // Omit Classic resolutions - video_modes[] = { - { -1, -1, 0x80 }, - { 640, 480, 0x81 }, - { 800, 600, 0x82 }, - { 1024, 768, 0x83 }, - { 1152, 870, 0x84 }, - { 1280, 1024, 0x85 }, - { 1600, 1200, 0x86 }, - { 0, } - }; -#else - video_modes[] = { - { -1, -1, 0x80 }, - { 512, 384, 0x80 }, - { 640, 480, 0x81 }, - { 800, 600, 0x82 }, - { 1024, 768, 0x83 }, - { 1152, 870, 0x84 }, - { 1280, 1024, 0x85 }, - { 1600, 1200, 0x86 }, - { 0, } - }; -#endif - video_modes[0].w = default_width; - video_modes[0].h = default_height; - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT); - else { - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (i > 0 && (w >= default_width || h >= default_height)) - continue; - for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) - add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); - } - } - } else if (display_type == DISPLAY_SCREEN) { - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (i > 0 && (w >= default_width || h >= default_height)) - continue; - if (w == 512 && h == 384) - continue; - for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) - add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); - } - } - - if (VideoModes.empty()) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - const VIDEO_MODE & mode = (*i); - if (VIDEO_MODE_X == default_width && VIDEO_MODE_Y == default_height && VIDEO_MODE_DEPTH == default_depth) { - default_id = VIDEO_MODE_RESOLUTION; -#ifdef SHEEPSHAVER - std::vector::const_iterator begin = VideoModes.begin(); - cur_mode = distance(begin, i); -#endif - break; - } - } - if (i == end) { // not found, use first available mode - const VIDEO_MODE & mode = VideoModes[0]; - default_depth = VIDEO_MODE_DEPTH; - default_id = VIDEO_MODE_RESOLUTION; -#ifdef SHEEPSHAVER - cur_mode = 0; -#endif - } - -#ifdef SHEEPSHAVER - for (int i = 0; i < VideoModes.size(); i++) - VModes[i] = VideoModes[i]; - VideoInfo *p = &VModes[VideoModes.size()]; - p->viType = DIS_INVALID; // End marker - p->viRowBytes = 0; - p->viXsize = p->viYsize = 0; - p->viAppleMode = 0; - p->viAppleID = 0; -#endif - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - const VIDEO_MODE & mode = (*i); - int bits = 1 << VIDEO_MODE_DEPTH; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << bits)); - } -#endif - - int color_depth = get_customized_color_depth(default_depth); - - D(bug("Return get_customized_color_depth %d\n", color_depth)); - - // Create SDL_monitor_desc for this (the only) display - SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)color_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - - -/* - * Deinitialization - */ - -// Close display -void SDL_monitor_desc::video_close(void) -{ - D(bug("video_close()\n")); - -#ifdef WIN32 - // Remove message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); -#endif - - // Stop redraw thread -#ifndef USE_CPU_EMUL_SERVICES - if (redraw_thread_active) { - redraw_thread_cancel = true; - SDL_WaitThread(redraw_thread, NULL); - } -#endif - redraw_thread_active = false; - - // Unlock frame buffer - UNLOCK_FRAME_BUFFER; - D(bug(" frame buffer unlocked\n")); - - // Close display - delete drv; - drv = NULL; -} - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); - - // Destroy locks - if (frame_buffer_lock) - SDL_DestroyMutex(frame_buffer_lock); - if (sdl_palette_lock) - SDL_DestroyMutex(sdl_palette_lock); - if (sdl_events_lock) - SDL_DestroyMutex(sdl_events_lock); -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - quit_full_screen = true; -} - -static void do_toggle_fullscreen(void) -{ -#ifndef USE_CPU_EMUL_SERVICES - // pause redraw thread - thread_stop_ack = false; - thread_stop_req = true; - while (!thread_stop_ack) ; -#endif - - // save the mouse position - int x, y; - SDL_GetMouseState(&x, &y); - - // save the screen contents - SDL_Surface *tmp_surface = SDL_ConvertSurface(drv->s, drv->s->format, - drv->s->flags); - - // switch modes - display_type = (display_type == DISPLAY_SCREEN) ? DISPLAY_WINDOW - : DISPLAY_SCREEN; - drv->set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); - drv->adapt_to_video_mode(); - - // reset the palette -#ifdef SHEEPSHAVER - video_set_palette(); -#endif - drv->update_palette(); - - // restore the screen contents - SDL_BlitSurface(tmp_surface, NULL, drv->s, NULL); - SDL_FreeSurface(tmp_surface); - SDL_UpdateRect(drv->s, 0, 0, 0, 0); - - // reset the video refresh handler - VideoRefreshInit(); - - // while SetVideoMode is happening, control key up may be missed - ADBKeyUp(0x36); - - // restore the mouse position - SDL_WarpMouse(x, y); - - // resume redraw thread - toggle_fullscreen = false; -#ifndef USE_CPU_EMUL_SERVICES - thread_stop_req = false; -#endif -} - -/* - * Mac VBL interrupt - */ - -/* - * Execute video VBL routine - */ - -#ifdef SHEEPSHAVER -void VideoVBL(void) -{ - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - if (toggle_fullscreen) - do_toggle_fullscreen(); - - // Setting the window name must happen on the main thread, else it doesn't work on - // some platforms - e.g. macOS Sierra. - if (mouse_grabbed_window_name_status != mouse_grabbed) { - set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE); - mouse_grabbed_window_name_status = mouse_grabbed; - } - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; - - // Execute video VBL - if (private_data != NULL && private_data->interruptsEnabled) - VSLDoInterruptService(private_data->vslServiceID); -} -#else -void VideoInterrupt(void) -{ - // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() - SDL_PumpEvents(); - - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - if (toggle_fullscreen) - do_toggle_fullscreen(); - - // Setting the window name must happen on the main thread, else it doesn't work on - // some platforms - e.g. macOS Sierra. - if (mouse_grabbed_window_name_status != mouse_grabbed) { - set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE); - mouse_grabbed_window_name_status = mouse_grabbed; - } - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; -} -#endif - - -/* - * Set palette - */ - -#ifdef SHEEPSHAVER -void video_set_palette(void) -{ - monitor_desc * monitor = VideoMonitors[0]; - int n_colors = palette_size(monitor->get_current_mode().viAppleMode); - uint8 pal[256 * 3]; - for (int c = 0; c < n_colors; c++) { - pal[c*3 + 0] = mac_pal[c].red; - pal[c*3 + 1] = mac_pal[c].green; - pal[c*3 + 2] = mac_pal[c].blue; - } - monitor->set_palette(pal, n_colors); -} -#endif - -void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) -{ - const VIDEO_MODE &mode = get_current_mode(); - - if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) { - // handle the gamma ramp - - if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey - return; // ignore - - uint16 red[256]; - uint16 green[256]; - uint16 blue[256]; - - int repeats = 256 / num_in; - - for (int i = 0; i < num_in; i++) { - for (int j = 0; j < repeats; j++) { - red[i*repeats + j] = pal[i*3 + 0] << 8; - green[i*repeats + j] = pal[i*3 + 1] << 8; - blue[i*repeats + j] = pal[i*3 + 2] << 8; - } - } - - // fill remaining entries (if any) with last value - for (int i = num_in * repeats; i < 256; i++) { - red[i] = pal[(num_in - 1) * 3] << 8; - green[i] = pal[(num_in - 1) * 3 + 1] << 8; - blue[i] = pal[(num_in - 1) * 3 + 2] << 8; - } - - bool changed = (memcmp(red, last_gamma_red, 512) != 0 || - memcmp(green, last_gamma_green, 512) != 0 || - memcmp(blue, last_gamma_blue, 512) != 0); - - if (changed) { - int result = SDL_SetGammaRamp(red, green, blue); - - if (result < 0) { - fprintf(stderr, "SDL_SetGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); - } - - memcpy(last_gamma_red, red, 512); - memcpy(last_gamma_green, green, 512); - memcpy(last_gamma_blue, blue, 512); - } - - return; - } - - LOCK_PALETTE; - - // Convert colors to XColor array - int num_out = 256; - bool stretch = false; - SDL_Color *p = sdl_palette; - for (int i=0; ir = pal[c*3 + 0] * 0x0101; - p->g = pal[c*3 + 1] * 0x0101; - p->b = pal[c*3 + 2] * 0x0101; - p++; - } - - // Recalculate pixel color expansion map - if (!IsDirectMode(mode)) { - for (int i=0; i<256; i++) { - int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) - ExpandMap[i] = SDL_MapRGB(drv->s->format, pal[c*3+0], pal[c*3+1], pal[c*3+2]); - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // We have to redraw everything because the interpretation of pixel values changed - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); - } -#endif - } - - // Tell redraw thread to change palette - sdl_palette_changed = true; - - UNLOCK_PALETTE; -} - - -/* - * Switch video mode - */ - -#ifdef SHEEPSHAVER -int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) -{ - /* return if no mode change */ - if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && - (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; - - /* first find video mode in table */ - for (int i=0; VModes[i].viType != DIS_INVALID; i++) { - if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && - (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { - csSave->saveMode = ReadMacInt16(ParamPtr + csMode); - csSave->saveData = ReadMacInt32(ParamPtr + csData); - csSave->savePage = ReadMacInt16(ParamPtr + csPage); - - // Disable interrupts and pause redraw thread - DisableInterrupt(); - thread_stop_ack = false; - thread_stop_req = true; - while (!thread_stop_ack) ; - - cur_mode = i; - monitor_desc *monitor = VideoMonitors[0]; - monitor->switch_to_current_mode(); - - WriteMacInt32(ParamPtr + csBaseAddr, screen_base); - csSave->saveBaseAddr=screen_base; - csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ - csSave->saveMode=VModes[cur_mode].viAppleMode; - - // Enable interrupts and resume redraw thread - thread_stop_req = false; - EnableInterrupt(); - return noErr; - } - } - return paramErr; -} -#endif - -void SDL_monitor_desc::switch_to_current_mode(void) -{ - // Close and reopen display - LOCK_EVENTS; - video_close(); - video_open(); - UNLOCK_EVENTS; - - if (drv == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Can we set the MacOS cursor image into the window? - */ - -#ifdef SHEEPSHAVER -bool video_can_change_cursor(void) -{ - if (display_type != DISPLAY_WINDOW) - return false; - -#if defined(__APPLE__) - static char driver[] = "Quartz?"; - static int quartzok = -1; - - if (quartzok < 0) { - if (SDL_VideoDriverName(driver, sizeof driver) == NULL || strncmp(driver, "Quartz", sizeof driver)) - quartzok = true; - else { - // Quartz driver bug prevents cursor changing in SDL 1.2.11 to 1.2.14. - const SDL_version *vp = SDL_Linked_Version(); - int version = SDL_VERSIONNUM(vp->major, vp->minor, vp->patch); - quartzok = (version <= SDL_VERSIONNUM(1, 2, 10) || version >= SDL_VERSIONNUM(1, 2, 15)); - } - } - - return quartzok; -#else - return true; -#endif -} -#endif - - -/* - * Set cursor image for window - */ - -#ifdef SHEEPSHAVER -void video_set_cursor(void) -{ - // Set new cursor image if it was changed - if (sdl_cursor) { - SDL_FreeCursor(sdl_cursor); - sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); - if (sdl_cursor) { - SDL_ShowCursor(private_data == NULL || private_data->cursorVisible); - SDL_SetCursor(sdl_cursor); - - // XXX Windows apparently needs an extra mouse event to - // make the new cursor image visible. - // On Mac, if mouse is grabbed, SDL_ShowCursor() recenters the - // mouse, we have to put it back. - bool move = false; -#ifdef WIN32 - move = true; -#elif defined(__APPLE__) - move = mouse_grabbed; -#endif - if (move) { - int visible = SDL_ShowCursor(-1); - if (visible) { - int x, y; - SDL_GetMouseState(&x, &y); - SDL_WarpMouse(x, y); - } - } - } - } -} -#endif - - -/* - * Keyboard-related utilify functions - */ - -static bool is_modifier_key(SDL_KeyboardEvent const & e) -{ - switch (e.keysym.sym) { - case SDLK_NUMLOCK: - case SDLK_CAPSLOCK: - case SDLK_SCROLLOCK: - case SDLK_RSHIFT: - case SDLK_LSHIFT: - case SDLK_RCTRL: - case SDLK_LCTRL: - case SDLK_RALT: - case SDLK_LALT: - case SDLK_RMETA: - case SDLK_LMETA: - case SDLK_LSUPER: - case SDLK_RSUPER: - case SDLK_MODE: - case SDLK_COMPOSE: - return true; - } - return false; -} - -static bool is_ctrl_down(SDL_keysym const & ks) -{ - return ctrl_down || (ks.mod & KMOD_CTRL); -} - - -/* - * Translate key event to Mac keycode, returns -1 if no keycode was found - * and -2 if the key was recognized as a hotkey - */ - -static int kc_decode(SDL_keysym const & ks, bool key_down) -{ - switch (ks.sym) { - case SDLK_a: return 0x00; - case SDLK_b: return 0x0b; - case SDLK_c: return 0x08; - case SDLK_d: return 0x02; - case SDLK_e: return 0x0e; - case SDLK_f: return 0x03; - case SDLK_g: return 0x05; - case SDLK_h: return 0x04; - case SDLK_i: return 0x22; - case SDLK_j: return 0x26; - case SDLK_k: return 0x28; - case SDLK_l: return 0x25; - case SDLK_m: return 0x2e; - case SDLK_n: return 0x2d; - case SDLK_o: return 0x1f; - case SDLK_p: return 0x23; - case SDLK_q: return 0x0c; - case SDLK_r: return 0x0f; - case SDLK_s: return 0x01; - case SDLK_t: return 0x11; - case SDLK_u: return 0x20; - case SDLK_v: return 0x09; - case SDLK_w: return 0x0d; - case SDLK_x: return 0x07; - case SDLK_y: return 0x10; - case SDLK_z: return 0x06; - - case SDLK_1: case SDLK_EXCLAIM: return 0x12; - case SDLK_2: case SDLK_AT: return 0x13; - case SDLK_3: case SDLK_HASH: return 0x14; - case SDLK_4: case SDLK_DOLLAR: return 0x15; - case SDLK_5: return 0x17; - case SDLK_6: return 0x16; - case SDLK_7: return 0x1a; - case SDLK_8: return 0x1c; - case SDLK_9: return 0x19; - case SDLK_0: return 0x1d; - - case SDLK_BACKQUOTE: return 0x0a; - case SDLK_MINUS: case SDLK_UNDERSCORE: return 0x1b; - case SDLK_EQUALS: case SDLK_PLUS: return 0x18; - case SDLK_LEFTBRACKET: return 0x21; - case SDLK_RIGHTBRACKET: return 0x1e; - case SDLK_BACKSLASH: return 0x2a; - case SDLK_SEMICOLON: case SDLK_COLON: return 0x29; - case SDLK_QUOTE: case SDLK_QUOTEDBL: return 0x27; - case SDLK_COMMA: case SDLK_LESS: return 0x2b; - case SDLK_PERIOD: case SDLK_GREATER: return 0x2f; - case SDLK_SLASH: case SDLK_QUESTION: return 0x2c; - - case SDLK_TAB: if (is_ctrl_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30; - case SDLK_RETURN: if (is_ctrl_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24; - case SDLK_SPACE: return 0x31; - case SDLK_BACKSPACE: return 0x33; - - case SDLK_DELETE: return 0x75; - case SDLK_INSERT: return 0x72; - case SDLK_HOME: case SDLK_HELP: return 0x73; - case SDLK_END: return 0x77; - case SDLK_PAGEUP: return 0x74; - case SDLK_PAGEDOWN: return 0x79; - - case SDLK_LCTRL: return 0x36; - case SDLK_RCTRL: return 0x36; - case SDLK_LSHIFT: return 0x38; - case SDLK_RSHIFT: return 0x38; -#if (defined(__APPLE__) && defined(__MACH__)) - case SDLK_LALT: return 0x3a; - case SDLK_RALT: return 0x3a; - case SDLK_LMETA: return 0x37; - case SDLK_RMETA: return 0x37; -#else - case SDLK_LALT: return 0x37; - case SDLK_RALT: return 0x37; - case SDLK_LMETA: return 0x3a; - case SDLK_RMETA: return 0x3a; -#endif - case SDLK_LSUPER: return 0x3a; // "Windows" key - case SDLK_RSUPER: return 0x3a; - case SDLK_MENU: return 0x32; - case SDLK_CAPSLOCK: return 0x39; - case SDLK_NUMLOCK: return 0x47; - - case SDLK_UP: return 0x3e; - case SDLK_DOWN: return 0x3d; - case SDLK_LEFT: return 0x3b; - case SDLK_RIGHT: return 0x3c; - - case SDLK_ESCAPE: if (is_ctrl_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35; - - case SDLK_F1: if (is_ctrl_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a; - case SDLK_F2: return 0x78; - case SDLK_F3: return 0x63; - case SDLK_F4: return 0x76; - case SDLK_F5: if (is_ctrl_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60; - case SDLK_F6: return 0x61; - case SDLK_F7: return 0x62; - case SDLK_F8: return 0x64; - case SDLK_F9: return 0x65; - case SDLK_F10: return 0x6d; - case SDLK_F11: return 0x67; - case SDLK_F12: return 0x6f; - - case SDLK_PRINT: return 0x69; - case SDLK_SCROLLOCK: return 0x6b; - case SDLK_PAUSE: return 0x71; - - case SDLK_KP0: return 0x52; - case SDLK_KP1: return 0x53; - case SDLK_KP2: return 0x54; - case SDLK_KP3: return 0x55; - case SDLK_KP4: return 0x56; - case SDLK_KP5: return 0x57; - case SDLK_KP6: return 0x58; - case SDLK_KP7: return 0x59; - case SDLK_KP8: return 0x5b; - case SDLK_KP9: return 0x5c; - case SDLK_KP_PERIOD: return 0x41; - case SDLK_KP_PLUS: return 0x45; - case SDLK_KP_MINUS: return 0x4e; - case SDLK_KP_MULTIPLY: return 0x43; - case SDLK_KP_DIVIDE: return 0x4b; - case SDLK_KP_ENTER: return 0x4c; - case SDLK_KP_EQUALS: return 0x51; - } - D(bug("Unhandled SDL keysym: %d\n", ks.sym)); - return -1; -} - -static int event2keycode(SDL_KeyboardEvent const &ev, bool key_down) -{ - return kc_decode(ev.keysym, key_down); -} - -static void force_complete_window_refresh() -{ - if (display_type == DISPLAY_WINDOW) { -#ifdef ENABLE_VOSF - if (use_vosf) { // VOSF refresh - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - } -#endif - // Ensure each byte of the_buffer_copy differs from the_buffer to force a full update. - const VIDEO_MODE &mode = VideoMonitors[0]->get_current_mode(); - const int len = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - for (int i = 0; i < len; i++) - the_buffer_copy[i] = !the_buffer[i]; - } -} - -/* - * SDL event handling - */ - -static void handle_events(void) -{ - SDL_Event events[10]; - const int n_max_events = sizeof(events) / sizeof(events[0]); - int n_events; - - while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, sdl_eventmask)) > 0) { - for (int i = 0; i < n_events; i++) { - SDL_Event const & event = events[i]; - switch (event.type) { - - // Mouse button - case SDL_MOUSEBUTTONDOWN: { - unsigned int button = event.button.button; - if (button == SDL_BUTTON_LEFT) - ADBMouseDown(0); - else if (button == SDL_BUTTON_RIGHT) - ADBMouseDown(1); - else if (button == SDL_BUTTON_MIDDLE) - ADBMouseDown(2); - else if (button < 6) { // Wheel mouse - if (mouse_wheel_mode == 0) { - int key = (button == 5) ? 0x79 : 0x74; // Page up/down - ADBKeyDown(key); - ADBKeyUp(key); - } else { - int key = (button == 5) ? 0x3d : 0x3e; // Cursor up/down - for(int i=0; imouse_moved(event.motion.x, event.motion.y); - break; - - // Keyboard - case SDL_KEYDOWN: { - int code = -1; - if (use_keycodes && !is_modifier_key(event.key)) { - if (event2keycode(event.key, true) != -2) // This is called to process the hotkeys - code = keycode_table[event.key.keysym.scancode & 0xff]; - } else - code = event2keycode(event.key, true); - if (code >= 0) { - if (!emul_suspended) { - if (code == 0x39) { // Caps Lock pressed - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyDown(code); - if (code == 0x36) - ctrl_down = true; - } else { - if (code == 0x31) - drv->resume(); // Space wakes us up - } - } - break; - } - case SDL_KEYUP: { - int code = -1; - if (use_keycodes && !is_modifier_key(event.key)) { - if (event2keycode(event.key, false) != -2) // This is called to process the hotkeys - code = keycode_table[event.key.keysym.scancode & 0xff]; - } else - code = event2keycode(event.key, false); - if (code >= 0) { - if (code == 0x39) { // Caps Lock released - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyUp(code); - if (code == 0x36) - ctrl_down = false; - } - break; - } - - // Hidden parts exposed, force complete refresh of window - case SDL_VIDEOEXPOSE: - force_complete_window_refresh(); - break; - - // Window "close" widget clicked - case SDL_QUIT: - ADBKeyDown(0x7f); // Power key - ADBKeyUp(0x7f); - break; - - // Application activate/deactivate - case SDL_ACTIVEEVENT: - // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. - if (event.active.gain) - force_complete_window_refresh(); - break; - } - } - } -} - - -/* - * Window display update - */ - -// Static display update (fixed frame rate, but incremental) -static void update_display_static(driver_base *drv) -{ - // Incremental update code - int wide = 0, high = 0; - uint32 x1, x2, y1, y2; - const VIDEO_MODE &mode = drv->mode; - int bytes_per_row = VIDEO_MODE_ROW_BYTES; - uint8 *p, *p2; - - // Check for first line from top and first line from bottom that have changed - y1 = 0; - for (uint32 j = 0; j < VIDEO_MODE_Y; j++) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y1 = j; - break; - } - } - y2 = y1 - 1; - for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y2 = j; - break; - } - } - high = y2 - y1 + 1; - - // Check for first column from left and first column from right that have changed - if (high) { - if (VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) { - const int src_bytes_per_row = bytes_per_row; - const int dst_bytes_per_row = drv->s->pitch; - const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row; - - x1 = VIDEO_MODE_X / pixels_per_byte; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (uint32 i = 0; i < x1; i++) { - if (*p != *p2) { - x1 = i; - break; - } - p++; p2++; - } - } - x2 = x1; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (uint32 i = (VIDEO_MODE_X / pixels_per_byte); i > x2; i--) { - p--; p2--; - if (*p != *p2) { - x2 = i; - break; - } - } - } - x1 *= pixels_per_byte; - x2 *= pixels_per_byte; - wide = (x2 - x1 + pixels_per_byte - 1) & -pixels_per_byte; - - // Update copy of the_buffer - if (high && wide) { - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Blit to screen surface - int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte); - int di = y1 * dst_bytes_per_row + x1; - for (uint32 j = y1; j <= y2; j++) { - memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte); - Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte); - si += src_bytes_per_row; - di += dst_bytes_per_row; - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - SDL_UpdateRect(drv->s, x1, y1, wide, high); - } - - } else { - const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X; - const int dst_bytes_per_row = drv->s->pitch; - - x1 = VIDEO_MODE_X; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) { - if (*p != *p2) { - x1 = i / bytes_per_pixel; - break; - } - p++; p2++; - } - } - x2 = x1; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (uint32 i = VIDEO_MODE_X * bytes_per_pixel; i > x2 * bytes_per_pixel; i--) { - p--; - p2--; - if (*p != *p2) { - x2 = i / bytes_per_pixel; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Blit to screen surface - for (uint32 j = y1; j <= y2; j++) { - uint32 i = j * bytes_per_row + x1 * bytes_per_pixel; - int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel; - memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); - Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide); - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - SDL_UpdateRect(drv->s, x1, y1, wide, high); - } - } - } -} - -// Static display update (fixed frame rate, bounding boxes based) -// XXX use NQD bounding boxes to help detect dirty areas? -static void update_display_static_bbox(driver_base *drv) -{ - const VIDEO_MODE &mode = drv->mode; - - // Allocate bounding boxes for SDL_UpdateRects() - const uint32 N_PIXELS = 64; - const uint32 n_x_boxes = (VIDEO_MODE_X + N_PIXELS - 1) / N_PIXELS; - const uint32 n_y_boxes = (VIDEO_MODE_Y + N_PIXELS - 1) / N_PIXELS; - SDL_Rect *boxes = (SDL_Rect *)alloca(sizeof(SDL_Rect) * n_x_boxes * n_y_boxes); - uint32 nr_boxes = 0; - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Update the surface from Mac screen - const uint32 bytes_per_row = VIDEO_MODE_ROW_BYTES; - const uint32 bytes_per_pixel = bytes_per_row / VIDEO_MODE_X; - const uint32 dst_bytes_per_row = drv->s->pitch; - for (uint32 y = 0; y < VIDEO_MODE_Y; y += N_PIXELS) { - uint32 h = N_PIXELS; - if (h > VIDEO_MODE_Y - y) - h = VIDEO_MODE_Y - y; - for (uint32 x = 0; x < VIDEO_MODE_X; x += N_PIXELS) { - uint32 w = N_PIXELS; - if (w > VIDEO_MODE_X - x) - w = VIDEO_MODE_X - x; - const int xs = w * bytes_per_pixel; - const int xb = x * bytes_per_pixel; - bool dirty = false; - for (uint32 j = y; j < (y + h); j++) { - const uint32 yb = j * bytes_per_row; - const uint32 dst_yb = j * dst_bytes_per_row; - if (memcmp(&the_buffer[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { - memcpy(&the_buffer_copy[yb + xb], &the_buffer[yb + xb], xs); - Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, the_buffer + yb + xb, xs); - dirty = true; - } - } - if (dirty) { - boxes[nr_boxes].x = x; - boxes[nr_boxes].y = y; - boxes[nr_boxes].w = w; - boxes[nr_boxes].h = h; - nr_boxes++; - } - } - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - if (nr_boxes) - SDL_UpdateRects(drv->s, nr_boxes, boxes); -} - - -// We suggest the compiler to inline the next two functions so that it -// may specialise the code according to the current screen depth and -// display type. A clever compiler would do that job by itself though... - -// NOTE: update_display_vosf is inlined too - -static inline void possibly_quit_dga_mode() -{ - // Quit DGA mode if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - delete drv; - drv = NULL; - } -} - -static inline void possibly_ungrab_mouse() -{ - // Ungrab mouse if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - if (drv) - drv->ungrab_mouse(); - } -} - -static inline void handle_palette_changes(void) -{ - LOCK_PALETTE; - - if (sdl_palette_changed) { - sdl_palette_changed = false; - drv->update_palette(); - } - - UNLOCK_PALETTE; -} - -static void video_refresh_window_static(void); - -static void video_refresh_dga(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - video_refresh_window_static(); -} - -#ifdef ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING -static void video_refresh_dga_vosf(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - - // Update display (VOSF variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_dga_vosf(drv); - UNLOCK_VOSF; - } - } -} -#endif - -static void video_refresh_window_vosf(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (VOSF variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_window_vosf(drv); - UNLOCK_VOSF; - } - } -} -#endif // def ENABLE_VOSF - -static void video_refresh_window_static(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (static variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - const VIDEO_MODE &mode = drv->mode; - if ((int)VIDEO_MODE_DEPTH >= VIDEO_DEPTH_8BIT) - update_display_static_bbox(drv); - else - update_display_static(drv); - } -} - - -/* - * Thread for screen refresh, input handling etc. - */ - -static void VideoRefreshInit(void) -{ - // TODO: set up specialised 8bpp VideoRefresh handlers ? - if (display_type == DISPLAY_SCREEN) { -#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) - if (use_vosf) - video_refresh = video_refresh_dga_vosf; - else -#endif - video_refresh = video_refresh_dga; - } - else { -#ifdef ENABLE_VOSF - if (use_vosf) - video_refresh = video_refresh_window_vosf; - else -#endif - video_refresh = video_refresh_window_static; - } -} - -static inline void do_video_refresh(void) -{ - // Handle SDL events - handle_events(); - - // Update display - video_refresh(); - - - // Set new palette if it was changed - handle_palette_changes(); -} - -// This function is called on non-threaded platforms from a timer interrupt -void VideoRefresh(void) -{ - // We need to check redraw_thread_active to inhibit refreshed during - // mode changes on non-threaded platforms - if (!redraw_thread_active) - return; - - // Process pending events and update display - do_video_refresh(); -} - -const int VIDEO_REFRESH_HZ = 60; -const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; - -#ifndef USE_CPU_EMUL_SERVICES -static int redraw_func(void *arg) -{ - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; - - while (!redraw_thread_cancel) { - - // Wait - next += VIDEO_REFRESH_DELAY; - int32 delay = int32(next - GetTicks_usec()); - if (delay > 0) - Delay_usec(delay); - else if (delay < -VIDEO_REFRESH_DELAY) - next = GetTicks_usec(); - ticks++; - - // Pause if requested (during video mode switches) - if (thread_stop_req) { - thread_stop_ack = true; - continue; - } - - // Process pending events and update display - do_video_refresh(); - } - - uint64 end = GetTicks_usec(); - D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); - return 0; -} -#endif - - -/* - * Record dirty area from NQD - */ - -#ifdef SHEEPSHAVER -void video_set_dirty_area(int x, int y, int w, int h) -{ -#ifdef ENABLE_VOSF - const VIDEO_MODE &mode = drv->mode; - const unsigned screen_width = VIDEO_MODE_X; - const unsigned screen_height = VIDEO_MODE_Y; - const unsigned bytes_per_row = VIDEO_MODE_ROW_BYTES; - - if (use_vosf) { - vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); - return; - } -#endif - - // XXX handle dirty bounding boxes for non-VOSF modes -} -#endif - -#endif // ends: SDL version check diff --git a/SheepShaver/src/SDL/video_sdl2.cpp b/SheepShaver/src/SDL/video_sdl2.cpp deleted file mode 100644 index 77f53fa96..000000000 --- a/SheepShaver/src/SDL/video_sdl2.cpp +++ /dev/null @@ -1,2869 +0,0 @@ -/* - * video_sdl2.cpp - Video/graphics emulation, SDL 2.x specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * The Ctrl key works like a qualifier for special actions: - * Ctrl-Tab = suspend DGA mode (TODO) - * Ctrl-Esc = emergency quit - * Ctrl-F1 = mount floppy - * Ctrl-F5 = grab mouse (in windowed mode) - * - * FIXMEs and TODOs: - * - Windows requires an extra mouse event to update the actual cursor image? - * - Ctr-Tab for suspend/resume but how? SDL does not support that for non-Linux - * - Ctrl-Fn doesn't generate SDL_KEYDOWN events (SDL bug?) - * - Mouse acceleration, there is no API in SDL yet for that - * - Gamma tables support is likely to be broken here - * - Events processing is bound to the general emulation thread as SDL requires - * to PumpEvents() within the same thread as the one that called SetVideoMode(). - * Besides, there can't seem to be a way to call SetVideoMode() from a child thread. - * - Backport hw cursor acceleration to Basilisk II? - * - Factor out code - */ - -#include "sysdeps.h" - -#include -#if SDL_VERSION_ATLEAST(2,0,0) - -#include -#include -#include -#include -#include - -#ifdef __MACOSX__ -#include "utils_macosx.h" -#endif - -#ifdef WIN32 -#include /* alloca() */ -#endif - -#include -#include "main.h" -#include "adb.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" -#include "video_defs.h" -#include "video_blit.h" -#include "vm_alloc.h" - -#define DEBUG 0 -#include "debug.h" - -#define CODE_INVALID -1 -#define CODE_HOTKEY -2 - -// Supported video modes -using std::vector; -static vector VideoModes; - -// Display types -#ifdef SHEEPSHAVER -enum { - DISPLAY_WINDOW = DIS_WINDOW, // windowed display - DISPLAY_SCREEN = DIS_SCREEN // fullscreen display -}; -extern int display_type; // See enum above -#else -enum { - DISPLAY_WINDOW, // windowed display - DISPLAY_SCREEN // fullscreen display -}; -static int display_type = DISPLAY_WINDOW; // See enum above -#endif - -// Constants -#if defined(__MACOSX__) || defined(WIN32) -const char KEYCODE_FILE_NAME[] = "keycodes"; -const char KEYCODE_FILE_NAME2[] = "BasiliskII_keycodes"; -#else -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; -const char KEYCODE_FILE_NAME2[] = DATADIR "/BasiliskII_keycodes"; -#endif - - -// Global variables -static uint32 frame_skip; // Prefs items -static int16 mouse_wheel_mode; -static int16 mouse_wheel_lines; -static bool mouse_wheel_reverse; - -static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) -static uint32 the_buffer_size; // Size of allocated the_buffer - -static bool redraw_thread_active = false; // Flag: Redraw thread installed -#ifndef USE_CPU_EMUL_SERVICES -static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread -static SDL_Thread *redraw_thread = NULL; // Redraw thread -static volatile bool thread_stop_req = false; -static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req -#endif - -#ifdef ENABLE_VOSF -static bool use_vosf = false; // Flag: VOSF enabled -#else -static const bool use_vosf = false; // VOSF not possible -#endif - -static bool ctrl_down = false; // Flag: Ctrl key pressed -static bool opt_down = false; // Flag: Opt key pressed -static bool cmd_down = false; // Flag: Cmd key pressed -static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread -static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread -static bool emul_suspended = false; // Flag: Emulator suspended - -static bool classic_mode = false; // Flag: Classic Mac video mode - -static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms -static int keycode_table[256]; // X keycode -> Mac keycode translation table - -// SDL variables -SDL_Window * sdl_window = NULL; // Wraps an OS-native window -static SDL_Surface * host_surface = NULL; // Surface in host-OS display format -static SDL_Surface * guest_surface = NULL; // Surface in guest-OS display format -static SDL_Renderer * sdl_renderer = NULL; // Handle to SDL2 renderer -static SDL_threadID sdl_renderer_thread_id = 0; // Thread ID where the SDL_renderer was created, and SDL_renderer ops should run (for compatibility w/ d3d9) -static SDL_Texture * sdl_texture = NULL; // Handle to a GPU texture, with which to draw guest_surface to -static SDL_Rect sdl_update_video_rect = {0,0,0,0}; // Union of all rects to update, when updating sdl_texture -static SDL_mutex * sdl_update_video_mutex = NULL; // Mutex to protect sdl_update_video_rect -static int screen_depth; // Depth of current screen -static SDL_Cursor *sdl_cursor = NULL; // Copy of Mac cursor -static SDL_Palette *sdl_palette = NULL; // Color palette to be used as CLUT and gamma table -static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors -static bool toggle_fullscreen = false; -static bool did_add_event_watch = false; - -static bool mouse_grabbed = false; - -// Mutex to protect SDL events -static SDL_mutex *sdl_events_lock = NULL; -#define LOCK_EVENTS SDL_LockMutex(sdl_events_lock) -#define UNLOCK_EVENTS SDL_UnlockMutex(sdl_events_lock) - -// Mutex to protect palette -static SDL_mutex *sdl_palette_lock = NULL; -#define LOCK_PALETTE SDL_LockMutex(sdl_palette_lock) -#define UNLOCK_PALETTE SDL_UnlockMutex(sdl_palette_lock) - -// Mutex to protect frame buffer -static SDL_mutex *frame_buffer_lock = NULL; -#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock) -#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock) - -// Initially set gamma tables -static uint16 init_gamma_red[256]; -static uint16 init_gamma_green[256]; -static uint16 init_gamma_blue[256]; -static bool init_gamma_valid; - -// Previously set gamma tables -static uint16 last_gamma_red[256]; -static uint16 last_gamma_green[256]; -static uint16 last_gamma_blue[256]; - -// Video refresh function -static void VideoRefreshInit(void); -static void (*video_refresh)(void); - - -// Prototypes -static int redraw_func(void *arg); -static int present_sdl_video(); -static int SDLCALL on_sdl_event_generated(void *userdata, SDL_Event * event); -static bool is_fullscreen(SDL_Window *); - -// From sys_unix.cpp -extern void SysMountFirstFloppy(void); - - -/* - * SDL surface locking glue - */ - -#ifdef ENABLE_VOSF -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ - if (sdl_window && SDL_GetWindowFlags(sdl_window) & (SDL_WINDOW_FULLSCREEN)) \ - the_host_buffer = (uint8 *)(SURFACE)->pixels; \ -} while (0) -#else -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) -#endif - -#define SDL_VIDEO_LOCK_SURFACE(SURFACE) do { \ - if (SDL_MUSTLOCK(SURFACE)) { \ - SDL_LockSurface(SURFACE); \ - SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE); \ - } \ -} while (0) - -#define SDL_VIDEO_UNLOCK_SURFACE(SURFACE) do { \ - if (SDL_MUSTLOCK(SURFACE)) \ - SDL_UnlockSurface(SURFACE); \ -} while (0) - - -/* - * Framebuffer allocation routines - */ - -static void *vm_acquire_framebuffer(uint32 size) -{ -#ifdef HAVE_MACH_VM - return vm_acquire_reserved(size); -#else - // always try to reallocate framebuffer at the same address - static void *fb = VM_MAP_FAILED; - if (fb != VM_MAP_FAILED) { - if (vm_acquire_fixed(fb, size) < 0) { -#ifndef SHEEPSHAVER - printf("FATAL: Could not reallocate framebuffer at previous address\n"); -#endif - fb = VM_MAP_FAILED; - } - } - if (fb == VM_MAP_FAILED) - fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return fb; -#endif -} - -static inline void vm_release_framebuffer(void *fb, uint32 size) -{ -#ifndef HAVE_MACH_VM - vm_release(fb, size); -#endif -} - -static inline int get_customized_color_depth(int default_depth) -{ - int display_color_depth = PrefsFindInt32("displaycolordepth"); - - D(bug("Get displaycolordepth %d\n", display_color_depth)); - - if(0 == display_color_depth) - return default_depth; - else{ - switch (display_color_depth) { - case 8: - return VIDEO_DEPTH_8BIT; - case 15: case 16: - return VIDEO_DEPTH_16BIT; - case 24: case 32: - return VIDEO_DEPTH_32BIT; - default: - return default_depth; - } - } -} - -/* - * Windows message handler - */ - -#ifdef WIN32 -#include -static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL - -extern void SysMediaArrived(void); -extern void SysMediaRemoved(void); -extern HWND GetMainWindowHandle(void); - -static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_DEVICECHANGE: - if (wParam == DBT_DEVICEREMOVECOMPLETE) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaRemoved(); - } - else if (wParam == DBT_DEVICEARRIVAL) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaArrived(); - } - return 0; - - default: - if (sdl_window_proc) - return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} -#endif - - -/* - * SheepShaver glue - */ - -#ifdef SHEEPSHAVER -// Color depth modes type -typedef int video_depth; - -// 1, 2, 4 and 8 bit depths use a color palette -static inline bool IsDirectMode(VIDEO_MODE const & mode) -{ - return IsDirectMode(mode.viAppleMode); -} - -// Abstract base class representing one (possibly virtual) monitor -// ("monitor" = rectangular display with a contiguous frame buffer) -class monitor_desc { -public: - monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) {} - virtual ~monitor_desc() {} - - // Get current Mac frame buffer base address - uint32 get_mac_frame_base(void) const {return screen_base;} - - // Set Mac frame buffer base address (called from switch_to_mode()) - void set_mac_frame_base(uint32 base) {screen_base = base;} - - // Get current video mode - const VIDEO_MODE &get_current_mode(void) const {return VModes[cur_mode];} - - // Called by the video driver to switch the video mode on this display - // (must call set_mac_frame_base()) - virtual void switch_to_current_mode(void) = 0; - - // Called by the video driver to set the color palette (in indexed modes) - virtual void set_palette(uint8 *pal, int num) = 0; - - // Called by the video driver to set the gamma table - virtual void set_gamma(uint8 *gamma, int num) = 0; -}; - -// Vector of pointers to available monitor descriptions, filled by VideoInit() -static vector VideoMonitors; - -// Find Apple mode matching best specified dimensions -static int find_apple_resolution(int xsize, int ysize) -{ - if (xsize == 640 && ysize == 480) - return APPLE_640x480; - if (xsize == 800 && ysize == 600) - return APPLE_800x600; - if (xsize == 1024 && ysize == 768) - return APPLE_1024x768; - if (xsize == 1152 && ysize == 768) - return APPLE_1152x768; - if (xsize == 1152 && ysize == 900) - return APPLE_1152x900; - if (xsize == 1280 && ysize == 1024) - return APPLE_1280x1024; - if (xsize == 1600 && ysize == 1200) - return APPLE_1600x1200; - return APPLE_CUSTOM; -} - -// Display error alert -static void ErrorAlert(int error) -{ - ErrorAlert(GetString(error)); -} -#endif - - -/* - * monitor_desc subclass for SDL display - */ - -class SDL_monitor_desc : public monitor_desc { -public: - SDL_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~SDL_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - virtual void set_gamma(uint8 *gamma, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * Utility functions - */ - -// Find palette size for given color depth -static int palette_size(int mode) -{ - switch (mode) { - case VIDEO_DEPTH_1BIT: return 2; - case VIDEO_DEPTH_2BIT: return 4; - case VIDEO_DEPTH_4BIT: return 16; - case VIDEO_DEPTH_8BIT: return 256; - case VIDEO_DEPTH_16BIT: return 32; - case VIDEO_DEPTH_32BIT: return 256; - default: return 0; - } -} - -// Map video_mode depth ID to numerical depth value -static int mac_depth_of_video_depth(int video_depth) -{ - int depth = -1; - switch (video_depth) { - case VIDEO_DEPTH_1BIT: - depth = 1; - break; - case VIDEO_DEPTH_2BIT: - depth = 2; - break; - case VIDEO_DEPTH_4BIT: - depth = 4; - break; - case VIDEO_DEPTH_8BIT: - depth = 8; - break; - case VIDEO_DEPTH_16BIT: - depth = 16; - break; - case VIDEO_DEPTH_32BIT: - depth = 32; - break; - default: - abort(); - } - return depth; -} - -// Map video_mode depth ID to SDL screen depth -static int sdl_depth_of_video_depth(int video_depth) -{ - return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth); -} - -// Get screen dimensions -static void sdl_display_dimensions(int &width, int &height) -{ - SDL_DisplayMode desktop_mode; - const int display_index = 0; // TODO: try supporting multiple displays - if (SDL_GetDesktopDisplayMode(display_index, &desktop_mode) != 0) { - // TODO: report a warning, here? - width = height = 0; - return; - } - width = desktop_mode.w; - height = desktop_mode.h; -} - -static inline int sdl_display_width(void) -{ - int width, height; - sdl_display_dimensions(width, height); - return width; -} - -static inline int sdl_display_height(void) -{ - int width, height; - sdl_display_dimensions(width, height); - return height; -} - -// Check whether specified mode is available -static bool has_mode(int type, int width, int height, int depth) -{ - // Filter out out-of-bounds resolutions - if (width > sdl_display_width() || height > sdl_display_height()) - return false; - - // Whatever size it is, beyond what we've checked, we'll scale to/from as appropriate. - return true; -} - -// Add mode to list of supported modes -static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) -{ - // Filter out unsupported modes - if (!has_mode(type, width, height, depth)) - return; - - // Fill in VideoMode entry - VIDEO_MODE mode; -#ifdef SHEEPSHAVER - resolution_id = find_apple_resolution(width, height); - mode.viType = type; -#endif - VIDEO_MODE_X = width; - VIDEO_MODE_Y = height; - VIDEO_MODE_RESOLUTION = resolution_id; - VIDEO_MODE_ROW_BYTES = bytes_per_row; - VIDEO_MODE_DEPTH = (video_depth)depth; - VideoModes.push_back(mode); -} - -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool native_byte_order) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - int layout = FLAYOUT_DIRECT; - if (depth == VIDEO_DEPTH_16BIT) - layout = (screen_depth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; - else if (depth == VIDEO_DEPTH_32BIT) - layout = (screen_depth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; - if (native_byte_order) - MacFrameLayout = layout; - else - MacFrameLayout = FLAYOUT_DIRECT; - monitor.set_mac_frame_base(MacFrameBaseMac); - - // Set variables used by UAE memory banking - const VIDEO_MODE &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; - MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - InitFrameBufferMapping(); -#else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); -#endif - D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); -} - -// Set window name and class -static void set_window_name() { - if (!sdl_window) return; - const char *title = PrefsFindString("title"); - std::string s = title ? title : GetString(STR_WINDOW_TITLE); - if (mouse_grabbed) { - s += GetString(STR_WINDOW_TITLE_GRABBED0); - int hotkey = PrefsFindInt32("hotkey"); - if (!hotkey) hotkey = 1; - if (hotkey & 1) s += GetString(STR_WINDOW_TITLE_GRABBED1); - if (hotkey & 2) s += GetString(STR_WINDOW_TITLE_GRABBED2); - if (hotkey & 4) s += GetString(STR_WINDOW_TITLE_GRABBED3); - s += GetString(STR_WINDOW_TITLE_GRABBED4); - } - SDL_SetWindowTitle(sdl_window, s.c_str()); -} - -// Migrate preferences items (XXX to be handled in MigratePrefs()) -static void migrate_screen_prefs(void) -{ -#ifdef SHEEPSHAVER - // Look-up priorities are: "screen", "screenmodes", "windowmodes". - if (PrefsFindString("screen")) - return; - - uint32 window_modes = PrefsFindInt32("windowmodes"); - uint32 screen_modes = PrefsFindInt32("screenmodes"); - int width = 0, height = 0; - if (screen_modes) { - static const struct { - int id; - int width; - int height; - } - modes[] = { - { 1, 640, 480 }, - { 2, 800, 600 }, - { 4, 1024, 768 }, - { 64, 1152, 768 }, - { 8, 1152, 900 }, - { 16, 1280, 1024 }, - { 32, 1600, 1200 }, - { 0, } - }; - for (int i = 0; modes[i].id != 0; i++) { - if (screen_modes & modes[i].id) { - if (width < modes[i].width && height < modes[i].height) { - width = modes[i].width; - height = modes[i].height; - } - } - } - } else { - if (window_modes & 1) - width = 640, height = 480; - if (window_modes & 2) - width = 800, height = 600; - } - if (width && height) { - char str[32]; - sprintf(str, "%s/%d/%d", screen_modes ? "dga" : "win", width, height); - PrefsReplaceString("screen", str); - } -#endif -} - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(SDL_monitor_desc &m); - ~driver_base(); - - void init(); // One-time init - void set_video_mode(int flags); - void adapt_to_video_mode(); - - void update_palette(void); - void suspend(void) {} - void resume(void) {} - void toggle_mouse_grab(void); - void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } - - void disable_mouse_accel(void); - void restore_mouse_accel(void); - - void grab_mouse(void); - void ungrab_mouse(void); - -public: - SDL_monitor_desc &monitor; // Associated video monitor - const VIDEO_MODE &mode; // Video mode handled by the driver - - bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - SDL_Surface *s; // The surface we draw into -}; - -#ifdef ENABLE_VOSF -static void update_display_window_vosf(driver_base *drv); -#endif -static void update_display_static(driver_base *drv); - -static driver_base *drv = NULL; // Pointer to currently used driver object - -#ifdef ENABLE_VOSF -# include "video_vosf.h" -#endif - -driver_base::driver_base(SDL_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false), s(NULL) -{ - the_buffer = NULL; - the_buffer_copy = NULL; -} - -static void delete_sdl_video_surfaces() -{ - if (sdl_texture) { - SDL_DestroyTexture(sdl_texture); - sdl_texture = NULL; - } - - if (host_surface) { - if (host_surface == guest_surface) { - guest_surface = NULL; - } - - SDL_FreeSurface(host_surface); - host_surface = NULL; - } - - if (guest_surface) { - SDL_FreeSurface(guest_surface); - guest_surface = NULL; - } -} - -static void delete_sdl_video_window() -{ - if (sdl_renderer) { - SDL_DestroyRenderer(sdl_renderer); - sdl_renderer = NULL; - } - - if (sdl_window) { - SDL_DestroyWindow(sdl_window); - sdl_window = NULL; - } -} - -static void shutdown_sdl_video() -{ - delete_sdl_video_surfaces(); - delete_sdl_video_window(); -} - -static int get_mag_rate() -{ - int m = PrefsFindInt32("mag_rate"); - return m < 1 ? 1 : m > 4 ? 4 : m; -} - -static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags) -{ - if (guest_surface) { - delete_sdl_video_surfaces(); - } - - int window_width = width; - int window_height = height; - Uint32 window_flags = SDL_WINDOW_ALLOW_HIGHDPI; - const int window_flags_to_monitor = SDL_WINDOW_FULLSCREEN; - - if (flags & SDL_WINDOW_FULLSCREEN) { - SDL_DisplayMode desktop_mode; - if (SDL_GetDesktopDisplayMode(0, &desktop_mode) != 0) { - shutdown_sdl_video(); - return NULL; - } -#ifdef __MACOSX__ - window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - window_width = desktop_mode.w; - window_height = desktop_mode.h; -#else - window_flags |= SDL_WINDOW_FULLSCREEN; -#endif - } - - if (sdl_window) { - int old_window_width, old_window_height, old_window_flags; - SDL_GetWindowSize(sdl_window, &old_window_width, &old_window_height); - old_window_flags = SDL_GetWindowFlags(sdl_window); - if (old_window_width != window_width || - old_window_height != window_height || - (old_window_flags & window_flags_to_monitor) != (window_flags & window_flags_to_monitor)) - { - delete_sdl_video_window(); - } - } - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, PrefsFindBool("scale_nearest") ? "nearest" : "linear"); - -#if defined(__MACOSX__) && SDL_VERSION_ATLEAST(2,0,14) - if (MetalIsAvailable()) window_flags |= SDL_WINDOW_METAL; -#endif - - if (!sdl_window) { - int m = get_mag_rate(); - sdl_window = SDL_CreateWindow( - "", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - m * window_width, - m * window_height, - window_flags); - if (!sdl_window) { - shutdown_sdl_video(); - return NULL; - } - set_window_name(); - } - if (flags & SDL_WINDOW_FULLSCREEN) SDL_SetWindowGrab(sdl_window, SDL_TRUE); - - // Some SDL events (regarding some native-window events), need processing - // as they are generated. SDL2 has a facility, SDL_AddEventWatch(), which - // allows events to be processed as they are generated. - if (!did_add_event_watch) { - SDL_AddEventWatch(&on_sdl_event_generated, NULL); - did_add_event_watch = true; - } - - if (!sdl_renderer) { - const char *render_driver = PrefsFindString("sdlrender"); - if (render_driver) { - SDL_SetHint(SDL_HINT_RENDER_DRIVER, render_driver); - } - else { -#ifdef WIN32 - SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); -#elif defined(__MACOSX__) && SDL_VERSION_ATLEAST(2,0,14) - SDL_SetHint(SDL_HINT_RENDER_DRIVER, window_flags & SDL_WINDOW_METAL ? "metal" : "opengl"); -#else - SDL_SetHint(SDL_HINT_RENDER_DRIVER, ""); -#endif - } - - bool sdl_vsync = PrefsFindBool("sdl_vsync"); - if (sdl_vsync) { - SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1"); - } - - sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0); - - if (!sdl_renderer) { - shutdown_sdl_video(); - return NULL; - } - sdl_renderer_thread_id = SDL_ThreadID(); - - SDL_RendererInfo info; - memset(&info, 0, sizeof(info)); - SDL_GetRendererInfo(sdl_renderer, &info); - printf("Using SDL_Renderer driver: %s\n", (info.name ? info.name : "(null)")); - } - - if (!sdl_update_video_mutex) { - sdl_update_video_mutex = SDL_CreateMutex(); - } - - SDL_assert(sdl_texture == NULL); - sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); - if (!sdl_texture) { - shutdown_sdl_video(); - return NULL; - } - sdl_update_video_rect.x = 0; - sdl_update_video_rect.y = 0; - sdl_update_video_rect.w = 0; - sdl_update_video_rect.h = 0; - - SDL_assert(guest_surface == NULL); - SDL_assert(host_surface == NULL); - switch (bpp) { - case 8: - guest_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0); - break; - case 16: - guest_surface = SDL_CreateRGBSurface(0, width, height, 16, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000); - break; - case 32: - guest_surface = SDL_CreateRGBSurface(0, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); - host_surface = guest_surface; - break; - default: - printf("WARNING: An unsupported bpp of %d was used\n", bpp); - break; - } - if (!guest_surface) { - shutdown_sdl_video(); - return NULL; - } - - if (!host_surface) { - Uint32 texture_format; - if (SDL_QueryTexture(sdl_texture, &texture_format, NULL, NULL, NULL) != 0) { - printf("ERROR: Unable to get the SDL texture's pixel format: %s\n", SDL_GetError()); - shutdown_sdl_video(); - return NULL; - } - - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - if (!SDL_PixelFormatEnumToMasks(texture_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { - printf("ERROR: Unable to determine format for host SDL_surface: %s\n", SDL_GetError()); - shutdown_sdl_video(); - return NULL; - } - - host_surface = SDL_CreateRGBSurface(0, width, height, bpp, Rmask, Gmask, Bmask, Amask); - if (!host_surface) { - printf("ERROR: Unable to create host SDL_surface: %s\n", SDL_GetError()); - shutdown_sdl_video(); - return NULL; - } - } - - if (SDL_RenderSetLogicalSize(sdl_renderer, width, height) != 0) { - printf("ERROR: Unable to set SDL rendeer's logical size (to %dx%d): %s\n", - width, height, SDL_GetError()); - shutdown_sdl_video(); - return NULL; - } - - SDL_RenderSetIntegerScale(sdl_renderer, PrefsFindBool("scale_integer") ? SDL_TRUE : SDL_FALSE); - - return guest_surface; -} - -static int present_sdl_video() -{ - if (SDL_RectEmpty(&sdl_update_video_rect)) return 0; - - if (!sdl_renderer || !sdl_texture || !guest_surface) { - printf("WARNING: A video mode does not appear to have been set.\n"); - return -1; - } - - // Some systems, such as D3D9, can fail if and when they are used across - // certain operations. To address this, only utilize SDL_Renderer in a - // single thread, preferably the main thread. - // - // This was added as part of a fix for https://github.com/DavidLudwig/macemu/issues/21 - // "BasiliskII, Win32: resizing a window does not stretch " - SDL_assert(SDL_ThreadID() == sdl_renderer_thread_id); - - // Make sure the display's internal (to SDL, possibly the OS) buffer gets - // cleared. Not doing so can, if and when letterboxing is applied (whereby - // colored bars are drawn on the screen's sides to help with aspect-ratio - // correction), the colored bars can be an unknown color. - SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, 0); // Use black - SDL_RenderClear(sdl_renderer); // Clear the display - - // We're about to work with sdl_update_video_rect, so stop other threads from - // modifying it! - LOCK_PALETTE; - SDL_LockMutex(sdl_update_video_mutex); - // Convert from the guest OS' pixel format, to the host OS' texture, if necessary. - if (host_surface != guest_surface && - host_surface != NULL && - guest_surface != NULL) - { - SDL_Rect destRect = sdl_update_video_rect; - int result = SDL_BlitSurface(guest_surface, &sdl_update_video_rect, host_surface, &destRect); - if (result != 0) { - SDL_UnlockMutex(sdl_update_video_mutex); - UNLOCK_PALETTE; - return -1; - } - } - UNLOCK_PALETTE; // passed potential deadlock, can unlock palette - - // Update the host OS' texture - void * srcPixels = (void *)((uint8_t *)host_surface->pixels + - sdl_update_video_rect.y * host_surface->pitch + - sdl_update_video_rect.x * host_surface->format->BytesPerPixel); - - if (SDL_UpdateTexture(sdl_texture, &sdl_update_video_rect, srcPixels, host_surface->pitch) != 0) { - SDL_UnlockMutex(sdl_update_video_mutex); - return -1; - } - - // We are done working with pixels in host_surface. Reset sdl_update_video_rect, then let - // other threads modify it, as-needed. - sdl_update_video_rect.x = 0; - sdl_update_video_rect.y = 0; - sdl_update_video_rect.w = 0; - sdl_update_video_rect.h = 0; - SDL_UnlockMutex(sdl_update_video_mutex); - - // Copy the texture to the display - if (SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL) != 0) { - return -1; - } - - // Update the display - SDL_RenderPresent(sdl_renderer); - - // Indicate success to the caller! - return 0; -} - -void update_sdl_video(SDL_Surface *s, int numrects, SDL_Rect *rects) -{ - // TODO: make sure SDL_Renderer resources get displayed, if and when - // MacsBug is running (and VideoInterrupt() might not get called) - - SDL_LockMutex(sdl_update_video_mutex); - for (int i = 0; i < numrects; ++i) { - SDL_UnionRect(&sdl_update_video_rect, &rects[i], &sdl_update_video_rect); - } - SDL_UnlockMutex(sdl_update_video_mutex); -} - -void update_sdl_video(SDL_Surface *s, Sint32 x, Sint32 y, Sint32 w, Sint32 h) -{ - SDL_Rect temp = {x, y, w, h}; - update_sdl_video(s, 1, &temp); -} - -#ifdef SHEEPSHAVER -static void MagBits(Uint8 *dst, Uint8 *src, int mag) { - for (int y = 0; y < 16; y++) - for (int x = 0; x < 16; x++) { - int sa = 16 * y + x; - if (!(src[sa >> 3] & 0x80 >> (sa & 7))) continue; - for (int dy = 0; dy < mag; dy++) - for (int dx = 0; dx < mag; dx++) { - int da = 16 * mag * (mag * y + dy) + mag * x + dx; - dst[da >> 3] |= 0x80 >> (da & 7); - } - } -} -static SDL_Cursor *MagCursor(bool hot) { - int w, h; - SDL_GetWindowSize(sdl_window, &w, &h); - int mag = std::min(w / drv->VIDEO_MODE_X, h / drv->VIDEO_MODE_Y); - Uint8 *data = (Uint8 *)SDL_calloc(1, 32 * mag * mag); - Uint8 *mask = (Uint8 *)SDL_calloc(1, 32 * mag * mag); - MagBits(data, &MacCursor[4], mag); - MagBits(mask, &MacCursor[36], mag); - SDL_Cursor *cursor = SDL_CreateCursor(data, mask, 16 * mag, 16 * mag, hot ? MacCursor[2] * mag : 0, hot ? MacCursor[3] * mag : 0); - SDL_free(data); - SDL_free(mask); - return cursor; -} -#endif - -void driver_base::set_video_mode(int flags) -{ - int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - if ((s = init_sdl_video(VIDEO_MODE_X, VIDEO_MODE_Y, depth, flags)) == NULL) - return; -#ifdef ENABLE_VOSF - the_host_buffer = (uint8 *)s->pixels; -#endif -} - -void driver_base::init() -{ - set_video_mode(display_type == DISPLAY_SCREEN ? SDL_WINDOW_FULLSCREEN : 0); - int aligned_height = (VIDEO_MODE_Y + 15) & ~15; - -#ifdef ENABLE_VOSF - use_vosf = true; - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_buffer_size = page_extend((aligned_height + 2) * s->pitch); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); - - // Check whether we can initialize the VOSF subsystem and it's profitable - if (!video_vosf_init(monitor)) { - WarningAlert(GetString(STR_VOSF_INIT_ERR)); - use_vosf = false; - } - else if (!video_vosf_profitable()) { - video_vosf_exit(); - printf("VOSF acceleration is not profitable on this platform, disabling it\n"); - use_vosf = false; - } - if (!use_vosf) { - free(the_buffer_copy); - vm_release(the_buffer, the_buffer_size); - the_host_buffer = NULL; - } -#endif - if (!use_vosf) { - // Allocate memory for frame buffer - the_buffer_size = (aligned_height + 2) * s->pitch; - the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); - } - - // Set frame buffer base - set_mac_frame_buffer(monitor, VIDEO_MODE_DEPTH, true); - - adapt_to_video_mode(); - - // set default B/W palette - sdl_palette = SDL_AllocPalette(256); - sdl_palette->colors[1] = (SDL_Color){ .r = 0, .g = 0, .b = 0, .a = 255 }; - SDL_SetSurfacePalette(s, sdl_palette); -} - -void driver_base::adapt_to_video_mode() { - ADBSetRelMouseMode(mouse_grabbed); - - // Init blitting routines - SDL_PixelFormat *f = s->format; - VisualFormat visualFormat; - visualFormat.depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - visualFormat.Rmask = f->Rmask; - visualFormat.Gmask = f->Gmask; - visualFormat.Bmask = f->Bmask; - Screen_blitter_init(visualFormat, true, mac_depth_of_video_depth(VIDEO_MODE_DEPTH)); - - // Load gray ramp to 8->16/32 expand map - if (!IsDirectMode(mode)) - for (int i=0; i<256; i++) - ExpandMap[i] = SDL_MapRGB(f, i, i, i); - - - bool hardware_cursor = false; -#ifdef SHEEPSHAVER - hardware_cursor = video_can_change_cursor(); - if (hardware_cursor) { - // Create cursor - if ((sdl_cursor = MagCursor(false)) != NULL) { - SDL_SetCursor(sdl_cursor); - } - } - // Tell the video driver there's a change in cursor type - if (private_data) - private_data->cursorHardware = hardware_cursor; -#endif - SDL_LockMutex(sdl_update_video_mutex); - sdl_update_video_rect.x = 0; - sdl_update_video_rect.y = 0; - sdl_update_video_rect.w = VIDEO_MODE_X; - sdl_update_video_rect.h = VIDEO_MODE_Y; - SDL_UnlockMutex(sdl_update_video_mutex); - - // Hide cursor - SDL_ShowCursor(hardware_cursor); - - // Set window name/class - set_window_name(); - - // Everything went well - init_ok = true; -} - -driver_base::~driver_base() -{ - ungrab_mouse(); - restore_mouse_accel(); - - // HACK: Just delete instances of SDL_Surface and SDL_Texture, rather - // than also the SDL_Window and SDL_Renderer. This fixes a bug whereby - // OSX hosts, when in fullscreen, will, on a guest OS resolution change, - // do a series of switches (using OSX's "Spaces" feature) to and from - // the Basilisk II desktop, - delete_sdl_video_surfaces(); // This deletes instances of SDL_Surface and SDL_Texture - //shutdown_sdl_video(); // This deletes SDL_Window, SDL_Renderer, in addition to - // instances of SDL_Surface and SDL_Texture. - - // the_buffer shall always be mapped through vm_acquire_framebuffer() - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release_framebuffer(the_buffer, the_buffer_size); - the_buffer = NULL; - } - - // Free frame buffer(s) - if (!use_vosf) { - if (the_buffer_copy) { - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#ifdef ENABLE_VOSF - else { - if (the_buffer_copy) { - D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); - free(the_buffer_copy); - the_buffer_copy = NULL; - } - - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - SDL_ShowCursor(1); -} - -// Palette has changed -void driver_base::update_palette(void) -{ - const VIDEO_MODE &mode = monitor.get_current_mode(); - - if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) { - SDL_SetSurfacePalette(s, sdl_palette); - SDL_LockMutex(sdl_update_video_mutex); - sdl_update_video_rect.x = 0; - sdl_update_video_rect.y = 0; - sdl_update_video_rect.w = VIDEO_MODE_X; - sdl_update_video_rect.h = VIDEO_MODE_Y; - SDL_UnlockMutex(sdl_update_video_mutex); - } -} - -// Disable mouse acceleration -void driver_base::disable_mouse_accel(void) -{ -} - -// Restore mouse acceleration to original value -void driver_base::restore_mouse_accel(void) -{ -} - -// Toggle mouse grab -void driver_base::toggle_mouse_grab(void) -{ - if (mouse_grabbed) - ungrab_mouse(); - else - grab_mouse(); -} - -static void update_mouse_grab() -{ - if (mouse_grabbed) { - SDL_SetRelativeMouseMode(SDL_TRUE); - } else { - SDL_SetRelativeMouseMode(SDL_FALSE); - } -} - -// Grab mouse, switch to relative mouse mode -void driver_base::grab_mouse(void) -{ - if (!mouse_grabbed) { - mouse_grabbed = true; - update_mouse_grab(); - set_window_name(); - disable_mouse_accel(); - ADBSetRelMouseMode(true); - } -} - -// Ungrab mouse, switch to absolute mouse mode -void driver_base::ungrab_mouse(void) -{ - if (mouse_grabbed) { - mouse_grabbed = false; - update_mouse_grab(); - set_window_name(); - restore_mouse_accel(); - ADBSetRelMouseMode(false); - } -} - -/* - * Initialization - */ - -// Init keycode translation table -static void keycode_init(void) -{ - bool use_kc = PrefsFindBool("keycodes"); - if (use_kc) { - - // Get keycode file path from preferences - const char *kc_path = PrefsFindString("keycodefile"); - - // Open keycode table - FILE *f = fopen(kc_path && *kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); - if (f == NULL) f = fopen(KEYCODE_FILE_NAME2, "r"); - if (f == NULL) { - char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); - WarningAlert(str); - return; - } - - // Default translation table - for (int i=0; i<256; i++) - keycode_table[i] = CODE_INVALID; - - // Search for server vendor string, then read keycodes - const char * video_driver = SDL_GetCurrentVideoDriver(); - bool video_driver_found = false; - char line[256]; - int n_keys = 0; - while (fgets(line, sizeof(line) - 1, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - - // Comments begin with "#" or ";" - if (line[0] == '#' || line[0] == ';' || line[0] == 0) - continue; - - if (video_driver_found) { - // Skip aliases as long as we have read keycodes yet - // Otherwise, it's another mapping and we have to stop - static const char sdl_str[] = "sdl"; - if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0 && n_keys == 0) - continue; - - // Read keycode - int x_code, mac_code; - if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) - keycode_table[x_code & 0xff] = mac_code, n_keys++; - else - break; - } else { - // Search for SDL video driver string - static const char sdl_str[] = "sdl"; - if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) { - char *p = line + sizeof(sdl_str); - if (video_driver && strstr(video_driver, p) == video_driver) - video_driver_found = true; - } - } - } - - // Keycode file completely read - fclose(f); - use_keycodes = video_driver_found; - - // Vendor not found? Then display warning - if (!video_driver_found) { - char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver ? video_driver : "", kc_path ? kc_path : KEYCODE_FILE_NAME); - WarningAlert(str); - return; - } - - D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver ? video_driver : "", n_keys)); - } -} - -// Open display for current mode -bool SDL_monitor_desc::video_open(void) -{ - D(bug("video_open()\n")); -#if DEBUG - const VIDEO_MODE &mode = get_current_mode(); - D(bug("Current video mode:\n")); - D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f))); -#endif - - // Create display driver object of requested type - drv = new(std::nothrow) driver_base(*this); - if (drv == NULL) - return false; - drv->init(); - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - -#ifdef WIN32 - // Chain in a new message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); -#endif - - // Initialize VideoRefresh function - VideoRefreshInit(); - - // Lock down frame buffer - LOCK_FRAME_BUFFER; - - // Start redraw/input thread -#ifndef USE_CPU_EMUL_SERVICES - redraw_thread_cancel = false; - redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, "Redraw Thread", NULL)) != NULL); - if (!redraw_thread_active) { - printf("FATAL: cannot create redraw thread\n"); - return false; - } -#else - redraw_thread_active = true; -#endif - return true; -} - -#ifdef SHEEPSHAVER -bool VideoInit(void) -{ - const bool classic = false; -#else -bool VideoInit(bool classic) -{ -#endif - classic_mode = classic; - -#ifdef ENABLE_VOSF - // Zero the mainBuffer structure - mainBuffer.dirtyPages = NULL; - mainBuffer.pageInfo = NULL; -#endif - - // Create Mutexes - if ((sdl_events_lock = SDL_CreateMutex()) == NULL) - return false; - if ((sdl_palette_lock = SDL_CreateMutex()) == NULL) - return false; - if ((frame_buffer_lock = SDL_CreateMutex()) == NULL) - return false; - - // Init keycode translation - keycode_init(); - - // Read prefs - frame_skip = PrefsFindInt32("frameskip"); - mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); - mouse_wheel_lines = PrefsFindInt32("mousewheellines"); - mouse_wheel_reverse = mouse_wheel_lines < 0; - if (mouse_wheel_reverse) mouse_wheel_lines = -mouse_wheel_lines; - - // Get screen mode from preferences - migrate_screen_prefs(); - const char *mode_str = NULL; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width, default_height; - if (classic) { - default_width = 512; - default_height = 384; - } - else { - default_width = 640; - default_height = 480; - } - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_SCREEN; - } - if (default_width <= 0) - default_width = sdl_display_width(); - else if (default_width > sdl_display_width()) - default_width = sdl_display_width(); - if (default_height <= 0) - default_height = sdl_display_height(); - else if (default_height > sdl_display_height()) - default_height = sdl_display_height(); - - // Mac screen depth follows X depth - screen_depth = 32; - SDL_DisplayMode desktop_mode; - if (SDL_GetDesktopDisplayMode(0, &desktop_mode) == 0) { - screen_depth = SDL_BITSPERPIXEL(desktop_mode.format); - } - int default_depth; - switch (screen_depth) { - case 8: - default_depth = VIDEO_DEPTH_8BIT; - break; - case 15: case 16: - default_depth = VIDEO_DEPTH_16BIT; - break; - case 24: case 32: - default_depth = VIDEO_DEPTH_32BIT; - break; - default: - default_depth = VIDEO_DEPTH_1BIT; - break; - } - - // Initialize list of video modes to try - struct { - int w; - int h; - int resolution_id; - } -#ifdef SHEEPSHAVER - // Omit Classic resolutions - video_modes[] = { - { -1, -1, 0x80 }, - { 640, 480, 0x81 }, - { 800, 600, 0x82 }, - { 1024, 768, 0x83 }, - { 1152, 870, 0x84 }, - { 1280, 1024, 0x85 }, - { 1600, 1200, 0x86 }, - { 0, } - }; -#else - video_modes[] = { - { -1, -1, 0x80 }, - { 512, 384, 0x80 }, - { 640, 480, 0x81 }, - { 800, 600, 0x82 }, - { 1024, 768, 0x83 }, - { 1152, 870, 0x84 }, - { 1280, 1024, 0x85 }, - { 1600, 1200, 0x86 }, - { 0, } - }; -#endif - video_modes[0].w = default_width; - video_modes[0].h = default_height; - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT); - else { - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (i > 0 && (w >= default_width || h >= default_height)) - continue; - for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) - add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); - } - } - } else if (display_type == DISPLAY_SCREEN) { - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (i > 0 && (w >= default_width || h >= default_height)) - continue; - for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) - add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); - } - } - - if (VideoModes.empty()) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - const VIDEO_MODE & mode = (*i); - if (VIDEO_MODE_X == default_width && VIDEO_MODE_Y == default_height && VIDEO_MODE_DEPTH == default_depth) { - default_id = VIDEO_MODE_RESOLUTION; -#ifdef SHEEPSHAVER - std::vector::const_iterator begin = VideoModes.begin(); - cur_mode = distance(begin, i); -#endif - break; - } - } - if (i == end) { // not found, use first available mode - const VIDEO_MODE & mode = VideoModes[0]; - default_depth = VIDEO_MODE_DEPTH; - default_id = VIDEO_MODE_RESOLUTION; -#ifdef SHEEPSHAVER - cur_mode = 0; -#endif - } - -#ifdef SHEEPSHAVER - for (int i = 0; i < VideoModes.size(); i++) - VModes[i] = VideoModes[i]; - VideoInfo *p = &VModes[VideoModes.size()]; - p->viType = DIS_INVALID; // End marker - p->viRowBytes = 0; - p->viXsize = p->viYsize = 0; - p->viAppleMode = 0; - p->viAppleID = 0; -#endif - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - const VIDEO_MODE & mode = (*i); - int bits = 1 << VIDEO_MODE_DEPTH; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << bits)); - } -#endif - - int color_depth = get_customized_color_depth(default_depth); - - D(bug("Return get_customized_color_depth %d\n", color_depth)); - - // Create SDL_monitor_desc for this (the only) display - SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)color_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - - -/* - * Deinitialization - */ - -// Close display -void SDL_monitor_desc::video_close(void) -{ - D(bug("video_close()\n")); - -#ifdef WIN32 - // Remove message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); -#endif - - // Stop redraw thread -#ifndef USE_CPU_EMUL_SERVICES - if (redraw_thread_active) { - redraw_thread_cancel = true; - SDL_WaitThread(redraw_thread, NULL); - } -#endif - redraw_thread_active = false; - - // Unlock frame buffer - UNLOCK_FRAME_BUFFER; - D(bug(" frame buffer unlocked\n")); - - // Close display - delete drv; - drv = NULL; -} - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); - - // Destroy locks - if (frame_buffer_lock) - SDL_DestroyMutex(frame_buffer_lock); - if (sdl_palette_lock) - SDL_DestroyMutex(sdl_palette_lock); - if (sdl_events_lock) - SDL_DestroyMutex(sdl_events_lock); -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - quit_full_screen = true; -} - -static void ApplyGammaRamp() { - if (sdl_window) { - int result; - if (!init_gamma_valid) { - result = SDL_GetWindowGammaRamp(sdl_window, init_gamma_red, init_gamma_green, init_gamma_blue); - if (result < 0) - fprintf(stderr, "SDL_GetWindowGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); - init_gamma_valid = true; - } - const char *s = PrefsFindString("gammaramp"); - if (!s) s = "off"; - if (strcmp(s, "off") && (strcmp(s, "fullscreen") || display_type == DISPLAY_SCREEN)) - result = SDL_SetWindowGammaRamp(sdl_window, last_gamma_red, last_gamma_green, last_gamma_blue); - else - result = SDL_SetWindowGammaRamp(sdl_window, init_gamma_red, init_gamma_green, init_gamma_blue); - if (result < 0) - fprintf(stderr, "SDL_SetWindowGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); - } -} - -static void do_toggle_fullscreen(void) -{ -#ifndef USE_CPU_EMUL_SERVICES - // pause redraw thread - thread_stop_ack = false; - thread_stop_req = true; - while (!thread_stop_ack) ; -#endif - - // Apply fullscreen - if (sdl_window) { - if (display_type == DISPLAY_SCREEN) { - display_type = DISPLAY_WINDOW; - SDL_SetWindowFullscreen(sdl_window, 0); - const VIDEO_MODE &mode = drv->mode; - int m = get_mag_rate(); - SDL_SetWindowSize(sdl_window, m * VIDEO_MODE_X, m * VIDEO_MODE_Y); - SDL_SetWindowGrab(sdl_window, SDL_FALSE); - } else { - display_type = DISPLAY_SCREEN; -#ifdef __MACOSX__ - SDL_SetWindowFullscreen(sdl_window, SDL_WINDOW_FULLSCREEN_DESKTOP); -#else - SDL_SetWindowFullscreen(sdl_window, SDL_WINDOW_FULLSCREEN); -#endif - SDL_SetWindowGrab(sdl_window, SDL_TRUE); - } - } - - // switch modes - drv->adapt_to_video_mode(); - - // reset the palette -#ifdef SHEEPSHAVER - video_set_palette(); -#endif - ApplyGammaRamp(); - drv->update_palette(); - - // reset the video refresh handler - VideoRefreshInit(); - - // while SetVideoMode is happening, control key up may be missed - ADBKeyUp(0x36); - - // resume redraw thread - toggle_fullscreen = false; -#ifndef USE_CPU_EMUL_SERVICES - thread_stop_req = false; -#endif -} - -/* - * Mac VBL interrupt - */ - -/* - * Execute video VBL routine - */ - -static bool is_fullscreen(SDL_Window * window) -{ -#ifdef __MACOSX__ - // On OSX, SDL, at least as of 2.0.5 (and possibly beyond), does not always - // report changes to fullscreen via the SDL_WINDOW_FULLSCREEN flag. - // (Example: https://bugzilla.libsdl.org/show_bug.cgi?id=3766 , which - // involves fullscreen/windowed toggles via window-manager UI controls). - // Until it does, or adds a facility to do so, we'll use a platform-specific - // code path to detect fullscreen changes. - extern bool is_fullscreen_osx(SDL_Window * window); - return is_fullscreen_osx(sdl_window); -#else - if (!window) { - return false; - } - const Uint32 sdl_window_flags = SDL_GetWindowFlags(sdl_window); - return (sdl_window_flags & SDL_WINDOW_FULLSCREEN) != 0; -#endif -} - -#ifdef SHEEPSHAVER -void VideoVBL(void) -{ - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - if (toggle_fullscreen) - do_toggle_fullscreen(); - - present_sdl_video(); - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; - - // Execute video VBL - if (private_data != NULL && private_data->interruptsEnabled) - VSLDoInterruptService(private_data->vslServiceID); -} -#else -void VideoInterrupt(void) -{ - // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() - SDL_PumpEvents(); - - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - if (toggle_fullscreen) - do_toggle_fullscreen(); - - present_sdl_video(); - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; -} -#endif - - -/* - * Set palette - */ - -#ifdef SHEEPSHAVER -void video_set_palette(void) -{ - monitor_desc * monitor = VideoMonitors[0]; - int n_colors = palette_size(monitor->get_current_mode().viAppleMode); - uint8 pal[256 * 3]; - for (int c = 0; c < n_colors; c++) { - pal[c*3 + 0] = mac_pal[c].red; - pal[c*3 + 1] = mac_pal[c].green; - pal[c*3 + 2] = mac_pal[c].blue; - } - monitor->set_palette(pal, n_colors); -} - -void video_set_gamma(int n_colors) -{ - monitor_desc * monitor = VideoMonitors[0]; - uint8 gamma[256 * 3]; - for (int c = 0; c < n_colors; c++) { - gamma[c*3 + 0] = mac_gamma[c].red; - gamma[c*3 + 1] = mac_gamma[c].green; - gamma[c*3 + 2] = mac_gamma[c].blue; - } - monitor->set_gamma(gamma, n_colors); -} -#endif - -void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) -{ - - const VIDEO_MODE &mode = get_current_mode(); - - LOCK_PALETTE; - - // Convert colors to XColor array - int num_out = 256; - bool stretch = false; - - if (!sdl_palette) { - sdl_palette = SDL_AllocPalette(num_out); - } - - SDL_Color *p = sdl_palette->colors; - for (int i=0; ir = pal[c*3 + 0] * 0x0101; - p->g = pal[c*3 + 1] * 0x0101; - p->b = pal[c*3 + 2] * 0x0101; - p++; - } - - // Recalculate pixel color expansion map - if (!IsDirectMode(mode)) { - for (int i=0; i<256; i++) { - int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) - ExpandMap[i] = SDL_MapRGB(drv->s->format, pal[c*3+0], pal[c*3+1], pal[c*3+2]); - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // We have to redraw everything because the interpretation of pixel values changed - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); - } -#endif - } - - // Tell redraw thread to change palette - sdl_palette_changed = true; - - UNLOCK_PALETTE; -} - -void SDL_monitor_desc::set_gamma(uint8 *gamma, int num_in) -{ - // handle the gamma ramp - - if (gamma[0] == 127 && gamma[num_in*3-1] == 127) // solid grey - return; // ignore - - uint16 red[256]; - uint16 green[256]; - uint16 blue[256]; - - int repeats = 256 / num_in; - - for (int i = 0; i < num_in; i++) { - for (int j = 0; j < repeats; j++) { - red[i*repeats + j] = gamma[i*3 + 0] << 8; - green[i*repeats + j] = gamma[i*3 + 1] << 8; - blue[i*repeats + j] = gamma[i*3 + 2] << 8; - } - } - - // fill remaining entries (if any) with last value - for (int i = num_in * repeats; i < 256; i++) { - red[i] = gamma[(num_in - 1) * 3] << 8; - green[i] = gamma[(num_in - 1) * 3 + 1] << 8; - blue[i] = gamma[(num_in - 1) * 3 + 2] << 8; - } - - bool changed = (memcmp(red, last_gamma_red, 512) != 0 || - memcmp(green, last_gamma_green, 512) != 0 || - memcmp(blue, last_gamma_blue, 512) != 0); - - if (changed) { - memcpy(last_gamma_red, red, 512); - memcpy(last_gamma_green, green, 512); - memcpy(last_gamma_blue, blue, 512); - ApplyGammaRamp(); - } - -} - - - -/* - * Switch video mode - */ - -#ifdef SHEEPSHAVER -int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) -{ - /* return if no mode change */ - if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && - (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; - - /* first find video mode in table */ - for (int i=0; VModes[i].viType != DIS_INVALID; i++) { - if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && - (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { - csSave->saveMode = ReadMacInt16(ParamPtr + csMode); - csSave->saveData = ReadMacInt32(ParamPtr + csData); - csSave->savePage = ReadMacInt16(ParamPtr + csPage); - - // Disable interrupts and pause redraw thread - DisableInterrupt(); - thread_stop_ack = false; - thread_stop_req = true; - while (!thread_stop_ack) ; - - cur_mode = i; - monitor_desc *monitor = VideoMonitors[0]; - monitor->switch_to_current_mode(); - - WriteMacInt32(ParamPtr + csBaseAddr, screen_base); - csSave->saveBaseAddr=screen_base; - csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ - csSave->saveMode=VModes[cur_mode].viAppleMode; - - // Enable interrupts and resume redraw thread - thread_stop_req = false; - EnableInterrupt(); - return noErr; - } - } - return paramErr; -} -#endif - -static bool is_cursor_in_mac_screen() { - - int windowX, windowY; - int cursorX, cursorY; - int deltaX, deltaY; - bool out; - - // TODO figure out a check for full screen mode - if (display_type == DISPLAY_SCREEN) - return true; - - if (display_type == DISPLAY_WINDOW) { - - if (sdl_window == NULL || SDL_GetMouseFocus() != sdl_window) - return false; - - SDL_GetWindowPosition(sdl_window, &windowX, &windowY); - SDL_GetGlobalMouseState(&cursorX, &cursorY); - deltaX = cursorX - windowX; - deltaY = cursorY - windowY; - D(bug("cursor relative {%d,%d}\n", deltaX, deltaY)); - const VIDEO_MODE &mode = drv->mode; - const int m = get_mag_rate(); - out = deltaX >= 0 && deltaX < VIDEO_MODE_X * m && - deltaY >= 0 && deltaY < VIDEO_MODE_Y * m; - D(bug("cursor in window? %s\n", out? "yes" : "no")); - return out; - } - - return false; -} - -void SDL_monitor_desc::switch_to_current_mode(void) -{ - // Close and reopen display - LOCK_EVENTS; - video_close(); - video_open(); - UNLOCK_EVENTS; - - if (drv == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Can we set the MacOS cursor image into the window? - */ - -#ifdef SHEEPSHAVER -bool video_can_change_cursor(void) -{ - return PrefsFindBool("hardcursor") && (display_type == DISPLAY_WINDOW || PrefsFindBool("scale_integer")); -} -#endif - - -/* - * Set cursor image for window - */ - -#ifdef SHEEPSHAVER -void video_set_cursor(void) -{ - // Set new cursor image if it was changed - if (sdl_cursor) { - SDL_FreeCursor(sdl_cursor); - sdl_cursor = MagCursor(true); - if (sdl_cursor) { - SDL_ShowCursor(private_data == NULL || private_data->cursorVisible); - SDL_SetCursor(sdl_cursor); - - // XXX Windows apparently needs an extra mouse event to - // make the new cursor image visible. - // On Mac, if mouse is grabbed, SDL_ShowCursor() recenters the - // mouse, we have to put it back. - bool move = false; -#ifdef WIN32 - move = true; -#elif defined(__APPLE__) - move = mouse_grabbed; -#endif - if (move) { - int visible = SDL_ShowCursor(-1); - if (visible) { - bool cursor_in_window = is_cursor_in_mac_screen(); - - if (cursor_in_window) { - int x, y; - SDL_GetMouseState(&x, &y); - D(bug("WarpMouse to {%d,%d} via video_set_cursor\n", x, y)); - SDL_WarpMouseInWindow(sdl_window, x, y); - } - } - } - } - } -} -#endif - - -/* - * Keyboard-related utilify functions - */ - -static bool is_hotkey_down(SDL_Keysym const & ks) -{ - int hotkey = PrefsFindInt32("hotkey"); - if (!hotkey) hotkey = 1; - return (ctrl_down || (ks.mod & KMOD_CTRL) || !(hotkey & 1)) && - (opt_down || (ks.mod & KMOD_ALT) || !(hotkey & 2)) && - (cmd_down || (ks.mod & KMOD_GUI) || !(hotkey & 4)); -} - -static int modify_opt_cmd(int code) { - static bool f, c; - if (!f) { - f = true; - c = PrefsFindBool("swap_opt_cmd"); - } - if (c) { - switch (code) { - case 0x37: return 0x3a; - case 0x3a: return 0x37; - } - } - return code; -} - -/* - * Translate key event to Mac keycode, returns CODE_INVALID if no keycode was found - * and CODE_HOTKEY if the key was recognized as a hotkey - */ - -static int kc_decode(SDL_Keysym const & ks, bool key_down) -{ - switch (ks.sym) { - case SDLK_a: return 0x00; - case SDLK_b: return 0x0b; - case SDLK_c: return 0x08; - case SDLK_d: return 0x02; - case SDLK_e: return 0x0e; - case SDLK_f: return 0x03; - case SDLK_g: return 0x05; - case SDLK_h: return 0x04; - case SDLK_i: return 0x22; - case SDLK_j: return 0x26; - case SDLK_k: return 0x28; - case SDLK_l: return 0x25; - case SDLK_m: return 0x2e; - case SDLK_n: return 0x2d; - case SDLK_o: return 0x1f; - case SDLK_p: return 0x23; - case SDLK_q: return 0x0c; - case SDLK_r: return 0x0f; - case SDLK_s: return 0x01; - case SDLK_t: return 0x11; - case SDLK_u: return 0x20; - case SDLK_v: return 0x09; - case SDLK_w: return 0x0d; - case SDLK_x: return 0x07; - case SDLK_y: return 0x10; - case SDLK_z: return 0x06; - - case SDLK_1: case SDLK_EXCLAIM: return 0x12; - case SDLK_2: case SDLK_AT: return 0x13; - case SDLK_3: case SDLK_HASH: return 0x14; - case SDLK_4: case SDLK_DOLLAR: return 0x15; - case SDLK_5: return 0x17; - case SDLK_6: return 0x16; - case SDLK_7: return 0x1a; - case SDLK_8: return 0x1c; - case SDLK_9: return 0x19; - case SDLK_0: return 0x1d; - - case SDLK_BACKQUOTE: case 167: return 0x32; - case SDLK_MINUS: case SDLK_UNDERSCORE: return 0x1b; - case SDLK_EQUALS: case SDLK_PLUS: return 0x18; - case SDLK_LEFTBRACKET: return 0x21; - case SDLK_RIGHTBRACKET: return 0x1e; - case SDLK_BACKSLASH: return 0x2a; - case SDLK_SEMICOLON: case SDLK_COLON: return 0x29; - case SDLK_QUOTE: case SDLK_QUOTEDBL: return 0x27; - case SDLK_COMMA: case SDLK_LESS: return 0x2b; - case SDLK_PERIOD: case SDLK_GREATER: return 0x2f; - case SDLK_SLASH: case SDLK_QUESTION: return 0x2c; - - case SDLK_TAB: if (is_hotkey_down(ks)) {if (!key_down) drv->suspend(); return CODE_HOTKEY;} else return 0x30; - case SDLK_RETURN: if (is_hotkey_down(ks)) {if (!key_down) toggle_fullscreen = true; return CODE_HOTKEY;} else return 0x24; - case SDLK_SPACE: return 0x31; - case SDLK_BACKSPACE: return 0x33; - - case SDLK_DELETE: return 0x75; - case SDLK_INSERT: return 0x72; - case SDLK_HOME: case SDLK_HELP: return 0x73; - case SDLK_END: return 0x77; - case SDLK_PAGEUP: return 0x74; - case SDLK_PAGEDOWN: return 0x79; - - case SDLK_LCTRL: return 0x36; - case SDLK_RCTRL: return 0x36; - case SDLK_LSHIFT: return 0x38; - case SDLK_RSHIFT: return 0x38; - case SDLK_LALT: case SDLK_RALT: return 0x3a; - case SDLK_LGUI: case SDLK_RGUI: return 0x37; - case SDLK_MENU: return 0x32; - case SDLK_CAPSLOCK: return 0x39; - case SDLK_NUMLOCKCLEAR: return 0x47; - - case SDLK_UP: return 0x3e; - case SDLK_DOWN: return 0x3d; - case SDLK_LEFT: return 0x3b; - case SDLK_RIGHT: return 0x3c; - - case SDLK_ESCAPE: if (is_hotkey_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return CODE_HOTKEY;} else return 0x35; - - case SDLK_F1: if (is_hotkey_down(ks)) {if (!key_down) SysMountFirstFloppy(); return CODE_HOTKEY;} else return 0x7a; - case SDLK_F2: return 0x78; - case SDLK_F3: return 0x63; - case SDLK_F4: return 0x76; - case SDLK_F5: return 0x60; - case SDLK_F6: return 0x61; - case SDLK_F7: return 0x62; - case SDLK_F8: return 0x64; - case SDLK_F9: return 0x65; - case SDLK_F10: return 0x6d; - case SDLK_F11: return 0x67; - case SDLK_F12: return 0x6f; - - case SDLK_PRINTSCREEN: return 0x69; - case SDLK_SCROLLLOCK: return 0x6b; - case SDLK_PAUSE: return 0x71; - - case SDLK_KP_0: return 0x52; - case SDLK_KP_1: return 0x53; - case SDLK_KP_2: return 0x54; - case SDLK_KP_3: return 0x55; - case SDLK_KP_4: return 0x56; - case SDLK_KP_5: return 0x57; - case SDLK_KP_6: return 0x58; - case SDLK_KP_7: return 0x59; - case SDLK_KP_8: return 0x5b; - case SDLK_KP_9: return 0x5c; - case SDLK_KP_PERIOD: return 0x41; - case SDLK_KP_PLUS: return 0x45; - case SDLK_KP_MINUS: return 0x4e; - case SDLK_KP_MULTIPLY: return 0x43; - case SDLK_KP_DIVIDE: return 0x4b; - case SDLK_KP_ENTER: return 0x4c; - case SDLK_KP_EQUALS: return 0x51; - } - D(bug("Unhandled SDL keysym: %d\n", ks.sym)); - return CODE_INVALID; -} - -static int event2keycode(SDL_KeyboardEvent const &ev, bool key_down) -{ - return kc_decode(ev.keysym, key_down); -} - -static void force_complete_window_refresh() -{ - if (display_type == DISPLAY_WINDOW) { -#ifdef ENABLE_VOSF - if (use_vosf) { // VOSF refresh - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - } -#endif - // Ensure each byte of the_buffer_copy differs from the_buffer to force a full update. - const VIDEO_MODE &mode = VideoMonitors[0]->get_current_mode(); - const int len = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - for (int i = 0; i < len; i++) - the_buffer_copy[i] = !the_buffer[i]; - } -} - -/* - * SDL event handling - */ - -// possible return codes for SDL-registered event watches -enum { - EVENT_DROP_FROM_QUEUE = 0, - EVENT_ADD_TO_QUEUE = 1 -}; - -// Some events need to be processed in the host-app's main thread, due to -// host-OS requirements. -// -// This function is called by SDL, whenever it generates an SDL_Event. It has -// the ability to process events, and optionally, to prevent them from being -// added to SDL's event queue (and retrieve-able via SDL_PeepEvents(), etc.) -static int SDLCALL on_sdl_event_generated(void *userdata, SDL_Event * event) -{ - switch (event->type) { - case SDL_KEYUP: { - SDL_Keysym const & ks = event->key.keysym; - switch (ks.sym) { - case SDLK_F5: { - if (is_hotkey_down(ks) && !PrefsFindBool("hardcursor")) { - drv->toggle_mouse_grab(); - return EVENT_DROP_FROM_QUEUE; - } - } break; - } - } break; - - case SDL_WINDOWEVENT: { - switch (event->window.event) { - case SDL_WINDOWEVENT_RESIZED: { - if (!redraw_thread_active) break; - // Handle changes of fullscreen. This is done here, in - // on_sdl_event_generated() and not the main SDL_Event-processing - // loop, in order to perform this change on the main thread. - // (Some os'es UI APIs, such as OSX's NSWindow, are not - // thread-safe.) - const bool is_full = is_fullscreen(sdl_window); - const bool adjust_fullscreen = \ - (display_type == DISPLAY_WINDOW && is_full) || - (display_type == DISPLAY_SCREEN && !is_full); - if (adjust_fullscreen) { - do_toggle_fullscreen(); - -#if __MACOSX__ - // HACK-FIX: on OSX hosts, make sure that the OSX menu - // bar does not show up in fullscreen mode, when the - // cursor is near the top of the screen, lest the - // guest OS' menu bar be obscured. - if (is_full) { - extern void set_menu_bar_visible_osx(bool); - set_menu_bar_visible_osx(false); - } -#endif - } - } break; - } - } break; - } - - return EVENT_ADD_TO_QUEUE; -} - - -static void handle_events(void) -{ - SDL_Event events[10]; - const int n_max_events = sizeof(events) / sizeof(events[0]); - int n_events; - - while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) > 0) { - for (int i = 0; i < n_events; i++) { - SDL_Event & event = events[i]; - - switch (event.type) { - - // Mouse button - case SDL_MOUSEBUTTONDOWN: { - unsigned int button = event.button.button; - if (button == SDL_BUTTON_LEFT) - ADBMouseDown(0); - else if (button == SDL_BUTTON_RIGHT) - ADBMouseDown(1); - else if (button == SDL_BUTTON_MIDDLE) - ADBMouseDown(2); - break; - } - case SDL_MOUSEBUTTONUP: { - unsigned int button = event.button.button; - if (button == SDL_BUTTON_LEFT) - ADBMouseUp(0); - else if (button == SDL_BUTTON_RIGHT) - ADBMouseUp(1); - else if (button == SDL_BUTTON_MIDDLE) - ADBMouseUp(2); - break; - } - - // Mouse moved - case SDL_MOUSEMOTION: - if (mouse_grabbed) { - drv->mouse_moved(event.motion.xrel, event.motion.yrel); - } else { - drv->mouse_moved(event.motion.x, event.motion.y); - } - break; - - case SDL_MOUSEWHEEL: - if (!event.wheel.y) break; - if (!mouse_wheel_mode) { - int key = (event.wheel.y < 0) ^ mouse_wheel_reverse ? 0x79 : 0x74; // Page up/down - ADBKeyDown(key); - ADBKeyUp(key); - } - else { - int key = (event.wheel.y < 0) ^ mouse_wheel_reverse ? 0x3d : 0x3e; // Cursor up/down - for (int i = 0; i < mouse_wheel_lines; i++) { - ADBKeyDown(key); - ADBKeyUp(key); - } - } - break; - - // Keyboard - case SDL_KEYDOWN: { - if (event.key.repeat) - break; - int code = CODE_INVALID; - if (use_keycodes && event2keycode(event.key, true) != CODE_HOTKEY) - code = keycode_table[event.key.keysym.scancode & 0xff]; - if (code == CODE_INVALID) - code = event2keycode(event.key, true); - if (code >= 0) { - if (!emul_suspended) { - code = modify_opt_cmd(code); -#ifdef __MACOSX__ - ADBKeyDown(code); -#else - if (code == 0x39) - (SDL_GetModState() & KMOD_CAPS ? ADBKeyDown : ADBKeyUp)(code); - else - ADBKeyDown(code); -#endif - if (code == 0x36) - ctrl_down = true; - if (code == 0x3a) - opt_down = true; - if (code == 0x37) - cmd_down = true; - - } else { - if (code == 0x31) - drv->resume(); // Space wakes us up - } - } - break; - } - case SDL_KEYUP: { - int code = CODE_INVALID; - if (use_keycodes && event2keycode(event.key, false) != CODE_HOTKEY) - code = keycode_table[event.key.keysym.scancode & 0xff]; - if (code == CODE_INVALID) - code = event2keycode(event.key, false); - if (code >= 0) { - code = modify_opt_cmd(code); -#ifdef __MACOSX__ - ADBKeyUp(code); -#else - if (code != 0x39) - ADBKeyUp(code); -#endif - if (code == 0x36) - ctrl_down = false; - if (code == 0x3a) - opt_down = false; - if (code == 0x37) - cmd_down = false; - } - break; - } - - case SDL_WINDOWEVENT: { - switch (event.window.event) { - // Hidden parts exposed, force complete refresh of window - case SDL_WINDOWEVENT_EXPOSED: - force_complete_window_refresh(); - break; - - // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. - case SDL_WINDOWEVENT_RESTORED: - force_complete_window_refresh(); - break; - - } - break; - } - - // Window "close" widget clicked - case SDL_QUIT: - if (SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) break; - ADBKeyDown(0x7f); // Power key - ADBKeyUp(0x7f); - break; - } - } - } -} - - -/* - * Window display update - */ - -// Static display update (fixed frame rate, but incremental) -static void update_display_static(driver_base *drv) -{ - // Incremental update code - int wide = 0, high = 0; - uint32 x1, x2, y1, y2; - const VIDEO_MODE &mode = drv->mode; - int bytes_per_row = VIDEO_MODE_ROW_BYTES; - uint8 *p, *p2; - uint32 x2_clipped, wide_clipped; - - // Check for first line from top and first line from bottom that have changed - y1 = 0; - for (uint32 j = 0; j < VIDEO_MODE_Y; j++) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y1 = j; - break; - } - } - y2 = y1 - 1; - for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y2 = j; - break; - } - } - high = y2 - y1 + 1; - - // Check for first column from left and first column from right that have changed - if (high) { - if ((int)VIDEO_MODE_DEPTH < (int)VIDEO_DEPTH_8BIT) { - const int src_bytes_per_row = bytes_per_row; - const int dst_bytes_per_row = drv->s->pitch; - const int pixels_per_byte = 8/mac_depth_of_video_depth(VIDEO_MODE_DEPTH); - - const uint32 line_len = TrivialBytesPerRow(VIDEO_MODE_X, VIDEO_MODE_DEPTH); - - x1 = line_len; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (uint32 i = 0; i < x1; i++) { - if (*p != *p2) { - x1 = i; - break; - } - p++; p2++; - } - } - x2 = x1; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (uint32 i = line_len; i > x2; i--) { - p--; p2--; - if (*p != *p2) { - x2 = i; - break; - } - } - } - - x1 *= pixels_per_byte; - x2 *= pixels_per_byte; - wide = x2 - x1; - x2_clipped = x2 > VIDEO_MODE_X? VIDEO_MODE_X : x2; - wide_clipped = x2_clipped - x1; - - // Update copy of the_buffer - if (high && wide) { - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Blit to screen surface - int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte); - int di = y1 * dst_bytes_per_row + x1; - for (uint32 j = y1; j <= y2; j++) { - memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte); - Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte); - si += src_bytes_per_row; - di += dst_bytes_per_row; - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - update_sdl_video(drv->s, x1, y1, wide_clipped, high); - } - - } else { - const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X; - const int dst_bytes_per_row = drv->s->pitch; - - x1 = VIDEO_MODE_X; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) { - if (*p != *p2) { - x1 = i / bytes_per_pixel; - break; - } - p++; p2++; - } - } - x2 = x1; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (uint32 i = VIDEO_MODE_X * bytes_per_pixel; i > x2 * bytes_per_pixel; i--) { - p--; - p2--; - if (*p != *p2) { - x2 = i / bytes_per_pixel; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Blit to screen surface - for (uint32 j = y1; j <= y2; j++) { - uint32 i = j * bytes_per_row + x1 * bytes_per_pixel; - int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel; - memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); - Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide); - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - update_sdl_video(drv->s, x1, y1, wide, high); - } - } - } -} - -// Static display update (fixed frame rate, bounding boxes based) -// XXX use NQD bounding boxes to help detect dirty areas? -static void update_display_static_bbox(driver_base *drv) -{ - const VIDEO_MODE &mode = drv->mode; - - // Allocate bounding boxes for SDL_UpdateRects() - const uint32 N_PIXELS = 64; - const uint32 n_x_boxes = (VIDEO_MODE_X + N_PIXELS - 1) / N_PIXELS; - const uint32 n_y_boxes = (VIDEO_MODE_Y + N_PIXELS - 1) / N_PIXELS; - SDL_Rect *boxes = (SDL_Rect *)alloca(sizeof(SDL_Rect) * n_x_boxes * n_y_boxes); - uint32 nr_boxes = 0; - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Update the surface from Mac screen - const uint32 bytes_per_row = VIDEO_MODE_ROW_BYTES; - const uint32 bytes_per_pixel = bytes_per_row / VIDEO_MODE_X; - const uint32 dst_bytes_per_row = drv->s->pitch; - for (uint32 y = 0; y < VIDEO_MODE_Y; y += N_PIXELS) { - uint32 h = N_PIXELS; - if (h > VIDEO_MODE_Y - y) - h = VIDEO_MODE_Y - y; - for (uint32 x = 0; x < VIDEO_MODE_X; x += N_PIXELS) { - uint32 w = N_PIXELS; - if (w > VIDEO_MODE_X - x) - w = VIDEO_MODE_X - x; - const int xs = w * bytes_per_pixel; - const int xb = x * bytes_per_pixel; - bool dirty = false; - for (uint32 j = y; j < (y + h); j++) { - const uint32 yb = j * bytes_per_row; - const uint32 dst_yb = j * dst_bytes_per_row; - if (memcmp(&the_buffer[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { - memcpy(&the_buffer_copy[yb + xb], &the_buffer[yb + xb], xs); - Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, the_buffer + yb + xb, xs); - dirty = true; - } - } - if (dirty) { - boxes[nr_boxes].x = x; - boxes[nr_boxes].y = y; - boxes[nr_boxes].w = w; - boxes[nr_boxes].h = h; - nr_boxes++; - } - } - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - if (nr_boxes) - update_sdl_video(drv->s, nr_boxes, boxes); -} - - -// We suggest the compiler to inline the next two functions so that it -// may specialise the code according to the current screen depth and -// display type. A clever compiler would do that job by itself though... - -// NOTE: update_display_vosf is inlined too - -static inline void possibly_quit_dga_mode() -{ - // Quit DGA mode if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - delete drv; - drv = NULL; - } -} - -static inline void possibly_ungrab_mouse() -{ - // Ungrab mouse if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - if (drv) - drv->ungrab_mouse(); - } -} - -static inline void handle_palette_changes(void) -{ - LOCK_PALETTE; - - if (sdl_palette_changed) { - sdl_palette_changed = false; - drv->update_palette(); - } - - UNLOCK_PALETTE; -} - -static void video_refresh_window_static(void); - -static void video_refresh_dga(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - video_refresh_window_static(); -} - -#ifdef ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING -static void video_refresh_dga_vosf(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - - // Update display (VOSF variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_dga_vosf(drv); - UNLOCK_VOSF; - } - } -} -#endif - -static void video_refresh_window_vosf(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (VOSF variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_window_vosf(drv); - UNLOCK_VOSF; - } - } -} -#endif // def ENABLE_VOSF - -static void video_refresh_window_static(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (static variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - const VIDEO_MODE &mode = drv->mode; - if ((int)VIDEO_MODE_DEPTH >= VIDEO_DEPTH_8BIT) - update_display_static_bbox(drv); - else - update_display_static(drv); - } -} - - -/* - * Thread for screen refresh, input handling etc. - */ - -static void VideoRefreshInit(void) -{ - // TODO: set up specialised 8bpp VideoRefresh handlers ? - if (display_type == DISPLAY_SCREEN) { -#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) - if (use_vosf) - video_refresh = video_refresh_dga_vosf; - else -#endif - video_refresh = video_refresh_dga; - } - else { -#ifdef ENABLE_VOSF - if (use_vosf) - video_refresh = video_refresh_window_vosf; - else -#endif - video_refresh = video_refresh_window_static; - } -} - -static inline void do_video_refresh(void) -{ - // Handle SDL events - handle_events(); - - // Update display - video_refresh(); - - - // Set new palette if it was changed - handle_palette_changes(); -} - -// This function is called on non-threaded platforms from a timer interrupt -void VideoRefresh(void) -{ - // We need to check redraw_thread_active to inhibit refreshed during - // mode changes on non-threaded platforms - if (!redraw_thread_active) - return; - - // Process pending events and update display - do_video_refresh(); -} - -const int VIDEO_REFRESH_HZ = 60; -const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; - -#ifndef USE_CPU_EMUL_SERVICES -static int redraw_func(void *arg) -{ - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; - - while (!redraw_thread_cancel) { - - // Wait - next += VIDEO_REFRESH_DELAY; - int32 delay = int32(next - GetTicks_usec()); - if (delay > 0) - Delay_usec(delay); - else if (delay < -VIDEO_REFRESH_DELAY) - next = GetTicks_usec(); - ticks++; - - // Pause if requested (during video mode switches) - if (thread_stop_req) { - thread_stop_ack = true; - continue; - } - - // Process pending events and update display - do_video_refresh(); - } - - uint64 end = GetTicks_usec(); - D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); - return 0; -} -#endif - - -/* - * Record dirty area from NQD - */ - -#ifdef SHEEPSHAVER -void video_set_dirty_area(int x, int y, int w, int h) -{ -#ifdef ENABLE_VOSF - const VIDEO_MODE &mode = drv->mode; - const unsigned screen_width = VIDEO_MODE_X; - const unsigned screen_height = VIDEO_MODE_Y; - const unsigned bytes_per_row = VIDEO_MODE_ROW_BYTES; - - if (use_vosf) { - vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); - return; - } -#endif - - // XXX handle dirty bounding boxes for non-VOSF modes -} -#endif - -#endif // ends: SDL version check diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index 0771f5671..f521d5e93 100755 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -163,23 +163,28 @@ const uint32 SIG_STACK_SIZE = 0x10000; // Size of signal stack // Global variables (exported) +int64 CPUClockSpeed; // Processor clock speed (Hz) +int64 BusClockSpeed; // Bus clock speed (Hz) +int64 TimebaseSpeed; // Timebase clock speed (Hz) #if !EMULATED_PPC void *TOC = NULL; // Pointer to Thread Local Storage (r2) void *R13 = NULL; // Pointer to .sdata section (r13 under Linux) #endif + +// RAM and ROM +uint8 *RAMBaseHost; // Base address of Mac RAM (host address space) +uint8 *ROMBaseHost; // Base address of Mac ROM (host address space) +uint8 *MacFrameBaseHost=NULL; // Mac VRAM uint32 RAMBase; // Base address of Mac RAM uint32 RAMSize; // Size of Mac RAM uint32 ROMBase; // Base address of Mac ROM +uint32 ROMEnd; +uint32 VRAMSize; + uint32 KernelDataAddr; // Address of Kernel Data uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM uint32 DRCacheAddr; // Address of DR Cache uint32 PVR; // Theoretical PVR -int64 CPUClockSpeed; // Processor clock speed (Hz) -int64 BusClockSpeed; // Bus clock speed (Hz) -int64 TimebaseSpeed; // Timebase clock speed (Hz) -uint8 *RAMBaseHost; // Base address of Mac RAM (host address space) -uint8 *ROMBaseHost; // Base address of Mac ROM (host address space) -uint32 ROMEnd; #if defined(__APPLE__) && defined(__x86_64__) uint8 gZeroPage[0x3000], gKernelData[0x2000]; @@ -319,27 +324,22 @@ int atomic_or(int *var, int v) } #endif - /* * Memory management helpers */ -static inline uint8 *vm_mac_acquire(uint32 size) -{ - return (uint8 *)vm_acquire(size); +static inline uint8 *vm_mac_acquire(uint32 size){ + return (uint8 *)vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); } -static inline int vm_mac_acquire_fixed(uint32 addr, uint32 size) -{ +static inline int vm_mac_acquire_fixed(uint32 addr, uint32 size){ return vm_acquire_fixed(Mac2HostAddr(addr), size); } -static inline int vm_mac_release(uint32 addr, uint32 size) -{ +static inline int vm_mac_release(uint32 addr, uint32 size){ return vm_release(Mac2HostAddr(addr), size); } - /* * Main program */ @@ -992,6 +992,16 @@ int main(int argc, char **argv){ goto quit; } + // allocate Mac framebuffer + VRAMSize = 16*1024*1024; // 16mb, more than enough for 1920x1440x32 + MacFrameBaseHost = vm_mac_acquire(VRAMSize); + if (MacFrameBaseHost == VM_MAP_FAILED) { + MacFrameBaseHost = NULL; + sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno)); + ErrorAlert(str); + goto quit; + } + // Create area for SheepShaver data if (!SheepMem::Init()) { sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno)); @@ -1137,6 +1147,10 @@ static void Quit(void) if (lm_area_mapped) vm_mac_release(0, 0x3000); + if(MacFrameBaseHost){ + vm_mac_release(Host2MacAddr(MacFrameBaseHost),VRAMSize); + } + // Close /dev/zero if (zero_fd > 0) close(zero_fd); diff --git a/SheepShaver/src/Windows/main_windows.cpp b/SheepShaver/src/Windows/main_windows.cpp index 0683c4711..febc22184 100755 --- a/SheepShaver/src/Windows/main_windows.cpp +++ b/SheepShaver/src/Windows/main_windows.cpp @@ -64,22 +64,26 @@ const uint32 SIG_STACK_SIZE = 0x10000; // Size of signal stack // Global variables (exported) -uint32 RAMBase; // Base address of Mac RAM +int64 CPUClockSpeed; // Processor clock speed (Hz) +int64 BusClockSpeed; // Bus clock speed (Hz) +int64 TimebaseSpeed; // Timebase clock speed (Hz) + +// RAM and ROM +uint8 *RAMBaseHost; // Base address of Mac RAM (host address space) +uint8 *ROMBaseHost; // Base address of Mac ROM (host address space) +uint8 *MacFrameBaseHost=NULL; // Mac VRAM +uint32 RAMBase=0; // Base address of Mac RAM uint32 RAMSize; // Size of Mac RAM uint32 ROMBase; // Base address of Mac ROM +uint32 VRAMSize; + uint32 KernelDataAddr; // Address of Kernel Data uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM uint32 DRCacheAddr; // Address of DR Cache uint32 PVR; // Theoretical PVR -int64 CPUClockSpeed; // Processor clock speed (Hz) -int64 BusClockSpeed; // Bus clock speed (Hz) -int64 TimebaseSpeed; // Timebase clock speed (Hz) -uint8 *RAMBaseHost; // Base address of Mac RAM (host address space) -uint8 *ROMBaseHost; // Base address of Mac ROM (host address space) DWORD win_os; // Windows OS id DWORD win_os_major; // Windows OS version major - // Global variables static int kernel_area = -1; // SHM ID of Kernel Data area static bool rom_area_mapped = false; // Flag: Mac ROM mmap()ped @@ -119,38 +123,31 @@ extern void init_emul_ppc(void); extern void exit_emul_ppc(void); sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip); - /* * Return signal stack base */ -uintptr SignalStackBase(void) -{ +uintptr SignalStackBase(void){ return sig_stack + SIG_STACK_SIZE; } - /* * Memory management helpers */ -static inline int vm_mac_acquire(uint32 addr, uint32 size) -{ +static inline int vm_mac_acquire(uint32 addr, uint32 size){ return vm_acquire_fixed(Mac2HostAddr(addr), size); } -static inline int vm_mac_release(uint32 addr, uint32 size) -{ +static inline int vm_mac_release(uint32 addr, uint32 size){ return vm_release(Mac2HostAddr(addr), size); } - /* * Main program */ -static void usage(const char *prg_name) -{ +static void usage(const char *prg_name){ printf("Usage: %s [OPTION...]\n", prg_name); printf("\nUnix options:\n"); printf(" --display STRING\n X display to use\n"); @@ -158,8 +155,7 @@ static void usage(const char *prg_name) exit(0); } -int main(int argc, char **argv) -{ +int main(int argc, char **argv){ char str[256]; int16 i16; HANDLE rom_fh; @@ -168,9 +164,6 @@ int main(int argc, char **argv) DWORD actual; uint8 *rom_tmp; - // Initialize variables - RAMBase = 0; - // Print some info printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); printf(" %s\n", GetString(STR_ABOUT_TEXT2)); @@ -294,14 +287,16 @@ int main(int argc, char **argv) goto quit; } - // Create area for Mac ROM - if (vm_mac_acquire(ROM_BASE, ROM_AREA_SIZE) < 0) { + // Create area for Mac ROM + VRAM + VRAMSize = 16*1024*1024; // 16mb, more than enough for 1920x1440x32 + if (vm_mac_acquire(ROM_BASE, ROM_AREA_SIZE + VRAMSize) < 0) { sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } ROMBase = ROM_BASE; ROMBaseHost = Mac2HostAddr(ROMBase); + MacFrameBaseHost = Mac2HostAddr(ROMBase + ROM_AREA_SIZE); rom_area_mapped = true; D(bug("ROM area at %p (%08x)\n", ROMBaseHost, ROMBase)); @@ -314,7 +309,6 @@ int main(int argc, char **argv) WarningAlert(GetString(STR_SMALL_RAM_WARN)); RAMSize = 16 * 1024 * 1024; } - RAMBase = 0; if (vm_mac_acquire(RAMBase, RAMSize) < 0) { sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno)); ErrorAlert(str); @@ -362,7 +356,7 @@ int main(int argc, char **argv) } } delete[] rom_tmp; - + // Initialize native timers timer_init(); @@ -398,13 +392,11 @@ int main(int argc, char **argv) return 0; } - /* * Cleanup and quit */ -static void Quit(void) -{ +static void Quit(void){ // Exit PowerPC emulation exit_emul_ppc(); diff --git a/SheepShaver/src/include/cpu_emulation.h b/SheepShaver/src/include/cpu_emulation.h index aa4b7a701..d80f67aab 100644 --- a/SheepShaver/src/include/cpu_emulation.h +++ b/SheepShaver/src/include/cpu_emulation.h @@ -57,6 +57,8 @@ extern uint8 *RAMBaseHost; // Base address of Mac RAM (host address space) extern uint32 ROMBase; // Base address of Mac ROM extern uint8 *ROMBaseHost; // Base address of Mac ROM (host address space) +extern uint32 VRAMSize; // Size of VRAM + // Mac memory access functions #if EMULATED_PPC #include "cpu/vm.hpp" From 958f283daa2c2ab4ef731ec408637c65a02f8f94 Mon Sep 17 00:00:00 2001 From: Seg Date: Thu, 17 Jun 2021 16:29:49 -0700 Subject: [PATCH 16/24] Remove (broken) SDL1 --- .../BasiliskII.xcodeproj/project.pbxproj | 4 - BasiliskII/src/SDL/video_sdl.cpp | 2341 ----------------- BasiliskII/src/Unix/configure.ac | 61 +- BasiliskII/src/Windows/BasiliskII.vcxproj | 3 +- BasiliskII/src/Windows/Makefile.in | 2 +- SheepShaver/src/Unix/configure.ac | 71 +- SheepShaver/src/Windows/Makefile.in | 2 +- 7 files changed, 27 insertions(+), 2457 deletions(-) delete mode 100644 BasiliskII/src/SDL/video_sdl.cpp diff --git a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj index 6c450db11..a52057595 100644 --- a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj +++ b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj @@ -55,7 +55,6 @@ 756C1B391F25306A00620917 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 756C1B381F25306A00620917 /* AppKit.framework */; }; 757A2BF01F5AF9D6003EDB01 /* user_strings_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 757A2BEF1F5AF9D6003EDB01 /* user_strings_unix.cpp */; }; 75CBCF751F5DB3AD00830063 /* video_sdl2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 75CBCF741F5DB3AD00830063 /* video_sdl2.cpp */; }; - 75CBCF771F5DB65E00830063 /* video_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 75CBCF761F5DB65E00830063 /* video_sdl.cpp */; }; E40CEEC620D7910E00BCB88D /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = E40CEEC520D7910E00BCB88D /* SDLMain.m */; }; E413D92120D260BC00E437D8 /* tftp.c in Sources */ = {isa = PBXBuildFile; fileRef = E413D8F820D260B900E437D8 /* tftp.c */; }; E413D92220D260BC00E437D8 /* mbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = E413D8F920D260B900E437D8 /* mbuf.c */; }; @@ -262,7 +261,6 @@ 756C1B381F25306A00620917 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 757A2BEF1F5AF9D6003EDB01 /* user_strings_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = user_strings_unix.cpp; sourceTree = ""; }; 75CBCF741F5DB3AD00830063 /* video_sdl2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_sdl2.cpp; sourceTree = ""; }; - 75CBCF761F5DB65E00830063 /* video_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_sdl.cpp; sourceTree = ""; }; E40CEEC420D7910D00BCB88D /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = ""; }; E40CEEC520D7910E00BCB88D /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = ""; }; E413D8F820D260B900E437D8 /* tftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tftp.c; sourceTree = ""; }; @@ -523,7 +521,6 @@ 752F27001F242BAF001032B4 /* prefs_sdl.cpp */, E40CEEC420D7910D00BCB88D /* SDLMain.h */, E40CEEC520D7910E00BCB88D /* SDLMain.m */, - 75CBCF761F5DB65E00830063 /* video_sdl.cpp */, 75CBCF741F5DB3AD00830063 /* video_sdl2.cpp */, 752F27021F242F51001032B4 /* xpram_sdl.cpp */, ); @@ -799,7 +796,6 @@ 7539E1721F23B25A006B2DF2 /* rsrc_patches.cpp in Sources */, 5D5C3B0A24B2DF3500CDAB41 /* bincue.cpp in Sources */, 7539E2931F23C56F006B2DF2 /* serial_dummy.cpp in Sources */, - 75CBCF771F5DB65E00830063 /* video_sdl.cpp in Sources */, 7539E2801F23C4CA006B2DF2 /* main_unix.cpp in Sources */, 7539E1E11F23B25A006B2DF2 /* user_strings.cpp in Sources */, 75CBCF751F5DB3AD00830063 /* video_sdl2.cpp in Sources */, diff --git a/BasiliskII/src/SDL/video_sdl.cpp b/BasiliskII/src/SDL/video_sdl.cpp deleted file mode 100644 index 3161c6dc1..000000000 --- a/BasiliskII/src/SDL/video_sdl.cpp +++ /dev/null @@ -1,2341 +0,0 @@ -/* - * video_sdl.cpp - Video/graphics emulation, SDL 1.x specific stuff - * - * Basilisk II (C) 1997-2008 Christian Bauer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * NOTES: - * The Ctrl key works like a qualifier for special actions: - * Ctrl-Tab = suspend DGA mode (TODO) - * Ctrl-Esc = emergency quit - * Ctrl-F1 = mount floppy - * Ctrl-F5 = grab mouse (in windowed mode) - * - * FIXMEs and TODOs: - * - Windows requires an extra mouse event to update the actual cursor image? - * - Ctr-Tab for suspend/resume but how? SDL does not support that for non-Linux - * - Ctrl-Fn doesn't generate SDL_KEYDOWN events (SDL bug?) - * - Mouse acceleration, there is no API in SDL yet for that - * - Force relative mode in Grab mode even if SDL provides absolute coordinates? - * - Gamma tables support is likely to be broken here - * - Events processing is bound to the general emulation thread as SDL requires - * to PumpEvents() within the same thread as the one that called SetVideoMode(). - * Besides, there can't seem to be a way to call SetVideoMode() from a child thread. - * - Backport hw cursor acceleration to Basilisk II? - * - Factor out code - */ - -#include "sysdeps.h" - -#include -#if (SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)) - -#include -#include -#include -#include - -#ifdef WIN32 -#include /* alloca() */ -#endif - -#include "cpu_emulation.h" -#include "main.h" -#include "adb.h" -#include "macos_util.h" -#include "prefs.h" -#include "user_strings.h" -#include "video.h" -#include "video_defs.h" -#include "video_blit.h" -#include "vm_alloc.h" - -#define DEBUG 0 -#include "debug.h" - -// Supported video modes -using std::vector; -static vector VideoModes; - -// Display types -#ifdef SHEEPSHAVER -enum { - DISPLAY_WINDOW = DIS_WINDOW, // windowed display - DISPLAY_SCREEN = DIS_SCREEN // fullscreen display -}; -extern int display_type; // See enum above -#else -enum { - DISPLAY_WINDOW, // windowed display - DISPLAY_SCREEN // fullscreen display -}; -static int display_type = DISPLAY_WINDOW; // See enum above -#endif - -// Constants -#if defined(WIN32) || __MACOSX__ -const char KEYCODE_FILE_NAME[] = "BasiliskII_keycodes"; -#else -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; -#endif - - -// Global variables -static uint32 frame_skip; // Prefs items -static int16 mouse_wheel_mode; -static int16 mouse_wheel_lines; - -#error merge changes from SDL2 -static uint8 *the_buffer = NULL; // Mac frame buffer (where MacOS draws into) -static uint8 *the_buffer_copy = NULL; // Copy of Mac frame buffer (for refreshed modes) -static uint32 the_buffer_size; // Size of allocated the_buffer - -static bool redraw_thread_active = false; // Flag: Redraw thread installed -#ifndef USE_CPU_EMUL_SERVICES -static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread -static SDL_Thread *redraw_thread = NULL; // Redraw thread -static volatile bool thread_stop_req = false; -static volatile bool thread_stop_ack = false; // Acknowledge for thread_stop_req -#endif - -#ifdef ENABLE_VOSF -static bool use_vosf = false; // Flag: VOSF enabled -#else -static const bool use_vosf = false; // VOSF not possible -#endif - -static bool ctrl_down = false; // Flag: Ctrl key pressed -static bool caps_on = false; // Flag: Caps Lock on -static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread -static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread -static bool emul_suspended = false; // Flag: Emulator suspended - -static bool classic_mode = false; // Flag: Classic Mac video mode - -static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms -static int keycode_table[256]; // X keycode -> Mac keycode translation table - -// SDL variables -static int screen_depth; // Depth of current screen -static SDL_Cursor *sdl_cursor; // Copy of Mac cursor -static SDL_Color sdl_palette[256]; // Color palette to be used as CLUT and gamma table -static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors -static bool toggle_fullscreen = false; -static const int sdl_eventmask = SDL_MOUSEEVENTMASK | SDL_KEYEVENTMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK | SDL_ACTIVEEVENTMASK; - -static bool mouse_grabbed = false; -static bool mouse_grabbed_window_name_status = false; - -// Mutex to protect SDL events -static SDL_mutex *sdl_events_lock = NULL; -#define LOCK_EVENTS SDL_LockMutex(sdl_events_lock) -#define UNLOCK_EVENTS SDL_UnlockMutex(sdl_events_lock) - -// Mutex to protect palette -static SDL_mutex *sdl_palette_lock = NULL; -#define LOCK_PALETTE SDL_LockMutex(sdl_palette_lock) -#define UNLOCK_PALETTE SDL_UnlockMutex(sdl_palette_lock) - -// Mutex to protect frame buffer -static SDL_mutex *frame_buffer_lock = NULL; -#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock) -#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock) - -// Previously set gamma tables -static uint16 last_gamma_red[256]; -static uint16 last_gamma_green[256]; -static uint16 last_gamma_blue[256]; - -// Video refresh function -static void VideoRefreshInit(void); -static void (*video_refresh)(void); - - -// Prototypes -static int redraw_func(void *arg); - -// From sys_unix.cpp -extern void SysMountFirstFloppy(void); - - -/* - * SDL surface locking glue - */ - -#ifdef ENABLE_VOSF -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ - if ((SURFACE)->flags & (SDL_HWSURFACE | SDL_FULLSCREEN)) \ - the_host_buffer = (uint8 *)(SURFACE)->pixels; \ -} while (0) -#else -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) -#endif - -#define SDL_VIDEO_LOCK_SURFACE(SURFACE) do { \ - if (SDL_MUSTLOCK(SURFACE)) { \ - SDL_LockSurface(SURFACE); \ - SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE); \ - } \ -} while (0) - -#define SDL_VIDEO_UNLOCK_SURFACE(SURFACE) do { \ - if (SDL_MUSTLOCK(SURFACE)) \ - SDL_UnlockSurface(SURFACE); \ -} while (0) - - -/* - * Framebuffer allocation routines - */ - -static void *vm_acquire_framebuffer(uint32 size) -{ - // always try to reallocate framebuffer at the same address - static void *fb = VM_MAP_FAILED; - if (fb != VM_MAP_FAILED) { - if (vm_acquire_fixed(fb, size) < 0) { -#ifndef SHEEPSHAVER - printf("FATAL: Could not reallocate framebuffer at previous address\n"); -#endif - fb = VM_MAP_FAILED; - } - } - if (fb == VM_MAP_FAILED) - fb = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return fb; -} - -static inline void vm_release_framebuffer(void *fb, uint32 size) -{ - vm_release(fb, size); -} - -static inline int get_customized_color_depth(int default_depth) -{ - int display_color_depth = PrefsFindInt32("displaycolordepth"); - - D(bug("Get displaycolordepth %d\n", display_color_depth)); - - if(0 == display_color_depth) - return default_depth; - else{ - switch (display_color_depth) { - case 8: - return VIDEO_DEPTH_8BIT; - case 15: case 16: - return VIDEO_DEPTH_16BIT; - case 24: case 32: - return VIDEO_DEPTH_32BIT; - default: - return default_depth; - } - } -} - -/* - * Windows message handler - */ - -#ifdef WIN32 -#include -static WNDPROC sdl_window_proc = NULL; // Window proc used by SDL - -extern void SysMediaArrived(void); -extern void SysMediaRemoved(void); -extern HWND GetMainWindowHandle(void); - -static LRESULT CALLBACK windows_message_handler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_DEVICECHANGE: - if (wParam == DBT_DEVICEREMOVECOMPLETE) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaRemoved(); - } - else if (wParam == DBT_DEVICEARRIVAL) { - DEV_BROADCAST_HDR *p = (DEV_BROADCAST_HDR *)lParam; - if (p->dbch_devicetype == DBT_DEVTYP_VOLUME) - SysMediaArrived(); - } - return 0; - - default: - if (sdl_window_proc) - return CallWindowProc(sdl_window_proc, hwnd, msg, wParam, lParam); - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} -#endif - - -/* - * SheepShaver glue - */ - -#ifdef SHEEPSHAVER -// Color depth modes type -typedef int video_depth; - -// 1, 2, 4 and 8 bit depths use a color palette -static inline bool IsDirectMode(VIDEO_MODE const & mode) -{ - return IsDirectMode(mode.viAppleMode); -} - -// Abstract base class representing one (possibly virtual) monitor -// ("monitor" = rectangular display with a contiguous frame buffer) -class monitor_desc { -public: - monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) {} - virtual ~monitor_desc() {} - - // Get current Mac frame buffer base address - uint32 get_mac_frame_base(void) const {return screen_base;} - - // Set Mac frame buffer base address (called from switch_to_mode()) - void set_mac_frame_base(uint32 base) {screen_base = base;} - - // Get current video mode - const VIDEO_MODE &get_current_mode(void) const {return VModes[cur_mode];} - - // Called by the video driver to switch the video mode on this display - // (must call set_mac_frame_base()) - virtual void switch_to_current_mode(void) = 0; - - // Called by the video driver to set the color palette (in indexed modes) - // or the gamma table (in direct modes) - virtual void set_palette(uint8 *pal, int num) = 0; -}; - -// Vector of pointers to available monitor descriptions, filled by VideoInit() -static vector VideoMonitors; - -// Find Apple mode matching best specified dimensions -static int find_apple_resolution(int xsize, int ysize) -{ - if (xsize == 640 && ysize == 480) - return APPLE_640x480; - if (xsize == 800 && ysize == 600) - return APPLE_800x600; - if (xsize == 1024 && ysize == 768) - return APPLE_1024x768; - if (xsize == 1152 && ysize == 768) - return APPLE_1152x768; - if (xsize == 1152 && ysize == 900) - return APPLE_1152x900; - if (xsize == 1280 && ysize == 1024) - return APPLE_1280x1024; - if (xsize == 1600 && ysize == 1200) - return APPLE_1600x1200; - return APPLE_CUSTOM; -} - -// Display error alert -static void ErrorAlert(int error) -{ - ErrorAlert(GetString(error)); -} -#endif - - -/* - * monitor_desc subclass for SDL display - */ - -class SDL_monitor_desc : public monitor_desc { -public: - SDL_monitor_desc(const vector &available_modes, video_depth default_depth, uint32 default_id) : monitor_desc(available_modes, default_depth, default_id) {} - ~SDL_monitor_desc() {} - - virtual void switch_to_current_mode(void); - virtual void set_palette(uint8 *pal, int num); - - bool video_open(void); - void video_close(void); -}; - - -/* - * Utility functions - */ - -// Find palette size for given color depth -static int palette_size(int mode) -{ - switch (mode) { - case VIDEO_DEPTH_1BIT: return 2; - case VIDEO_DEPTH_2BIT: return 4; - case VIDEO_DEPTH_4BIT: return 16; - case VIDEO_DEPTH_8BIT: return 256; - case VIDEO_DEPTH_16BIT: return 32; - case VIDEO_DEPTH_32BIT: return 256; - default: return 0; - } -} - -// Map video_mode depth ID to numerical depth value -static int mac_depth_of_video_depth(int video_depth) -{ - int depth = -1; - switch (video_depth) { - case VIDEO_DEPTH_1BIT: - depth = 1; - break; - case VIDEO_DEPTH_2BIT: - depth = 2; - break; - case VIDEO_DEPTH_4BIT: - depth = 4; - break; - case VIDEO_DEPTH_8BIT: - depth = 8; - break; - case VIDEO_DEPTH_16BIT: - depth = 16; - break; - case VIDEO_DEPTH_32BIT: - depth = 32; - break; - default: - abort(); - } - return depth; -} - -// Map video_mode depth ID to SDL screen depth -static int sdl_depth_of_video_depth(int video_depth) -{ - return (video_depth <= VIDEO_DEPTH_8BIT) ? 8 : mac_depth_of_video_depth(video_depth); -} - -// Get screen dimensions -static void sdl_display_dimensions(int &width, int &height) -{ - static int max_width, max_height; - if (max_width == 0 && max_height == 0) { - max_width = 640 ; max_height = 480; - SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); - if (modes && modes != (SDL_Rect **)-1) { - // It turns out that on some implementations, and contrary to the documentation, - // the returned list is not sorted from largest to smallest (e.g. Windows) - for (int i = 0; modes[i] != NULL; i++) { - const int w = modes[i]->w; - const int h = modes[i]->h; - if (w > max_width && h > max_height) { - max_width = w; - max_height = h; - } - } - } - } - width = max_width; - height = max_height; -} - -static inline int sdl_display_width(void) -{ - int width, height; - sdl_display_dimensions(width, height); - return width; -} - -static inline int sdl_display_height(void) -{ - int width, height; - sdl_display_dimensions(width, height); - return height; -} - -// Check whether specified mode is available -static bool has_mode(int type, int width, int height, int depth) -{ - // Filter out out-of-bounds resolutions - if (width > sdl_display_width() || height > sdl_display_height()) - return false; - - // Rely on SDL capabilities - return SDL_VideoModeOK(width, height, - sdl_depth_of_video_depth(depth), - SDL_HWSURFACE | (type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0)) != 0; -} - -// Add mode to list of supported modes -static void add_mode(int type, int width, int height, int resolution_id, int bytes_per_row, int depth) -{ - // Filter out unsupported modes - if (!has_mode(type, width, height, depth)) - return; - - // Fill in VideoMode entry - VIDEO_MODE mode; -#ifdef SHEEPSHAVER - resolution_id = find_apple_resolution(width, height); - mode.viType = type; -#endif - VIDEO_MODE_X = width; - VIDEO_MODE_Y = height; - VIDEO_MODE_RESOLUTION = resolution_id; - VIDEO_MODE_ROW_BYTES = bytes_per_row; - VIDEO_MODE_DEPTH = (video_depth)depth; - VideoModes.push_back(mode); -} - -// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac) -static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - int layout = FLAYOUT_DIRECT; - if (depth == VIDEO_DEPTH_16BIT) - layout = (screen_depth == 15) ? FLAYOUT_HOST_555 : FLAYOUT_HOST_565; - else if (depth == VIDEO_DEPTH_32BIT) - layout = (screen_depth == 24) ? FLAYOUT_HOST_888 : FLAYOUT_DIRECT; - MacFrameLayout = layout; - monitor.set_mac_frame_base(MacFrameBaseMac); - - // Set variables used by UAE memory banking - const VIDEO_MODE &mode = monitor.get_current_mode(); - MacFrameBaseHost = the_buffer; - MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - InitFrameBufferMapping(); -#else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); -#endif - D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); -} - -// Set window name and class -static void set_window_name(int name) -{ - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - if (vi && vi->wm_available) { - const char *str = GetString(name); - SDL_WM_SetCaption(str, str); - } -} - -// Set mouse grab mode -static SDL_GrabMode set_grab_mode(SDL_GrabMode mode) -{ - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - return (vi && vi->wm_available ? SDL_WM_GrabInput(mode) : SDL_GRAB_OFF); -} - -// Migrate preferences items (XXX to be handled in MigratePrefs()) -static void migrate_screen_prefs(void) -{ -#ifdef SHEEPSHAVER - // Look-up priorities are: "screen", "screenmodes", "windowmodes". - if (PrefsFindString("screen")) - return; - - uint32 window_modes = PrefsFindInt32("windowmodes"); - uint32 screen_modes = PrefsFindInt32("screenmodes"); - int width = 0, height = 0; - if (screen_modes) { - static const struct { - int id; - int width; - int height; - } - modes[] = { - { 1, 640, 480 }, - { 2, 800, 600 }, - { 4, 1024, 768 }, - { 64, 1152, 768 }, - { 8, 1152, 900 }, - { 16, 1280, 1024 }, - { 32, 1600, 1200 }, - { 0, } - }; - for (int i = 0; modes[i].id != 0; i++) { - if (screen_modes & modes[i].id) { - if (width < modes[i].width && height < modes[i].height) { - width = modes[i].width; - height = modes[i].height; - } - } - } - } else { - if (window_modes & 1) - width = 640, height = 480; - if (window_modes & 2) - width = 800, height = 600; - } - if (width && height) { - char str[32]; - sprintf(str, "%s/%d/%d", screen_modes ? "dga" : "win", width, height); - PrefsReplaceString("screen", str); - } -#endif -} - -void update_sdl_video(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h) -{ - SDL_UpdateRect(screen, x, y, w, h); -} - -void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects) -{ - SDL_UpdateRects(screen, numrects, rects); -} - - -/* - * Display "driver" classes - */ - -class driver_base { -public: - driver_base(SDL_monitor_desc &m); - ~driver_base(); - - void init(); // One-time init - void set_video_mode(int flags); - void adapt_to_video_mode(); - - void update_palette(void); - void suspend(void) {} - void resume(void) {} - void toggle_mouse_grab(void); - void mouse_moved(int x, int y) { ADBMouseMoved(x, y); } - - void disable_mouse_accel(void); - void restore_mouse_accel(void); - - void grab_mouse(void); - void ungrab_mouse(void); - -public: - SDL_monitor_desc &monitor; // Associated video monitor - const VIDEO_MODE &mode; // Video mode handled by the driver - - bool init_ok; // Initialization succeeded (we can't use exceptions because of -fomit-frame-pointer) - SDL_Surface *s; // The surface we draw into -}; - -#ifdef ENABLE_VOSF -static void update_display_window_vosf(driver_base *drv); -#endif -static void update_display_static(driver_base *drv); - -static driver_base *drv = NULL; // Pointer to currently used driver object - -#ifdef ENABLE_VOSF -# include "video_vosf.h" -#endif - -driver_base::driver_base(SDL_monitor_desc &m) - : monitor(m), mode(m.get_current_mode()), init_ok(false), s(NULL) -{ - the_buffer = NULL; - the_buffer_copy = NULL; -} - -void driver_base::set_video_mode(int flags) -{ - int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - if ((s = SDL_SetVideoMode(VIDEO_MODE_X, VIDEO_MODE_Y, depth, - SDL_HWSURFACE | flags)) == NULL) - return; -#ifdef ENABLE_VOSF - the_host_buffer = (uint8 *)s->pixels; -#endif -} - -void driver_base::init() -{ - set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); - int aligned_height = (VIDEO_MODE_Y + 15) & ~15; - -#ifdef ENABLE_VOSF - use_vosf = true; - // Allocate memory for frame buffer (SIZE is extended to page-boundary) - the_buffer_size = page_extend((aligned_height + 2) * s->pitch); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - the_buffer_copy = (uint8 *)malloc(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer)); - - // Check whether we can initialize the VOSF subsystem and it's profitable - if (!video_vosf_init(monitor)) { - WarningAlert(GetString(STR_VOSF_INIT_ERR)); - use_vosf = false; - } - else if (!video_vosf_profitable()) { - video_vosf_exit(); - printf("VOSF acceleration is not profitable on this platform, disabling it\n"); - use_vosf = false; - } - if (!use_vosf) { - free(the_buffer_copy); - vm_release(the_buffer, the_buffer_size); - the_host_buffer = NULL; - } -#endif - if (!use_vosf) { - // Allocate memory for frame buffer - the_buffer_size = (aligned_height + 2) * s->pitch; - the_buffer_copy = (uint8 *)calloc(1, the_buffer_size); - the_buffer = (uint8 *)vm_acquire_framebuffer(the_buffer_size); - D(bug("the_buffer = %p, the_buffer_copy = %p\n", the_buffer, the_buffer_copy)); - } - - // Set frame buffer base - set_mac_frame_buffer(monitor, VIDEO_MODE_DEPTH); - - adapt_to_video_mode(); -} - -void driver_base::adapt_to_video_mode() { - ADBSetRelMouseMode(false); - - // Init blitting routines - SDL_PixelFormat *f = s->format; - VisualFormat visualFormat; - visualFormat.depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - visualFormat.Rmask = f->Rmask; - visualFormat.Gmask = f->Gmask; - visualFormat.Bmask = f->Bmask; - Screen_blitter_init(visualFormat, true, mac_depth_of_video_depth(VIDEO_MODE_DEPTH)); - - // Load gray ramp to 8->16/32 expand map - if (!IsDirectMode(mode)) - for (int i=0; i<256; i++) - ExpandMap[i] = SDL_MapRGB(f, i, i, i); - - - bool hardware_cursor = false; -#ifdef SHEEPSHAVER - hardware_cursor = video_can_change_cursor(); - if (hardware_cursor) { - // Create cursor - if ((sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, 0, 0)) != NULL) { - SDL_SetCursor(sdl_cursor); - } - } - // Tell the video driver there's a change in cursor type - if (private_data) - private_data->cursorHardware = hardware_cursor; -#endif - // Hide cursor - SDL_ShowCursor(hardware_cursor); - - // Set window name/class - set_window_name(STR_WINDOW_TITLE); - - // Everything went well - init_ok = true; -} - -driver_base::~driver_base() -{ - ungrab_mouse(); - restore_mouse_accel(); - - if (s) - SDL_FreeSurface(s); - - // the_buffer shall always be mapped through vm_acquire_framebuffer() - if (the_buffer != VM_MAP_FAILED) { - D(bug(" releasing the_buffer at %p (%d bytes)\n", the_buffer, the_buffer_size)); - vm_release_framebuffer(the_buffer, the_buffer_size); - the_buffer = NULL; - } - - // Free frame buffer(s) - if (!use_vosf) { - if (the_buffer_copy) { - free(the_buffer_copy); - the_buffer_copy = NULL; - } - } -#ifdef ENABLE_VOSF - else { - if (the_buffer_copy) { - D(bug(" freeing the_buffer_copy at %p\n", the_buffer_copy)); - free(the_buffer_copy); - the_buffer_copy = NULL; - } - - // Deinitialize VOSF - video_vosf_exit(); - } -#endif - - SDL_ShowCursor(1); -} - -// Palette has changed -void driver_base::update_palette(void) -{ - const VIDEO_MODE &mode = monitor.get_current_mode(); - - if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) - SDL_SetPalette(s, SDL_PHYSPAL, sdl_palette, 0, 256); -} - -// Disable mouse acceleration -void driver_base::disable_mouse_accel(void) -{ -} - -// Restore mouse acceleration to original value -void driver_base::restore_mouse_accel(void) -{ -} - -// Toggle mouse grab -void driver_base::toggle_mouse_grab(void) -{ - if (mouse_grabbed) - ungrab_mouse(); - else - grab_mouse(); -} - -// Grab mouse, switch to relative mouse mode -void driver_base::grab_mouse(void) -{ - if (!mouse_grabbed) { - SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_ON); - if (new_mode == SDL_GRAB_ON) { - disable_mouse_accel(); - mouse_grabbed = true; - } - } -} - -// Ungrab mouse, switch to absolute mouse mode -void driver_base::ungrab_mouse(void) -{ - if (mouse_grabbed) { - SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_OFF); - if (new_mode == SDL_GRAB_OFF) { - restore_mouse_accel(); - mouse_grabbed = false; - } - } -} - -/* - * Initialization - */ - -// Init keycode translation table -static void keycode_init(void) -{ - bool use_kc = PrefsFindBool("keycodes"); - if (use_kc) { - - // Get keycode file path from preferences - const char *kc_path = PrefsFindString("keycodefile"); - - // Open keycode table - FILE *f = fopen(kc_path ? kc_path : KEYCODE_FILE_NAME, "r"); - if (f == NULL) { - char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_FILE_WARN), kc_path ? kc_path : KEYCODE_FILE_NAME, strerror(errno)); - WarningAlert(str); - return; - } - - // Default translation table - for (int i=0; i<256; i++) - keycode_table[i] = -1; - - // Search for server vendor string, then read keycodes - char video_driver[256]; - SDL_VideoDriverName(video_driver, sizeof(video_driver)); - bool video_driver_found = false; - char line[256]; - int n_keys = 0; - while (fgets(line, sizeof(line) - 1, f)) { - // Read line - int len = strlen(line); - if (len == 0) - continue; - line[len-1] = 0; - - // Comments begin with "#" or ";" - if (line[0] == '#' || line[0] == ';' || line[0] == 0) - continue; - - if (video_driver_found) { - // Skip aliases as long as we have read keycodes yet - // Otherwise, it's another mapping and we have to stop - static const char sdl_str[] = "sdl"; - if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0 && n_keys == 0) - continue; - - // Read keycode - int x_code, mac_code; - if (sscanf(line, "%d %d", &x_code, &mac_code) == 2) - keycode_table[x_code & 0xff] = mac_code, n_keys++; - else - break; - } else { - // Search for SDL video driver string - static const char sdl_str[] = "sdl"; - if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) { - char *p = line + sizeof(sdl_str); - if (strstr(video_driver, p) == video_driver) - video_driver_found = true; - } - } - } - - // Keycode file completely read - fclose(f); - use_keycodes = video_driver_found; - - // Vendor not found? Then display warning - if (!video_driver_found) { - char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver, kc_path ? kc_path : KEYCODE_FILE_NAME); - WarningAlert(str); - return; - } - - D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver, n_keys)); - } -} - -// Open display for current mode -bool SDL_monitor_desc::video_open(void) -{ - D(bug("video_open()\n")); -#if DEBUG - const VIDEO_MODE &mode = get_current_mode(); - D(bug("Current video mode:\n")); - D(bug(" %dx%d (ID %02x), %d bpp\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << (VIDEO_MODE_DEPTH & 0x0f))); -#endif - - // Create display driver object of requested type - drv = new(std::nothrow) driver_base(*this); - if (drv == NULL) - return false; - drv->init(); - if (!drv->init_ok) { - delete drv; - drv = NULL; - return false; - } - -#ifdef WIN32 - // Chain in a new message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - sdl_window_proc = (WNDPROC)GetWindowLongPtr(the_window, GWLP_WNDPROC); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)windows_message_handler); -#endif - - // Initialize VideoRefresh function - VideoRefreshInit(); - - // Lock down frame buffer - LOCK_FRAME_BUFFER; - - // Start redraw/input thread -#ifndef USE_CPU_EMUL_SERVICES - redraw_thread_cancel = false; - redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, NULL)) != NULL); - if (!redraw_thread_active) { - printf("FATAL: cannot create redraw thread\n"); - return false; - } -#else - redraw_thread_active = true; -#endif - return true; -} - -#ifdef SHEEPSHAVER -bool VideoInit(void) -{ - const bool classic = false; -#else -bool VideoInit(bool classic) -{ -#endif - classic_mode = classic; - -#ifdef ENABLE_VOSF - // Zero the mainBuffer structure - mainBuffer.dirtyPages = NULL; - mainBuffer.pageInfo = NULL; -#endif - - // Create Mutexes - if ((sdl_events_lock = SDL_CreateMutex()) == NULL) - return false; - if ((sdl_palette_lock = SDL_CreateMutex()) == NULL) - return false; - if ((frame_buffer_lock = SDL_CreateMutex()) == NULL) - return false; - - // Init keycode translation - keycode_init(); - - // Read prefs - frame_skip = PrefsFindInt32("frameskip"); - mouse_wheel_mode = PrefsFindInt32("mousewheelmode"); - mouse_wheel_lines = PrefsFindInt32("mousewheellines"); - - // Get screen mode from preferences - migrate_screen_prefs(); - const char *mode_str = NULL; - if (classic_mode) - mode_str = "win/512/342"; - else - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width, default_height; - if (classic) { - default_width = 512; - default_height = 384; - } - else { - default_width = 640; - default_height = 480; - } - display_type = DISPLAY_WINDOW; - if (mode_str) { - if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_WINDOW; - else if (sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) - display_type = DISPLAY_SCREEN; - } - if (default_width <= 0) - default_width = sdl_display_width(); - else if (default_width > sdl_display_width()) - default_width = sdl_display_width(); - if (default_height <= 0) - default_height = sdl_display_height(); - else if (default_height > sdl_display_height()) - default_height = sdl_display_height(); - - // Mac screen depth follows X depth - screen_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; - int default_depth; - switch (screen_depth) { - case 8: - default_depth = VIDEO_DEPTH_8BIT; - break; - case 15: case 16: - default_depth = VIDEO_DEPTH_16BIT; - break; - case 24: case 32: - default_depth = VIDEO_DEPTH_32BIT; - break; - default: - default_depth = VIDEO_DEPTH_1BIT; - break; - } - - // Initialize list of video modes to try - struct { - int w; - int h; - int resolution_id; - } -#ifdef SHEEPSHAVER - // Omit Classic resolutions - video_modes[] = { - { -1, -1, 0x80 }, - { 640, 480, 0x81 }, - { 800, 600, 0x82 }, - { 1024, 768, 0x83 }, - { 1152, 870, 0x84 }, - { 1280, 1024, 0x85 }, - { 1600, 1200, 0x86 }, - { 0, } - }; -#else - video_modes[] = { - { -1, -1, 0x80 }, - { 512, 384, 0x80 }, - { 640, 480, 0x81 }, - { 800, 600, 0x82 }, - { 1024, 768, 0x83 }, - { 1152, 870, 0x84 }, - { 1280, 1024, 0x85 }, - { 1600, 1200, 0x86 }, - { 0, } - }; -#endif - video_modes[0].w = default_width; - video_modes[0].h = default_height; - - // Construct list of supported modes - if (display_type == DISPLAY_WINDOW) { - if (classic) - add_mode(display_type, 512, 342, 0x80, 64, VIDEO_DEPTH_1BIT); - else { - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (i > 0 && (w >= default_width || h >= default_height)) - continue; - for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) - add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); - } - } - } else if (display_type == DISPLAY_SCREEN) { - for (int i = 0; video_modes[i].w != 0; i++) { - const int w = video_modes[i].w; - const int h = video_modes[i].h; - if (i > 0 && (w >= default_width || h >= default_height)) - continue; - if (w == 512 && h == 384) - continue; - for (int d = VIDEO_DEPTH_1BIT; d <= default_depth; d++) - add_mode(display_type, w, h, video_modes[i].resolution_id, TrivialBytesPerRow(w, (video_depth)d), d); - } - } - - if (VideoModes.empty()) { - ErrorAlert(STR_NO_XVISUAL_ERR); - return false; - } - - // Find requested default mode with specified dimensions - uint32 default_id; - std::vector::const_iterator i, end = VideoModes.end(); - for (i = VideoModes.begin(); i != end; ++i) { - const VIDEO_MODE & mode = (*i); - if (VIDEO_MODE_X == default_width && VIDEO_MODE_Y == default_height && VIDEO_MODE_DEPTH == default_depth) { - default_id = VIDEO_MODE_RESOLUTION; -#ifdef SHEEPSHAVER - std::vector::const_iterator begin = VideoModes.begin(); - cur_mode = distance(begin, i); -#endif - break; - } - } - if (i == end) { // not found, use first available mode - const VIDEO_MODE & mode = VideoModes[0]; - default_depth = VIDEO_MODE_DEPTH; - default_id = VIDEO_MODE_RESOLUTION; -#ifdef SHEEPSHAVER - cur_mode = 0; -#endif - } - -#ifdef SHEEPSHAVER - for (int i = 0; i < VideoModes.size(); i++) - VModes[i] = VideoModes[i]; - VideoInfo *p = &VModes[VideoModes.size()]; - p->viType = DIS_INVALID; // End marker - p->viRowBytes = 0; - p->viXsize = p->viYsize = 0; - p->viAppleMode = 0; - p->viAppleID = 0; -#endif - -#if DEBUG - D(bug("Available video modes:\n")); - for (i = VideoModes.begin(); i != end; ++i) { - const VIDEO_MODE & mode = (*i); - int bits = 1 << VIDEO_MODE_DEPTH; - if (bits == 16) - bits = 15; - else if (bits == 32) - bits = 24; - D(bug(" %dx%d (ID %02x), %d colors\n", VIDEO_MODE_X, VIDEO_MODE_Y, VIDEO_MODE_RESOLUTION, 1 << bits)); - } -#endif - - int color_depth = get_customized_color_depth(default_depth); - - D(bug("Return get_customized_color_depth %d\n", color_depth)); - - // Create SDL_monitor_desc for this (the only) display - SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)color_depth, default_id); - VideoMonitors.push_back(monitor); - - // Open display - return monitor->video_open(); -} - - -/* - * Deinitialization - */ - -// Close display -void SDL_monitor_desc::video_close(void) -{ - D(bug("video_close()\n")); - -#ifdef WIN32 - // Remove message handler for WM_DEVICECHANGE - HWND the_window = GetMainWindowHandle(); - SetWindowLongPtr(the_window, GWLP_WNDPROC, (LONG_PTR)sdl_window_proc); -#endif - - // Stop redraw thread -#ifndef USE_CPU_EMUL_SERVICES - if (redraw_thread_active) { - redraw_thread_cancel = true; - SDL_WaitThread(redraw_thread, NULL); - } -#endif - redraw_thread_active = false; - - // Unlock frame buffer - UNLOCK_FRAME_BUFFER; - D(bug(" frame buffer unlocked\n")); - - // Close display - delete drv; - drv = NULL; -} - -void VideoExit(void) -{ - // Close displays - vector::iterator i, end = VideoMonitors.end(); - for (i = VideoMonitors.begin(); i != end; ++i) - dynamic_cast(*i)->video_close(); - - // Destroy locks - if (frame_buffer_lock) - SDL_DestroyMutex(frame_buffer_lock); - if (sdl_palette_lock) - SDL_DestroyMutex(sdl_palette_lock); - if (sdl_events_lock) - SDL_DestroyMutex(sdl_events_lock); -} - - -/* - * Close down full-screen mode (if bringing up error alerts is unsafe while in full-screen mode) - */ - -void VideoQuitFullScreen(void) -{ - D(bug("VideoQuitFullScreen()\n")); - quit_full_screen = true; -} - -static void do_toggle_fullscreen(void) -{ -#ifndef USE_CPU_EMUL_SERVICES - // pause redraw thread - thread_stop_ack = false; - thread_stop_req = true; - while (!thread_stop_ack) ; -#endif - - // save the mouse position - int x, y; - SDL_GetMouseState(&x, &y); - - // save the screen contents - SDL_Surface *tmp_surface = SDL_ConvertSurface(drv->s, drv->s->format, - drv->s->flags); - - // switch modes - display_type = (display_type == DISPLAY_SCREEN) ? DISPLAY_WINDOW - : DISPLAY_SCREEN; - drv->set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); - drv->adapt_to_video_mode(); - - // reset the palette -#ifdef SHEEPSHAVER - video_set_palette(); -#endif - drv->update_palette(); - - // restore the screen contents - SDL_BlitSurface(tmp_surface, NULL, drv->s, NULL); - SDL_FreeSurface(tmp_surface); - SDL_UpdateRect(drv->s, 0, 0, 0, 0); - - // reset the video refresh handler - VideoRefreshInit(); - - // while SetVideoMode is happening, control key up may be missed - ADBKeyUp(0x36); - - // restore the mouse position - SDL_WarpMouse(x, y); - - // resume redraw thread - toggle_fullscreen = false; -#ifndef USE_CPU_EMUL_SERVICES - thread_stop_req = false; -#endif -} - -/* - * Mac VBL interrupt - */ - -/* - * Execute video VBL routine - */ - -#ifdef SHEEPSHAVER -void VideoVBL(void) -{ - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - if (toggle_fullscreen) - do_toggle_fullscreen(); - - // Setting the window name must happen on the main thread, else it doesn't work on - // some platforms - e.g. macOS Sierra. - if (mouse_grabbed_window_name_status != mouse_grabbed) { - set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE); - mouse_grabbed_window_name_status = mouse_grabbed; - } - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; - - // Execute video VBL - if (private_data != NULL && private_data->interruptsEnabled) - VSLDoInterruptService(private_data->vslServiceID); -} -#else -void VideoInterrupt(void) -{ - // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() - SDL_PumpEvents(); - - // Emergency quit requested? Then quit - if (emerg_quit) - QuitEmulator(); - - if (toggle_fullscreen) - do_toggle_fullscreen(); - - // Setting the window name must happen on the main thread, else it doesn't work on - // some platforms - e.g. macOS Sierra. - if (mouse_grabbed_window_name_status != mouse_grabbed) { - set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE); - mouse_grabbed_window_name_status = mouse_grabbed; - } - - // Temporarily give up frame buffer lock (this is the point where - // we are suspended when the user presses Ctrl-Tab) - UNLOCK_FRAME_BUFFER; - LOCK_FRAME_BUFFER; -} -#endif - - -/* - * Set palette - */ - -#ifdef SHEEPSHAVER -void video_set_palette(void) -{ - monitor_desc * monitor = VideoMonitors[0]; - int n_colors = palette_size(monitor->get_current_mode().viAppleMode); - uint8 pal[256 * 3]; - for (int c = 0; c < n_colors; c++) { - pal[c*3 + 0] = mac_pal[c].red; - pal[c*3 + 1] = mac_pal[c].green; - pal[c*3 + 2] = mac_pal[c].blue; - } - monitor->set_palette(pal, n_colors); -} -#endif - -void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) -{ - const VIDEO_MODE &mode = get_current_mode(); - - if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) { - // handle the gamma ramp - - if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey - return; // ignore - - uint16 red[256]; - uint16 green[256]; - uint16 blue[256]; - - int repeats = 256 / num_in; - - for (int i = 0; i < num_in; i++) { - for (int j = 0; j < repeats; j++) { - red[i*repeats + j] = pal[i*3 + 0] << 8; - green[i*repeats + j] = pal[i*3 + 1] << 8; - blue[i*repeats + j] = pal[i*3 + 2] << 8; - } - } - - // fill remaining entries (if any) with last value - for (int i = num_in * repeats; i < 256; i++) { - red[i] = pal[(num_in - 1) * 3] << 8; - green[i] = pal[(num_in - 1) * 3 + 1] << 8; - blue[i] = pal[(num_in - 1) * 3 + 2] << 8; - } - - bool changed = (memcmp(red, last_gamma_red, 512) != 0 || - memcmp(green, last_gamma_green, 512) != 0 || - memcmp(blue, last_gamma_blue, 512) != 0); - - if (changed) { - int result = SDL_SetGammaRamp(red, green, blue); - - if (result < 0) { - fprintf(stderr, "SDL_SetGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError()); - } - - memcpy(last_gamma_red, red, 512); - memcpy(last_gamma_green, green, 512); - memcpy(last_gamma_blue, blue, 512); - } - - return; - } - - LOCK_PALETTE; - - // Convert colors to XColor array - int num_out = 256; - bool stretch = false; - SDL_Color *p = sdl_palette; - for (int i=0; ir = pal[c*3 + 0] * 0x0101; - p->g = pal[c*3 + 1] * 0x0101; - p->b = pal[c*3 + 2] * 0x0101; - p++; - } - - // Recalculate pixel color expansion map - if (!IsDirectMode(mode)) { - for (int i=0; i<256; i++) { - int c = i & (num_in-1); // If there are less than 256 colors, we repeat the first entries (this makes color expansion easier) - ExpandMap[i] = SDL_MapRGB(drv->s->format, pal[c*3+0], pal[c*3+1], pal[c*3+2]); - } - -#ifdef ENABLE_VOSF - if (use_vosf) { - // We have to redraw everything because the interpretation of pixel values changed - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - memset(the_buffer_copy, 0, VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y); - } -#endif - } - - // Tell redraw thread to change palette - sdl_palette_changed = true; - - UNLOCK_PALETTE; -} - - -/* - * Switch video mode - */ - -#ifdef SHEEPSHAVER -int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) -{ - /* return if no mode change */ - if ((csSave->saveData == ReadMacInt32(ParamPtr + csData)) && - (csSave->saveMode == ReadMacInt16(ParamPtr + csMode))) return noErr; - - /* first find video mode in table */ - for (int i=0; VModes[i].viType != DIS_INVALID; i++) { - if ((ReadMacInt16(ParamPtr + csMode) == VModes[i].viAppleMode) && - (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { - csSave->saveMode = ReadMacInt16(ParamPtr + csMode); - csSave->saveData = ReadMacInt32(ParamPtr + csData); - csSave->savePage = ReadMacInt16(ParamPtr + csPage); - - // Disable interrupts and pause redraw thread - DisableInterrupt(); - thread_stop_ack = false; - thread_stop_req = true; - while (!thread_stop_ack) ; - - cur_mode = i; - monitor_desc *monitor = VideoMonitors[0]; - monitor->switch_to_current_mode(); - - WriteMacInt32(ParamPtr + csBaseAddr, screen_base); - csSave->saveBaseAddr=screen_base; - csSave->saveData=VModes[cur_mode].viAppleID;/* First mode ... */ - csSave->saveMode=VModes[cur_mode].viAppleMode; - - // Enable interrupts and resume redraw thread - thread_stop_req = false; - EnableInterrupt(); - return noErr; - } - } - return paramErr; -} -#endif - -void SDL_monitor_desc::switch_to_current_mode(void) -{ - // Close and reopen display - LOCK_EVENTS; - video_close(); - video_open(); - UNLOCK_EVENTS; - - if (drv == NULL) { - ErrorAlert(STR_OPEN_WINDOW_ERR); - QuitEmulator(); - } -} - - -/* - * Can we set the MacOS cursor image into the window? - */ - -#ifdef SHEEPSHAVER -bool video_can_change_cursor(void) -{ - if (display_type != DISPLAY_WINDOW) - return false; - -#if defined(__APPLE__) - static char driver[] = "Quartz?"; - static int quartzok = -1; - - if (quartzok < 0) { - if (SDL_VideoDriverName(driver, sizeof driver) == NULL || strncmp(driver, "Quartz", sizeof driver)) - quartzok = true; - else { - // Quartz driver bug prevents cursor changing in SDL 1.2.11 to 1.2.14. - const SDL_version *vp = SDL_Linked_Version(); - int version = SDL_VERSIONNUM(vp->major, vp->minor, vp->patch); - quartzok = (version <= SDL_VERSIONNUM(1, 2, 10) || version >= SDL_VERSIONNUM(1, 2, 15)); - } - } - - return quartzok; -#else - return true; -#endif -} -#endif - - -/* - * Set cursor image for window - */ - -#ifdef SHEEPSHAVER -void video_set_cursor(void) -{ - // Set new cursor image if it was changed - if (sdl_cursor) { - SDL_FreeCursor(sdl_cursor); - sdl_cursor = SDL_CreateCursor(MacCursor + 4, MacCursor + 36, 16, 16, MacCursor[2], MacCursor[3]); - if (sdl_cursor) { - SDL_ShowCursor(private_data == NULL || private_data->cursorVisible); - SDL_SetCursor(sdl_cursor); - - // XXX Windows apparently needs an extra mouse event to - // make the new cursor image visible. - // On Mac, if mouse is grabbed, SDL_ShowCursor() recenters the - // mouse, we have to put it back. - bool move = false; -#ifdef WIN32 - move = true; -#elif defined(__APPLE__) - move = mouse_grabbed; -#endif - if (move) { - int visible = SDL_ShowCursor(-1); - if (visible) { - int x, y; - SDL_GetMouseState(&x, &y); - SDL_WarpMouse(x, y); - } - } - } - } -} -#endif - - -/* - * Keyboard-related utilify functions - */ - -static bool is_modifier_key(SDL_KeyboardEvent const & e) -{ - switch (e.keysym.sym) { - case SDLK_NUMLOCK: - case SDLK_CAPSLOCK: - case SDLK_SCROLLOCK: - case SDLK_RSHIFT: - case SDLK_LSHIFT: - case SDLK_RCTRL: - case SDLK_LCTRL: - case SDLK_RALT: - case SDLK_LALT: - case SDLK_RMETA: - case SDLK_LMETA: - case SDLK_LSUPER: - case SDLK_RSUPER: - case SDLK_MODE: - case SDLK_COMPOSE: - return true; - } - return false; -} - -static bool is_ctrl_down(SDL_keysym const & ks) -{ - return ctrl_down || (ks.mod & KMOD_CTRL); -} - - -/* - * Translate key event to Mac keycode, returns -1 if no keycode was found - * and -2 if the key was recognized as a hotkey - */ - -static int kc_decode(SDL_keysym const & ks, bool key_down) -{ - switch (ks.sym) { - case SDLK_a: return 0x00; - case SDLK_b: return 0x0b; - case SDLK_c: return 0x08; - case SDLK_d: return 0x02; - case SDLK_e: return 0x0e; - case SDLK_f: return 0x03; - case SDLK_g: return 0x05; - case SDLK_h: return 0x04; - case SDLK_i: return 0x22; - case SDLK_j: return 0x26; - case SDLK_k: return 0x28; - case SDLK_l: return 0x25; - case SDLK_m: return 0x2e; - case SDLK_n: return 0x2d; - case SDLK_o: return 0x1f; - case SDLK_p: return 0x23; - case SDLK_q: return 0x0c; - case SDLK_r: return 0x0f; - case SDLK_s: return 0x01; - case SDLK_t: return 0x11; - case SDLK_u: return 0x20; - case SDLK_v: return 0x09; - case SDLK_w: return 0x0d; - case SDLK_x: return 0x07; - case SDLK_y: return 0x10; - case SDLK_z: return 0x06; - - case SDLK_1: case SDLK_EXCLAIM: return 0x12; - case SDLK_2: case SDLK_AT: return 0x13; - case SDLK_3: case SDLK_HASH: return 0x14; - case SDLK_4: case SDLK_DOLLAR: return 0x15; - case SDLK_5: return 0x17; - case SDLK_6: return 0x16; - case SDLK_7: return 0x1a; - case SDLK_8: return 0x1c; - case SDLK_9: return 0x19; - case SDLK_0: return 0x1d; - - case SDLK_BACKQUOTE: return 0x0a; - case SDLK_MINUS: case SDLK_UNDERSCORE: return 0x1b; - case SDLK_EQUALS: case SDLK_PLUS: return 0x18; - case SDLK_LEFTBRACKET: return 0x21; - case SDLK_RIGHTBRACKET: return 0x1e; - case SDLK_BACKSLASH: return 0x2a; - case SDLK_SEMICOLON: case SDLK_COLON: return 0x29; - case SDLK_QUOTE: case SDLK_QUOTEDBL: return 0x27; - case SDLK_COMMA: case SDLK_LESS: return 0x2b; - case SDLK_PERIOD: case SDLK_GREATER: return 0x2f; - case SDLK_SLASH: case SDLK_QUESTION: return 0x2c; - - case SDLK_TAB: if (is_ctrl_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30; - case SDLK_RETURN: if (is_ctrl_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24; - case SDLK_SPACE: return 0x31; - case SDLK_BACKSPACE: return 0x33; - - case SDLK_DELETE: return 0x75; - case SDLK_INSERT: return 0x72; - case SDLK_HOME: case SDLK_HELP: return 0x73; - case SDLK_END: return 0x77; - case SDLK_PAGEUP: return 0x74; - case SDLK_PAGEDOWN: return 0x79; - - case SDLK_LCTRL: return 0x36; - case SDLK_RCTRL: return 0x36; - case SDLK_LSHIFT: return 0x38; - case SDLK_RSHIFT: return 0x38; -#if (defined(__APPLE__) && defined(__MACH__)) - case SDLK_LALT: return 0x3a; - case SDLK_RALT: return 0x3a; - case SDLK_LMETA: return 0x37; - case SDLK_RMETA: return 0x37; -#else - case SDLK_LALT: return 0x37; - case SDLK_RALT: return 0x37; - case SDLK_LMETA: return 0x3a; - case SDLK_RMETA: return 0x3a; -#endif - case SDLK_LSUPER: return 0x3a; // "Windows" key - case SDLK_RSUPER: return 0x3a; - case SDLK_MENU: return 0x32; - case SDLK_CAPSLOCK: return 0x39; - case SDLK_NUMLOCK: return 0x47; - - case SDLK_UP: return 0x3e; - case SDLK_DOWN: return 0x3d; - case SDLK_LEFT: return 0x3b; - case SDLK_RIGHT: return 0x3c; - - case SDLK_ESCAPE: if (is_ctrl_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35; - - case SDLK_F1: if (is_ctrl_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a; - case SDLK_F2: return 0x78; - case SDLK_F3: return 0x63; - case SDLK_F4: return 0x76; - case SDLK_F5: if (is_ctrl_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60; - case SDLK_F6: return 0x61; - case SDLK_F7: return 0x62; - case SDLK_F8: return 0x64; - case SDLK_F9: return 0x65; - case SDLK_F10: return 0x6d; - case SDLK_F11: return 0x67; - case SDLK_F12: return 0x6f; - - case SDLK_PRINT: return 0x69; - case SDLK_SCROLLOCK: return 0x6b; - case SDLK_PAUSE: return 0x71; - - case SDLK_KP0: return 0x52; - case SDLK_KP1: return 0x53; - case SDLK_KP2: return 0x54; - case SDLK_KP3: return 0x55; - case SDLK_KP4: return 0x56; - case SDLK_KP5: return 0x57; - case SDLK_KP6: return 0x58; - case SDLK_KP7: return 0x59; - case SDLK_KP8: return 0x5b; - case SDLK_KP9: return 0x5c; - case SDLK_KP_PERIOD: return 0x41; - case SDLK_KP_PLUS: return 0x45; - case SDLK_KP_MINUS: return 0x4e; - case SDLK_KP_MULTIPLY: return 0x43; - case SDLK_KP_DIVIDE: return 0x4b; - case SDLK_KP_ENTER: return 0x4c; - case SDLK_KP_EQUALS: return 0x51; - } - D(bug("Unhandled SDL keysym: %d\n", ks.sym)); - return -1; -} - -static int event2keycode(SDL_KeyboardEvent const &ev, bool key_down) -{ - return kc_decode(ev.keysym, key_down); -} - -static void force_complete_window_refresh() -{ - if (display_type == DISPLAY_WINDOW) { -#ifdef ENABLE_VOSF - if (use_vosf) { // VOSF refresh - LOCK_VOSF; - PFLAG_SET_ALL; - UNLOCK_VOSF; - } -#endif - // Ensure each byte of the_buffer_copy differs from the_buffer to force a full update. - const VIDEO_MODE &mode = VideoMonitors[0]->get_current_mode(); - const int len = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; - for (int i = 0; i < len; i++) - the_buffer_copy[i] = !the_buffer[i]; - } -} - -/* - * SDL event handling - */ - -static void handle_events(void) -{ - SDL_Event events[10]; - const int n_max_events = sizeof(events) / sizeof(events[0]); - int n_events; - - while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, sdl_eventmask)) > 0) { - for (int i = 0; i < n_events; i++) { - SDL_Event const & event = events[i]; - switch (event.type) { - - // Mouse button - case SDL_MOUSEBUTTONDOWN: { - unsigned int button = event.button.button; - if (button == SDL_BUTTON_LEFT) - ADBMouseDown(0); - else if (button == SDL_BUTTON_RIGHT) - ADBMouseDown(1); - else if (button == SDL_BUTTON_MIDDLE) - ADBMouseDown(2); - else if (button < 6) { // Wheel mouse - if (mouse_wheel_mode == 0) { - int key = (button == 5) ? 0x79 : 0x74; // Page up/down - ADBKeyDown(key); - ADBKeyUp(key); - } else { - int key = (button == 5) ? 0x3d : 0x3e; // Cursor up/down - for(int i=0; imouse_moved(event.motion.x, event.motion.y); - break; - - // Keyboard - case SDL_KEYDOWN: { - int code = -1; - if (use_keycodes && !is_modifier_key(event.key)) { - if (event2keycode(event.key, true) != -2) // This is called to process the hotkeys - code = keycode_table[event.key.keysym.scancode & 0xff]; - } else - code = event2keycode(event.key, true); - if (code >= 0) { - if (!emul_suspended) { - if (code == 0x39) { // Caps Lock pressed - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyDown(code); - if (code == 0x36) - ctrl_down = true; - } else { - if (code == 0x31) - drv->resume(); // Space wakes us up - } - } - break; - } - case SDL_KEYUP: { - int code = -1; - if (use_keycodes && !is_modifier_key(event.key)) { - if (event2keycode(event.key, false) != -2) // This is called to process the hotkeys - code = keycode_table[event.key.keysym.scancode & 0xff]; - } else - code = event2keycode(event.key, false); - if (code >= 0) { - if (code == 0x39) { // Caps Lock released - if (caps_on) { - ADBKeyUp(code); - caps_on = false; - } else { - ADBKeyDown(code); - caps_on = true; - } - } else - ADBKeyUp(code); - if (code == 0x36) - ctrl_down = false; - } - break; - } - - // Hidden parts exposed, force complete refresh of window - case SDL_VIDEOEXPOSE: - force_complete_window_refresh(); - break; - - // Window "close" widget clicked - case SDL_QUIT: - ADBKeyDown(0x7f); // Power key - ADBKeyUp(0x7f); - break; - - // Application activate/deactivate - case SDL_ACTIVEEVENT: - // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. - if (event.active.gain) - force_complete_window_refresh(); - break; - } - } - } -} - - -/* - * Window display update - */ - -// Static display update (fixed frame rate, but incremental) -static void update_display_static(driver_base *drv) -{ - // Incremental update code - int wide = 0, high = 0; - uint32 x1, x2, y1, y2; - const VIDEO_MODE &mode = drv->mode; - int bytes_per_row = VIDEO_MODE_ROW_BYTES; - uint8 *p, *p2; - - // Check for first line from top and first line from bottom that have changed - y1 = 0; - for (uint32 j = 0; j < VIDEO_MODE_Y; j++) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y1 = j; - break; - } - } - y2 = y1 - 1; - for (uint32 j = VIDEO_MODE_Y; j-- > y1; ) { - if (memcmp(&the_buffer[j * bytes_per_row], &the_buffer_copy[j * bytes_per_row], bytes_per_row)) { - y2 = j; - break; - } - } - high = y2 - y1 + 1; - - // Check for first column from left and first column from right that have changed - if (high) { - if (VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) { - const int src_bytes_per_row = bytes_per_row; - const int dst_bytes_per_row = drv->s->pitch; - const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row; - - x1 = VIDEO_MODE_X / pixels_per_byte; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (uint32 i = 0; i < x1; i++) { - if (*p != *p2) { - x1 = i; - break; - } - p++; p2++; - } - } - x2 = x1; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (uint32 i = (VIDEO_MODE_X / pixels_per_byte); i > x2; i--) { - p--; p2--; - if (*p != *p2) { - x2 = i; - break; - } - } - } - x1 *= pixels_per_byte; - x2 *= pixels_per_byte; - wide = (x2 - x1 + pixels_per_byte - 1) & -pixels_per_byte; - - // Update copy of the_buffer - if (high && wide) { - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Blit to screen surface - int si = y1 * src_bytes_per_row + (x1 / pixels_per_byte); - int di = y1 * dst_bytes_per_row + x1; - for (uint32 j = y1; j <= y2; j++) { - memcpy(the_buffer_copy + si, the_buffer + si, wide / pixels_per_byte); - Screen_blit((uint8 *)drv->s->pixels + di, the_buffer + si, wide / pixels_per_byte); - si += src_bytes_per_row; - di += dst_bytes_per_row; - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - SDL_UpdateRect(drv->s, x1, y1, wide, high); - } - - } else { - const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X; - const int dst_bytes_per_row = drv->s->pitch; - - x1 = VIDEO_MODE_X; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - for (uint32 i = 0; i < x1 * bytes_per_pixel; i++) { - if (*p != *p2) { - x1 = i / bytes_per_pixel; - break; - } - p++; p2++; - } - } - x2 = x1; - for (uint32 j = y1; j <= y2; j++) { - p = &the_buffer[j * bytes_per_row]; - p2 = &the_buffer_copy[j * bytes_per_row]; - p += bytes_per_row; - p2 += bytes_per_row; - for (uint32 i = VIDEO_MODE_X * bytes_per_pixel; i > x2 * bytes_per_pixel; i--) { - p--; - p2--; - if (*p != *p2) { - x2 = i / bytes_per_pixel; - break; - } - } - } - wide = x2 - x1; - - // Update copy of the_buffer - if (high && wide) { - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Blit to screen surface - for (uint32 j = y1; j <= y2; j++) { - uint32 i = j * bytes_per_row + x1 * bytes_per_pixel; - int dst_i = j * dst_bytes_per_row + x1 * bytes_per_pixel; - memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * wide); - Screen_blit((uint8 *)drv->s->pixels + dst_i, the_buffer + i, bytes_per_pixel * wide); - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - SDL_UpdateRect(drv->s, x1, y1, wide, high); - } - } - } -} - -// Static display update (fixed frame rate, bounding boxes based) -// XXX use NQD bounding boxes to help detect dirty areas? -static void update_display_static_bbox(driver_base *drv) -{ - const VIDEO_MODE &mode = drv->mode; - - // Allocate bounding boxes for SDL_UpdateRects() - const uint32 N_PIXELS = 64; - const uint32 n_x_boxes = (VIDEO_MODE_X + N_PIXELS - 1) / N_PIXELS; - const uint32 n_y_boxes = (VIDEO_MODE_Y + N_PIXELS - 1) / N_PIXELS; - SDL_Rect *boxes = (SDL_Rect *)alloca(sizeof(SDL_Rect) * n_x_boxes * n_y_boxes); - uint32 nr_boxes = 0; - - // Lock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_LockSurface(drv->s); - - // Update the surface from Mac screen - const uint32 bytes_per_row = VIDEO_MODE_ROW_BYTES; - const uint32 bytes_per_pixel = bytes_per_row / VIDEO_MODE_X; - const uint32 dst_bytes_per_row = drv->s->pitch; - for (uint32 y = 0; y < VIDEO_MODE_Y; y += N_PIXELS) { - uint32 h = N_PIXELS; - if (h > VIDEO_MODE_Y - y) - h = VIDEO_MODE_Y - y; - for (uint32 x = 0; x < VIDEO_MODE_X; x += N_PIXELS) { - uint32 w = N_PIXELS; - if (w > VIDEO_MODE_X - x) - w = VIDEO_MODE_X - x; - const int xs = w * bytes_per_pixel; - const int xb = x * bytes_per_pixel; - bool dirty = false; - for (uint32 j = y; j < (y + h); j++) { - const uint32 yb = j * bytes_per_row; - const uint32 dst_yb = j * dst_bytes_per_row; - if (memcmp(&the_buffer[yb + xb], &the_buffer_copy[yb + xb], xs) != 0) { - memcpy(&the_buffer_copy[yb + xb], &the_buffer[yb + xb], xs); - Screen_blit((uint8 *)drv->s->pixels + dst_yb + xb, the_buffer + yb + xb, xs); - dirty = true; - } - } - if (dirty) { - boxes[nr_boxes].x = x; - boxes[nr_boxes].y = y; - boxes[nr_boxes].w = w; - boxes[nr_boxes].h = h; - nr_boxes++; - } - } - } - - // Unlock surface, if required - if (SDL_MUSTLOCK(drv->s)) - SDL_UnlockSurface(drv->s); - - // Refresh display - if (nr_boxes) - SDL_UpdateRects(drv->s, nr_boxes, boxes); -} - - -// We suggest the compiler to inline the next two functions so that it -// may specialise the code according to the current screen depth and -// display type. A clever compiler would do that job by itself though... - -// NOTE: update_display_vosf is inlined too - -static inline void possibly_quit_dga_mode() -{ - // Quit DGA mode if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - delete drv; - drv = NULL; - } -} - -static inline void possibly_ungrab_mouse() -{ - // Ungrab mouse if requested (something terrible has happened and we - // want to give control back to the user) - if (quit_full_screen) { - quit_full_screen = false; - if (drv) - drv->ungrab_mouse(); - } -} - -static inline void handle_palette_changes(void) -{ - LOCK_PALETTE; - - if (sdl_palette_changed) { - sdl_palette_changed = false; - drv->update_palette(); - } - - UNLOCK_PALETTE; -} - -static void video_refresh_window_static(void); - -static void video_refresh_dga(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - video_refresh_window_static(); -} - -#ifdef ENABLE_VOSF -#if REAL_ADDRESSING || DIRECT_ADDRESSING -static void video_refresh_dga_vosf(void) -{ - // Quit DGA mode if requested - possibly_quit_dga_mode(); - - // Update display (VOSF variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_dga_vosf(drv); - UNLOCK_VOSF; - } - } -} -#endif - -static void video_refresh_window_vosf(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (VOSF variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - if (mainBuffer.dirty) { - LOCK_VOSF; - update_display_window_vosf(drv); - UNLOCK_VOSF; - } - } -} -#endif // def ENABLE_VOSF - -static void video_refresh_window_static(void) -{ - // Ungrab mouse if requested - possibly_ungrab_mouse(); - - // Update display (static variant) - static uint32 tick_counter = 0; - if (++tick_counter >= frame_skip) { - tick_counter = 0; - const VIDEO_MODE &mode = drv->mode; - if ((int)VIDEO_MODE_DEPTH >= VIDEO_DEPTH_8BIT) - update_display_static_bbox(drv); - else - update_display_static(drv); - } -} - - -/* - * Thread for screen refresh, input handling etc. - */ - -static void VideoRefreshInit(void) -{ - // TODO: set up specialised 8bpp VideoRefresh handlers ? - if (display_type == DISPLAY_SCREEN) { -#if ENABLE_VOSF && (REAL_ADDRESSING || DIRECT_ADDRESSING) - if (use_vosf) - video_refresh = video_refresh_dga_vosf; - else -#endif - video_refresh = video_refresh_dga; - } - else { -#ifdef ENABLE_VOSF - if (use_vosf) - video_refresh = video_refresh_window_vosf; - else -#endif - video_refresh = video_refresh_window_static; - } -} - -static inline void do_video_refresh(void) -{ - // Handle SDL events - handle_events(); - - // Update display - video_refresh(); - - - // Set new palette if it was changed - handle_palette_changes(); -} - -// This function is called on non-threaded platforms from a timer interrupt -void VideoRefresh(void) -{ - // We need to check redraw_thread_active to inhibit refreshed during - // mode changes on non-threaded platforms - if (!redraw_thread_active) - return; - - // Process pending events and update display - do_video_refresh(); -} - -const int VIDEO_REFRESH_HZ = 60; -const int VIDEO_REFRESH_DELAY = 1000000 / VIDEO_REFRESH_HZ; - -#ifndef USE_CPU_EMUL_SERVICES -static int redraw_func(void *arg) -{ - uint64 start = GetTicks_usec(); - int64 ticks = 0; - uint64 next = GetTicks_usec() + VIDEO_REFRESH_DELAY; - - while (!redraw_thread_cancel) { - - // Wait - next += VIDEO_REFRESH_DELAY; - int32 delay = int32(next - GetTicks_usec()); - if (delay > 0) - Delay_usec(delay); - else if (delay < -VIDEO_REFRESH_DELAY) - next = GetTicks_usec(); - ticks++; - - // Pause if requested (during video mode switches) - if (thread_stop_req) { - thread_stop_ack = true; - continue; - } - - // Process pending events and update display - do_video_refresh(); - } - - uint64 end = GetTicks_usec(); - D(bug("%lld refreshes in %lld usec = %f refreshes/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start))); - return 0; -} -#endif - - -/* - * Record dirty area from NQD - */ - -#ifdef SHEEPSHAVER -void video_set_dirty_area(int x, int y, int w, int h) -{ -#ifdef ENABLE_VOSF - const VIDEO_MODE &mode = drv->mode; - const unsigned screen_width = VIDEO_MODE_X; - const unsigned screen_height = VIDEO_MODE_Y; - const unsigned bytes_per_row = VIDEO_MODE_ROW_BYTES; - - if (use_vosf) { - vosf_set_dirty_area(x, y, w, h, screen_width, screen_height, bytes_per_row); - return; - } -#endif - - // XXX handle dirty bounding boxes for non-VOSF modes -} -#endif - -#endif // ends: SDL version check diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 505e6b0de..28423e8c3 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -33,7 +33,6 @@ AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphi AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [default=no]], [WANT_SDL_AUDIO=$enableval], [WANT_SDL_AUDIO=yes]) AC_ARG_ENABLE(sdl-framework, [ --enable-sdl-framework use SDL framework [default=no]], [WANT_SDL_FRAMEWORK=$enableval], [WANT_SDL_FRAMEWORK=no]) AC_ARG_ENABLE(sdl-framework-prefix, [ --enable-sdl-framework-prefix=PFX default=/Library/Frameworks], [SDL_FRAMEWORK="$enableval"], [SDL_FRAMEWORK=/Library/Frameworks]) -AC_ARG_WITH(sdl1, [ --with-sdl1 use SDL 1.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=1], []) dnl JIT compiler options. AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes]) @@ -284,59 +283,18 @@ if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then fi if [[ "x$WANT_SDL" = "xyes" ]]; then if [[ "x$WANT_SDL_FRAMEWORK" = "xyes" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=$WANT_SDL_VERSION_MAJOR - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=2 - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x2" ]]; then - AC_CHECK_SDLFRAMEWORK(SDL2, [#include ], [ - WANT_SDL_VERSION_MAJOR=2 - ], [ - TEMP_WANT_SDL_VERSION_MAJOR=1 - ]) - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x1" ]]; then - AC_CHECK_SDLFRAMEWORK(SDL, [#include ], [ - WANT_SDL_VERSION_MAJOR=1 - ]) - fi + AC_CHECK_SDLFRAMEWORK(SDL2, [#include ]) else ac_cv_framework_SDL=no fi if [[ "x$ac_cv_framework_SDL" = "xno" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=$WANT_SDL_VERSION_MAJOR - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=2 - fi - - dnl use PKG_PROG_PKG_CONFIG to declare PKG_CONFIG variables. Otherwise, - dnl PKG_* macros may fail, without much explanation. The lack of this - dnl was causing --with-sdl1 to fail, as SDL 1.x could not be detected, - dnl as the 2nd call to PKG_CHECK_MODULES would fail, as $PKG_CONFIG - dnl never got defined (bizarrely-enough). -- dludwig@pobox.com - PKG_PROG_PKG_CONFIG - - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x2" ]]; then - PKG_CHECK_MODULES([sdl2], [sdl2 >= 2.0], [ - CFLAGS="$CFLAGS $sdl2_CFLAGS" - CXXFLAGS="$CXXFLAGS $sdl2_CFLAGS" - LIBS="$LIBS $sdl2_LIBS" - WANT_SDL_VERSION_MAJOR=2 - ], [ - TEMP_WANT_SDL_VERSION_MAJOR=1 - ]) - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x1" ]]; then - PKG_CHECK_MODULES([sdl], [sdl >= 1.2], [ - CFLAGS="$CFLAGS $sdl_CFLAGS" - CXXFLAGS="$CXXFLAGS $sdl_CFLAGS" - LIBS="$LIBS $sdl_LIBS" - WANT_SDL_VERSION_MAJOR=1 - ], [ - WANT_SDL=no - WANT_SDL_VERSION_MAJOR= - ]) - fi + PKG_CHECK_MODULES([sdl2], [sdl2 >= 2.0], [ + CFLAGS="$CFLAGS $sdl2_CFLAGS" + CXXFLAGS="$CXXFLAGS $sdl2_CFLAGS" + LIBS="$LIBS $sdl2_LIBS" + ], [ + WANT_SDL=no + ]) fi SDL_SUPPORT=`echo "$SDL_SUPPORT" | sed -e "s/^ //"` else @@ -792,7 +750,7 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then fi if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support]) - VIDEOSRCS="../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp" + VIDEOSRCS="../SDL/video_sdl2.cpp" KEYCODES="../SDL/keycodes" if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then AC_MSG_CHECKING([whether __LP64__ is defined]) @@ -1751,7 +1709,6 @@ echo echo Mac OS X GUI ........................... : $WANT_MACOSX_GUI echo Mac OS X Sound ......................... : $WANT_MACOSX_SOUND echo SDL support ............................ : $SDL_SUPPORT -echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR echo BINCUE support ......................... : $have_bincue echo LIBVHD support ......................... : $have_libvhd echo VDE support ............................ : $have_vdeplug diff --git a/BasiliskII/src/Windows/BasiliskII.vcxproj b/BasiliskII/src/Windows/BasiliskII.vcxproj index b3a3a3ff2..4437453dc 100644 --- a/BasiliskII/src/Windows/BasiliskII.vcxproj +++ b/BasiliskII/src/Windows/BasiliskII.vcxproj @@ -55,7 +55,6 @@ - @@ -695,4 +694,4 @@ - \ No newline at end of file + diff --git a/BasiliskII/src/Windows/Makefile.in b/BasiliskII/src/Windows/Makefile.in index 40fc67db1..a0f795ef9 100755 --- a/BasiliskII/src/Windows/Makefile.in +++ b/BasiliskII/src/Windows/Makefile.in @@ -66,7 +66,7 @@ SRCS = ../main.cpp main_windows.cpp ../prefs.cpp ../prefs_items.cpp prefs_window ../emul_op.cpp ../macos_util.cpp ../xpram.cpp xpram_windows.cpp ../timer.cpp \ timer_windows.cpp ../adb.cpp ../serial.cpp serial_windows.cpp \ ../ether.cpp ether_windows.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp \ - ../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp ../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp \ + ../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp ../SDL/video_sdl2.cpp \ video_blit.cpp ../audio.cpp ../SDL/audio_sdl.cpp clip_windows.cpp \ ../extfs.cpp extfs_windows.cpp ../user_strings.cpp user_strings_windows.cpp \ vm_alloc.cpp sigsegv.cpp posix_emu.cpp util_windows.cpp \ diff --git a/SheepShaver/src/Unix/configure.ac b/SheepShaver/src/Unix/configure.ac index c65217eb5..d3da4317f 100755 --- a/SheepShaver/src/Unix/configure.ac +++ b/SheepShaver/src/Unix/configure.ac @@ -68,7 +68,6 @@ AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphic AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [default=no]], [WANT_SDL_AUDIO=$enableval], [WANT_SDL_AUDIO=yes]) AC_ARG_ENABLE(sdl-framework, [ --enable-sdl-framework use SDL framework [default=no]], [WANT_SDL_FRAMEWORK=$enableval], [WANT_SDL_FRAMEWORK=no]) AC_ARG_ENABLE(sdl-framework-prefix, [ --enable-sdl-framework-prefix=PFX default=/Library/Frameworks], [SDL_FRAMEWORK="$enableval"], [SDL_FRAMEWORK=/Library/Frameworks]) -AC_ARG_WITH(sdl1, [ --with-sdl1 use SDL 1.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=1], []) dnl Checks for programs. AC_PROG_CC @@ -181,65 +180,26 @@ if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then fi if [[ "x$WANT_SDL" = "xyes" ]]; then if [[ "x$WANT_SDL_FRAMEWORK" = "xyes" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=$WANT_SDL_VERSION_MAJOR - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=2 - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x2" ]]; then - AC_CHECK_SDLFRAMEWORK(SDL2, [#include ], [ - WANT_SDL_VERSION_MAJOR=2 - ], [ - TEMP_WANT_SDL_VERSION_MAJOR=1 - ]) - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x1" ]]; then - AC_CHECK_SDLFRAMEWORK(SDL, [#include ], [ - WANT_SDL_VERSION_MAJOR=1 - ]) - fi + AC_CHECK_SDLFRAMEWORK(SDL2, [#include ]) else ac_cv_framework_SDL=no fi if [[ "x$ac_cv_framework_SDL" = "xno" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=$WANT_SDL_VERSION_MAJOR - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x" ]]; then - TEMP_WANT_SDL_VERSION_MAJOR=2 - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x2" ]]; then - AC_PATH_PROG(sdl2_config, "sdl2-config") - if [[ -n "$sdl2_config" ]]; then - sdl2_cflags=`$sdl2_config --cflags` - if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then - sdl2_libs=`$sdl2_config --static-libs` - else - sdl2_libs=`$sdl2_config --libs` - fi - CFLAGS="$CFLAGS $sdl2_cflags" - CXXFLAGS="$CXXFLAGS $sdl2_cflags" - LIBS="$LIBS $sdl2_libs" - WANT_SDL_VERSION_MAJOR=2 - else - TEMP_WANT_SDL_VERSION_MAJOR=1 - fi - fi - if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x1" ]]; then - AC_PATH_PROG(sdl_config, "sdl-config") - if [[ -n "$sdl_config" ]]; then - sdl_cflags=`$sdl_config --cflags` - if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then - sdl_libs=`$sdl_config --static-libs` - else - sdl_libs=`$sdl_config --libs` - fi - CFLAGS="$CFLAGS $sdl_cflags" - CXXFLAGS="$CXXFLAGS $sdl_cflags" - LIBS="$LIBS $sdl_libs" - WANT_SDL_VERSION_MAJOR=1 + AC_PATH_PROG(sdl2_config, "sdl2-config") + if [[ -n "$sdl2_config" ]]; then + sdl2_cflags=`$sdl2_config --cflags` + if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then + sdl2_libs=`$sdl2_config --static-libs` else - WANT_SDL=no - WANT_SDL_VIDEO=no - WANT_SDL_AUDIO=no + sdl2_libs=`$sdl2_config --libs` fi + CFLAGS="$CFLAGS $sdl2_cflags" + CXXFLAGS="$CXXFLAGS $sdl2_cflags" + LIBS="$LIBS $sdl2_libs" + else + WANT_SDL=no + WANT_SDL_VIDEO=no + WANT_SDL_AUDIO=no fi fi SDL_SUPPORT=`echo "$SDL_SUPPORT" | sed -e "s/^ //"` @@ -663,7 +623,7 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then fi if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support.]) - VIDEOSRCS="../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp" + VIDEOSRCS="../SDL/video_sdl2.cpp" KEYCODES="../SDL/keycodes" if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then AC_MSG_CHECKING([whether __LP64__ is defined]) @@ -1658,7 +1618,6 @@ echo echo SheepShaver configuration summary: echo echo SDL support ...................... : $SDL_SUPPORT -echo SDL major-version ................ : $WANT_SDL_VERSION_MAJOR echo BINCUE support ................... : $have_bincue echo LIBVHD support ................... : $have_libvhd echo Using PowerPC emulator ........... : $EMULATED_PPC diff --git a/SheepShaver/src/Windows/Makefile.in b/SheepShaver/src/Windows/Makefile.in index 6e3fedaa5..9ca6f762d 100755 --- a/SheepShaver/src/Windows/Makefile.in +++ b/SheepShaver/src/Windows/Makefile.in @@ -70,7 +70,7 @@ SRCS = ../main.cpp main_windows.cpp ../prefs.cpp ../prefs_items.cpp prefs_window ../rom_patches.cpp ../rsrc_patches.cpp ../emul_op.cpp ../name_registry.cpp \ ../macos_util.cpp ../timer.cpp timer_windows.cpp ../xpram.cpp xpram_windows.cpp \ ../adb.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../dummy/scsi_dummy.cpp \ - ../gfxaccel.cpp ../video.cpp ../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp video_blit.cpp \ + ../gfxaccel.cpp ../video.cpp ../SDL/video_sdl2.cpp video_blit.cpp \ ../audio.cpp ../SDL/audio_sdl.cpp ../ether.cpp ether_windows.cpp \ ../thunks.cpp ../serial.cpp serial_windows.cpp ../extfs.cpp extfs_windows.cpp \ about_window_windows.cpp ../user_strings.cpp user_strings_windows.cpp \ From 7562d1df723eff96f954901257788d75e1d7ad71 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 18 Jun 2021 15:33:54 -0700 Subject: [PATCH 17/24] Remove debug asserts --- BasiliskII/src/SDL/video_sdl2.cpp | 1 - BasiliskII/src/uae_cpu/basilisk_glue.cpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BasiliskII/src/SDL/video_sdl2.cpp b/BasiliskII/src/SDL/video_sdl2.cpp index 7e3225f6e..453dc43e7 100644 --- a/BasiliskII/src/SDL/video_sdl2.cpp +++ b/BasiliskII/src/SDL/video_sdl2.cpp @@ -506,7 +506,6 @@ static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool nati MacFrameSize = VIDEO_MODE_ROW_BYTES * VIDEO_MODE_Y; memory_init(); #else - assert(Host2MacAddr(0)); monitor.set_mac_frame_base(Host2MacAddr(MacFrameBaseHost)); #endif D(bug("monitor.mac_frame_base = %08x\n", monitor.get_mac_frame_base())); diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index 680f15359..b39e7dbde 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -209,9 +209,10 @@ bool InitMacMem(void){ } void MacMemExit(void){ - assert(RAMBaseHost); + if(RAMBaseHost){ vm_release(RAMBaseHost, RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize); + } RAMBaseHost = NULL; ROMBaseHost = NULL; //Exit VM wrappers From 1f51b23925b2457f956842530bbd1c7132a1c7fd Mon Sep 17 00:00:00 2001 From: Seg Date: Thu, 17 Jun 2021 21:04:30 -0700 Subject: [PATCH 18/24] Add linux desktop metainfo and icon --- BasiliskII/src/Unix/Makefile.in | 17 ++++++++- BasiliskII/src/Unix/flatpak/BasiliskII128.png | Bin 0 -> 217 bytes BasiliskII/src/Unix/flatpak/BasiliskII64.png | Bin 0 -> 207 bytes .../Unix/flatpak/net.cebix.basilisk.desktop | 10 ++++++ .../flatpak/net.cebix.basilisk.metainfo.xml | 33 ++++++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 BasiliskII/src/Unix/flatpak/BasiliskII128.png create mode 100644 BasiliskII/src/Unix/flatpak/BasiliskII64.png create mode 100644 BasiliskII/src/Unix/flatpak/net.cebix.basilisk.desktop create mode 100644 BasiliskII/src/Unix/flatpak/net.cebix.basilisk.metainfo.xml diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 1b911c689..bc92f1c65 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -155,9 +155,24 @@ install: $(PROGS) installdirs $(INSTALL_DATA) @top_srcdir@/$(KEYCODES) $(DESTDIR)$(datadir)/$(APP)/keycodes $(INSTALL_DATA) @top_srcdir@/fbdevices $(DESTDIR)$(datadir)/$(APP)/fbdevices $(INSTALL_DATA) @top_srcdir@/tunconfig $(DESTDIR)$(datadir)/$(APP)/tunconfig + $(INSTALL_DATA) @top_srcdir@/flatpak/net.cebix.basilisk.metainfo.xml \ + $(DESTDIR)$(datadir)/metainfo/ + $(INSTALL_DATA) @top_srcdir@/flatpak/net.cebix.basilisk.desktop \ + $(DESTDIR)$(datadir)/applications/ + $(INSTALL_DATA) @top_srcdir@/flatpak/BasiliskII64.png \ + $(DESTDIR)$(datadir)/icons/hicolor/64x64/apps/net.cebix.basilisk.png + $(INSTALL_DATA) @top_srcdir@/flatpak/BasiliskII128.png \ + $(DESTDIR)$(datadir)/icons/hicolor/128x128/apps/net.cebix.basilisk.png installdirs: - $(SHELL) @top_srcdir@/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) $(DESTDIR)$(datadir)/$(APP) + $(SHELL) @top_srcdir@/mkinstalldirs \ + $(DESTDIR)$(bindir) \ + $(DESTDIR)$(man1dir) \ + $(DESTDIR)$(datadir)/$(APP) \ + $(DESTDIR)$(datadir)/metainfo \ + $(DESTDIR)$(datadir)/applications \ + $(DESTDIR)$(datadir)/icons/hicolor/64x64/apps \ + $(DESTDIR)$(datadir)/icons/hicolor/128x128/apps uninstall: rm -f $(DESTDIR)$(bindir)/$(APP)$(EXEEXT) diff --git a/BasiliskII/src/Unix/flatpak/BasiliskII128.png b/BasiliskII/src/Unix/flatpak/BasiliskII128.png new file mode 100644 index 0000000000000000000000000000000000000000..0aac0f1744433cb7944f5e2d6bc8e94ce9115163 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?K3?%mjbVdLv&H$ef*8>L*0GUA2M{i>nki}RM zYEfFN{a|i zWZUjt^}m_TRGm+d@y>3^X2y+69yVloUttzvEcHuG(0}Ef=G2yd!-*3i7hP=QBY*&&+{dztyg#ul|;OXk; Jvd$@?2>>^eN{0Xd literal 0 HcmV?d00001 diff --git a/BasiliskII/src/Unix/flatpak/BasiliskII64.png b/BasiliskII/src/Unix/flatpak/BasiliskII64.png new file mode 100644 index 0000000000000000000000000000000000000000..e46427f76842d3f1eb50b3a0d7156ce52df813b0 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSoB=)|u0R?H4jee(6qHp5WHFWm z`2{mLJiCzwvzbG(f1YE9Xri8mwst?`f + + net.cebix.basilisk + + Basilisk II + A 68k Macintosh emulator + + FSFAP + GPL-2.0-or-later + + +

+Basilisk II is an Open Source 68k Macintosh emulator. That is, it enables you to run 68k Mac OS software on you computer, even if you are using a different operating system. However, you still need a copy of Mac OS 7.x-8.1 and a Macintosh ROM image to use Basilisk II. +

+ + https://basilisk.cebix.net/ + + net.cebix.basilisk.desktop + + + + https://raw.githubusercontent.com/SegHaxx/flathub/new-pr/screenshots/1.png + + + + + + +

First Flathub release.

+
+
+
+
From bed233ca0c708f1a2e9ddd22616c78e35d6cb471 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 18 Jun 2021 19:46:43 -0700 Subject: [PATCH 19/24] Get version from git tag --- BasiliskII/src/Unix/configure.ac | 11 +-- BasiliskII/src/Unix/main_unix.cpp | 14 +-- BasiliskII/src/Unix/prefs_editor_gtk.cpp | 99 +++++---------------- BasiliskII/src/Windows/configure.ac | 8 +- BasiliskII/src/Windows/main_windows.cpp | 7 +- BasiliskII/src/Windows/prefs_editor_gtk.cpp | 71 +++++++-------- BasiliskII/src/include/user_strings.h | 3 +- BasiliskII/src/include/version.h | 9 +- BasiliskII/src/slot_rom.cpp | 6 +- BasiliskII/src/user_strings.cpp | 4 +- SheepShaver/src/Unix/configure.ac | 2 +- SheepShaver/src/Unix/main_unix.cpp | 3 +- SheepShaver/src/Unix/prefs_editor_gtk.cpp | 78 +++++++--------- SheepShaver/src/Windows/configure.ac | 2 +- SheepShaver/src/Windows/main_windows.cpp | 3 +- SheepShaver/src/include/user_strings.h | 3 +- SheepShaver/src/include/version.h | 7 +- SheepShaver/src/user_strings.cpp | 5 +- 18 files changed, 113 insertions(+), 222 deletions(-) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 28423e8c3..1057d2925 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -1,17 +1,13 @@ dnl Process this file with autoconf to produce a configure script. dnl Written in 2002 by Christian Bauer et al. -AC_INIT([Basilisk II], 1.0, [Christian.Bauer@uni-mainz.de], BasiliskII) +AC_INIT([Basilisk II], [m4_esyscmd_s([git describe --always --tags --dirty])]) AC_CONFIG_SRCDIR(main_unix.cpp) AC_PREREQ(2.52) AC_CONFIG_HEADER(config.h) AC_USE_SYSTEM_EXTENSIONS -dnl Aliases for PACKAGE and VERSION macros. -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE_NAME", [Define this program name.]) -AC_DEFINE_UNQUOTED(VERSION, "$PACKAGE_VERSION", [Define this program version.]) - dnl Some systems do not put corefiles in the currect directory, avoid saving dnl cores for the configure tests since some are intended to dump core. ulimit -c 0 @@ -385,11 +381,6 @@ if [[ "x$WANT_GTK" = "xgtk" ]]; then AM_PATH_GTK(1.2.0, [ GUI_CFLAGS="$GTK_CFLAGS" GUI_LIBS="$GTK_LIBS" - B2_PATH_GNOMEUI([ - AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.]) - GUI_CFLAGS="$GUI_CFLAGS $GNOMEUI_CFLAGS" - GUI_LIBS="$GUI_LIBS $GNOMEUI_LIBS" - ], []) ], [ AC_MSG_WARN([Could not find GTK+, disabling user interface.]) WANT_GTK=no diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 0b2cbcad2..9b3d2f0d9 100755 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -42,9 +42,6 @@ #ifdef ENABLE_GTK # include # include -# ifdef HAVE_GNOMEUI -# include -# endif # if !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND) # include # endif @@ -293,8 +290,7 @@ int main(int argc, char **argv){ tzset(); // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); + printf(GetString(STR_ABOUT_TEXT)); // Parse command line arguments for (int i=1; i #include -#ifdef HAVE_GNOMEUI -#include -#endif - #include "user_strings.h" #include "version.h" #include "cdrom.h" @@ -42,12 +38,10 @@ #define DEBUG 0 #include "debug.h" - // Global variables static GtkWidget *win; // Preferences window static bool start_clicked = false; // Return value of PrefsEditor() function - // Prototypes static void create_volumes_pane(GtkWidget *top); static void create_scsi_pane(GtkWidget *top); @@ -58,7 +52,6 @@ static void create_memory_pane(GtkWidget *top); static void create_jit_pane(GtkWidget *top); static void read_settings(void); - /* * Utility functions */ @@ -400,79 +393,36 @@ static void dl_quit(GtkWidget *dialog) } // "About" selected -static void mn_about(...) -{ - GtkWidget *dialog; - -#ifdef HAVE_GNOMEUI - - char version[32]; - sprintf(version, "Version %d.%d", VERSION_MAJOR, VERSION_MINOR); - const char *authors[] = { - "Christian Bauer", +static void mn_about(...){ + const gchar* authors[] = { + "Christian Bauer ", "Orlando Bassotto", - "Gwenolé Beauchesne", + "Gwenolé Beauchesne", "Marc Chabanas", "Marc Hellwig", "Biill Huey", "Brian J. Johnson", - "Jürgen Lachmann", + "Jürgen Lachmann", "Samuel Lander", "David Lawrence", "Lauri Pesonen", "Bernd Schmidt", + "Callum Lerwick ", "and others", NULL }; - dialog = gnome_about_new( - "Basilisk II", - version, - "Copyright (C) 1997-2008 Christian Bauer", - authors, - "Basilisk II comes with ABSOLUTELY NO WARRANTY." - "This is free software, and you are welcome to redistribute it" - "under the terms of the GNU General Public License.", + gtk_show_about_dialog(GTK_WINDOW(win), + "version", VERSION_STRING, + "copyright", "Copyright (C) 1997-2008 Christian Bauer et al.", + "website", "http://basilisk.cebix.net/", + "authors", authors, + "license", + "Basilisk II comes with ABSOLUTELY NO WARRANTY.\n\n" + "This is free software, and you are welcome to redistribute it " + "under the terms of the GNU General Public License.", + "wrap-license", true, NULL ); - gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(win)); - -#else - - GtkWidget *label, *button; - - char str[512]; - sprintf(str, - "Basilisk II\nVersion %d.%d\n\n" - "Copyright (C) 1997-2008 Christian Bauer et al.\n" - "E-mail: Christian.Bauer@uni-mainz.de\n" - "http://www.uni-mainz.de/~bauec002/B2Main.html\n\n" - "Basilisk II comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR - ); - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - - label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - button = gtk_button_new_with_label(GetString(STR_OK_BUTTON)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - -#endif - - gtk_widget_show(dialog); } // "Zap PRAM" selected @@ -492,8 +442,7 @@ static GtkItemFactoryEntry menu_items[] = { {(gchar *)GetString(STR_HELP_ITEM_ABOUT_GTK), NULL, GTK_SIGNAL_FUNC(mn_about), 0, NULL} }; -bool PrefsEditor(void) -{ +bool PrefsEditor(void){ // Create window win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE)); @@ -524,12 +473,12 @@ bool PrefsEditor(void) gtk_widget_realize(notebook); create_volumes_pane(notebook); - create_scsi_pane(notebook); create_graphics_pane(notebook); create_input_pane(notebook); create_serial_pane(notebook); create_memory_pane(notebook); create_jit_pane(notebook); + //create_scsi_pane(notebook); gtk_widget_show(notebook); static const opt_desc buttons[] = { @@ -1647,23 +1596,15 @@ static void sigchld_handler(int sig, siginfo_t *sip, void *) } } - /* * Start standalone GUI */ -int main(int argc, char *argv[]) -{ -#ifdef HAVE_GNOMEUI - // Init GNOME/GTK - char version[16]; - sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR); - gnome_init("Basilisk II", version, argc, argv); -#else +int main(int argc, char *argv[]){ // Init GTK gtk_set_locale(); gtk_init(&argc, &argv); -#endif + g_set_application_name("Basilisk II"); // Read preferences PrefsInit(NULL, argc, argv); diff --git a/BasiliskII/src/Windows/configure.ac b/BasiliskII/src/Windows/configure.ac index 88adb1bd5..20e11eedc 100755 --- a/BasiliskII/src/Windows/configure.ac +++ b/BasiliskII/src/Windows/configure.ac @@ -1,16 +1,12 @@ dnl Process this file with autoconf to produce a configure script. dnl Written in 2002 by Christian Bauer et al. -AC_INIT([Basilisk II], 1.0, [Christian.Bauer@uni-mainz.de], BasiliskII) +AC_INIT([Basilisk II], [m4_esyscmd_s([git describe --always --tags --dirty])]) AC_CONFIG_SRCDIR(main_windows.cpp) AC_CONFIG_AUX_DIR(../Unix) AC_PREREQ(2.52) AC_CONFIG_HEADER(config.h) -dnl Aliases for PACKAGE and VERSION macros. -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE_NAME", [Define this program name.]) -AC_DEFINE_UNQUOTED(VERSION, "$PACKAGE_VERSION", [Define this program version.]) - dnl SDL options. #AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no]) @@ -78,7 +74,7 @@ AC_CHECK_TOOL(WINDRES, windres) dnl We use GTK+ if possible. if [[ "x$WANT_GTK" = "xyes" ]]; then - AM_PATH_GTK_2_0(1.3.15, [], [ + AM_PATH_GTK_2_0(2.6.0, [], [ AC_MSG_WARN([Could not find GTK+ 2.0, disabling user interface.]) WANT_GTK=no ]) diff --git a/BasiliskII/src/Windows/main_windows.cpp b/BasiliskII/src/Windows/main_windows.cpp index ca242d81d..ec34daa18 100755 --- a/BasiliskII/src/Windows/main_windows.cpp +++ b/BasiliskII/src/Windows/main_windows.cpp @@ -48,10 +48,6 @@ typedef std::basic_string tstring; #include "sigsegv.h" #include "util_windows.h" -#if USE_JIT -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif - #ifdef ENABLE_MON # include "mon.h" #endif @@ -180,8 +176,7 @@ int main(int argc, char **argv){ tzset(); // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); + printf(GetString(STR_ABOUT_TEXT)); // Parse command line arguments for (int i=1; i", + "Orlando Bassotto", + "Gwenolé Beauchesne", + "Marc Chabanas", + "Marc Hellwig", + "Biill Huey", + "Brian J. Johnson", + "Jürgen Lachmann", + "Samuel Lander", + "David Lawrence", + "Lauri Pesonen", + "Bernd Schmidt", + "Callum Lerwick ", + "and others", + NULL + }; + gtk_show_about_dialog(GTK_WINDOW(win), + "version", VERSION_STRING, + "copyright", "Copyright (C) 1997-2008 Christian Bauer et al.", #ifdef SHEEPSHAVER - "http://sheepshaver.cebix.net/\n\n" + "website", "http://sheepshaver.cebix.net/", #else - "http://basilisk.cebix.net/\n\n" + "website", "http://basilisk.cebix.net/", #endif - PROGRAM_NAME " comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR + "authors", authors, + "license", + PACKAGE_NAME " comes with ABSOLUTELY NO WARRANTY.\n\n" + "This is free software, and you are welcome to redistribute it " + "under the terms of the GNU General Public License.", + "wrap-license", true, + NULL ); - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - - label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - button = gtk_button_new_with_label(GetString(STR_OK_BUTTON)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - - gtk_widget_show(dialog); } // Menu item descriptions @@ -1905,11 +1898,11 @@ void WarningAlert(const wchar_t *text) * Start standalone GUI */ -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]){ // Init GTK gtk_set_locale(); gtk_init(&argc, &argv); + g_set_application_name(PACKAGE_NAME); // Read preferences PrefsInit(NULL, argc, argv); diff --git a/BasiliskII/src/include/user_strings.h b/BasiliskII/src/include/user_strings.h index f75a738ed..1e4fd0d30 100644 --- a/BasiliskII/src/include/user_strings.h +++ b/BasiliskII/src/include/user_strings.h @@ -24,8 +24,7 @@ // Common string numbers enum { // General messages - STR_ABOUT_TEXT1 = 0, - STR_ABOUT_TEXT2, + STR_ABOUT_TEXT = 0, STR_READING_ROM_FILE, STR_SHELL_ERROR_PREFIX, STR_GUI_ERROR_PREFIX, diff --git a/BasiliskII/src/include/version.h b/BasiliskII/src/include/version.h index 79ba3196d..fd07bb564 100644 --- a/BasiliskII/src/include/version.h +++ b/BasiliskII/src/include/version.h @@ -21,9 +21,10 @@ #ifndef VERSION_H #define VERSION_H -const int VERSION_MAJOR = 1; -const int VERSION_MINOR = 1; - -#define VERSION_STRING "Basilisk II V1.0 SDL2" +#ifdef PACKAGE_VERSION // from config.h +#define VERSION_STRING PACKAGE_VERSION +#else +#define VERSION_STRING "1.0" +#endif #endif diff --git a/BasiliskII/src/slot_rom.cpp b/BasiliskII/src/slot_rom.cpp index d46d03298..9da179e95 100644 --- a/BasiliskII/src/slot_rom.cpp +++ b/BasiliskII/src/slot_rom.cpp @@ -32,10 +32,8 @@ #include "main.h" #include "video.h" #include "emul_op.h" -#include "version.h" #include "slot_rom.h" - // Temporary buffer for slot ROM static uint8 srom[4096]; @@ -243,7 +241,6 @@ bool InstallSlotROM(void) vector::const_iterator m, mend = VideoMonitors.end(); vector sRsrcVideo; - char str[256]; int i; p = 0; @@ -255,8 +252,7 @@ bool InstallSlotROM(void) vendorID = p; String("Christian Bauer"); revLevel = p; - sprintf(str, "V%d.%d", VERSION_MAJOR, VERSION_MINOR); - String(str); + String("V1.0"); partNum = p; String("BasiliskII"); date = p; diff --git a/BasiliskII/src/user_strings.cpp b/BasiliskII/src/user_strings.cpp index d15cf01d9..2c813157c 100644 --- a/BasiliskII/src/user_strings.cpp +++ b/BasiliskII/src/user_strings.cpp @@ -35,11 +35,11 @@ #define ELLIPSIS "..." +#include "version.h" // Common string definitions user_string_def common_strings[] = { - {STR_ABOUT_TEXT1, "Basilisk II V%d.%d"}, - {STR_ABOUT_TEXT2, "by Christian Bauer et al."}, + {STR_ABOUT_TEXT, "Basilisk II V" VERSION_STRING " by Christian Bauer et al.\n"}, {STR_READING_ROM_FILE, "Reading ROM file...\n"}, {STR_SHELL_ERROR_PREFIX, "ERROR: %s\n"}, {STR_GUI_ERROR_PREFIX, "Basilisk II error:\n%s"}, diff --git a/SheepShaver/src/Unix/configure.ac b/SheepShaver/src/Unix/configure.ac index d3da4317f..33dc2666c 100755 --- a/SheepShaver/src/Unix/configure.ac +++ b/SheepShaver/src/Unix/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. dnl Written in 2002 by Christian Bauer -AC_INIT([SheepShaver], 2.4, [Christian.Bauer@uni-mainz.de], SheepShaver) +AC_INIT([SheepShaver], [m4_esyscmd_s([git describe --always --tags --dirty])]) AC_CONFIG_SRCDIR(main_unix.cpp) AC_PREREQ(2.52) AC_CONFIG_HEADER(config.h) diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index f521d5e93..178c9f75e 100755 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -715,8 +715,7 @@ int main(int argc, char **argv){ tzset(); // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); + printf(GetString(STR_ABOUT_TEXT)); #if !EMULATED_PPC #ifdef SYSTEM_CLOBBERS_R2 diff --git a/SheepShaver/src/Unix/prefs_editor_gtk.cpp b/SheepShaver/src/Unix/prefs_editor_gtk.cpp index 81b16f14b..828cc8649 100644 --- a/SheepShaver/src/Unix/prefs_editor_gtk.cpp +++ b/SheepShaver/src/Unix/prefs_editor_gtk.cpp @@ -365,40 +365,40 @@ static void dl_quit(GtkWidget *dialog) } // "About" selected -static void mn_about(...) -{ - GtkWidget *dialog, *label, *button; - - char str[512]; - sprintf(str, - "SheepShaver\nVersion %d.%d\n\n" - "Copyright (C) 1997-2008 Christian Bauer and Marc Hellwig\n" - "E-mail: cb@cebix.net\n" - "http://sheepshaver.cebix.net/\n\n" - "SheepShaver comes with ABSOLUTELY NO\n" - "WARRANTY. This is free software, and\n" - "you are welcome to redistribute it\n" - "under the terms of the GNU General\n" - "Public License.\n", - VERSION_MAJOR, VERSION_MINOR +static void mn_about(...){ + const gchar* authors[] = { + "Christian Bauer ", + "Orlando Bassotto", + "Gwenolé Beauchesne", + "Marc Chabanas", + "Marc Hellwig", + "Biill Huey", + "Brian J. Johnson", + "Jürgen Lachmann", + "Samuel Lander", + "David Lawrence", + "Lauri Pesonen", + "Bernd Schmidt", + "Callum Lerwick ", + "and others", + NULL + }; + gtk_show_about_dialog(GTK_WINDOW(win), + "version", VERSION_STRING, + "copyright", "Copyright (C) 1997-2008 Christian Bauer et al.", +#ifdef SHEEPSHAVER + "website", "http://sheepshaver.cebix.net/", +#else + "website", "http://basilisk.cebix.net/", +#endif + "authors", authors, + "license", + PACKAGE_NAME " comes with ABSOLUTELY NO WARRANTY.\n\n" + "This is free software, and you are welcome to redistribute it " + "under the terms of the GNU General Public License.", + "wrap-license", true, + NULL ); - - dialog = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(dialog), GetString(STR_ABOUT_TITLE)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - - label = gtk_label_new(str); - gtk_widget_show(label); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); - - button = gtk_button_new_with_label(GetString(STR_OK_BUTTON)); - gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_widget_grab_default(button); - gtk_widget_show(dialog); } // "Zap NVRAM" selected @@ -712,8 +712,6 @@ static GtkWidget *l_frameskip, *l_display_x, *l_display_y; static int display_type; static int dis_width, dis_height; -static GtkWidget *w_dspdevice_file, *w_mixerdevice_file; - // Hide/show graphics widgets static void hide_show_graphics_widgets(void) { @@ -756,11 +754,8 @@ static void tb_gfxaccel(GtkWidget *widget) } // Set sensitivity of widgets -static void set_graphics_sensitive(void) -{ +static void set_graphics_sensitive(void){ const bool sound_enabled = !PrefsFindBool("nosound"); - gtk_widget_set_sensitive(w_dspdevice_file, sound_enabled); - gtk_widget_set_sensitive(w_mixerdevice_file, sound_enabled); } // "Disable Sound Output" button toggled @@ -857,9 +852,6 @@ static void read_graphics_settings(void) PrefsRemoveItem("windowmodes"); PrefsRemoveItem("screenmodes"); } - - PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file)); - PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file)); } // Create "Graphics/Sound" pane @@ -968,8 +960,6 @@ static void create_graphics_pane(GtkWidget *top) make_separator(box); make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound)); - w_dspdevice_file = make_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp"); - w_mixerdevice_file = make_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer"); set_graphics_sensitive(); diff --git a/SheepShaver/src/Windows/configure.ac b/SheepShaver/src/Windows/configure.ac index b5347be27..b45dc2876 100644 --- a/SheepShaver/src/Windows/configure.ac +++ b/SheepShaver/src/Windows/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. dnl Written in 2002 by Christian Bauer -AC_INIT([SheepShaver], 2.3, [Christian.Bauer@uni-mainz.de], SheepShaver) +AC_INIT([SheepShaver], [m4_esyscmd_s([git describe --always --tags --dirty])]) AC_CONFIG_SRCDIR(main_windows.cpp) AC_CONFIG_AUX_DIR(../Unix) AC_PREREQ(2.52) diff --git a/SheepShaver/src/Windows/main_windows.cpp b/SheepShaver/src/Windows/main_windows.cpp index febc22184..c9cb4a6f2 100755 --- a/SheepShaver/src/Windows/main_windows.cpp +++ b/SheepShaver/src/Windows/main_windows.cpp @@ -165,8 +165,7 @@ int main(int argc, char **argv){ uint8 *rom_tmp; // Print some info - printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); - printf(" %s\n", GetString(STR_ABOUT_TEXT2)); + printf(GetString(STR_ABOUT_TEXT)); // Read preferences PrefsInit(NULL, argc, argv); diff --git a/SheepShaver/src/include/user_strings.h b/SheepShaver/src/include/user_strings.h index 5a4f4048c..219f47bbb 100644 --- a/SheepShaver/src/include/user_strings.h +++ b/SheepShaver/src/include/user_strings.h @@ -24,8 +24,7 @@ // Common string numbers enum { // General messages - STR_ABOUT_TEXT1 = 0, - STR_ABOUT_TEXT2, + STR_ABOUT_TEXT = 0, STR_READING_ROM_FILE, STR_SHELL_ERROR_PREFIX, STR_GUI_ERROR_PREFIX, diff --git a/SheepShaver/src/include/version.h b/SheepShaver/src/include/version.h index 4b63bfd36..c179be170 100644 --- a/SheepShaver/src/include/version.h +++ b/SheepShaver/src/include/version.h @@ -21,7 +21,10 @@ #ifndef VERSION_H #define VERSION_H -const int VERSION_MAJOR = 2; -const int VERSION_MINOR = 5; +#ifdef PACKAGE_VERSION // from config.h +#define VERSION_STRING PACKAGE_VERSION +#else +#define VERSION_STRING "2.5" +#endif #endif diff --git a/SheepShaver/src/user_strings.cpp b/SheepShaver/src/user_strings.cpp index d88025cd0..d54f335c4 100644 --- a/SheepShaver/src/user_strings.cpp +++ b/SheepShaver/src/user_strings.cpp @@ -32,14 +32,13 @@ #include "sysdeps.h" #include "user_strings.h" +#include "version.h" #define ELLIPSIS "..." - // Common string definitions user_string_def common_strings[] = { - {STR_ABOUT_TEXT1, "SheepShaver V%d.%d"}, - {STR_ABOUT_TEXT2, "by Christian Bauer and Mar\"c\" Hellwig"}, + {STR_ABOUT_TEXT, "SheepShaver V" VERSION_STRING " by Christian Bauer and Mar\"c\" Hellwig\n"}, {STR_READING_ROM_FILE, "Reading ROM file...\n"}, {STR_SHELL_ERROR_PREFIX, "ERROR: %s\n"}, {STR_GUI_ERROR_PREFIX, "SheepShaver error:\n%s"}, From add845a57deea2c8ea7b6303bb2cd18f1180a40d Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 18 Jun 2021 18:41:28 -0700 Subject: [PATCH 20/24] Remove GTK1 support --- BasiliskII/src/Unix/configure.ac | 42 ++------- BasiliskII/src/Unix/main_unix.cpp | 12 +-- BasiliskII/src/Unix/prefs_editor_gtk.cpp | 105 ++++++++--------------- 3 files changed, 48 insertions(+), 111 deletions(-) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 1057d2925..77219b5b7 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -1,6 +1,3 @@ -dnl Process this file with autoconf to produce a configure script. -dnl Written in 2002 by Christian Bauer et al. - AC_INIT([Basilisk II], [m4_esyscmd_s([git describe --always --tags --dirty])]) AC_CONFIG_SRCDIR(main_unix.cpp) AC_PREREQ(2.52) @@ -63,14 +60,7 @@ AC_ARG_ENABLE(addressing, ]) dnl External packages. -AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], - [case "$withval" in - gtk1) WANT_GTK="gtk";; - gtk|gtk2) WANT_GTK="$withval";; - yes) WANT_GTK="gtk2 gtk";; - *) WANT_GTK="no";; - esac], - [WANT_GTK="gtk2 gtk"]) +AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes]) AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=no]], [WANT_MON=$withval], [WANT_MON=no]) AC_ARG_WITH(bincue, @@ -357,32 +347,14 @@ AC_CHECK_FUNCS(sem_init, , [ dnl We use GTK+ if possible. UISRCS=../dummy/prefs_editor_dummy.cpp -case "x$WANT_GTK" in -xgtk2*) - AM_PATH_GTK_2_0(1.3.15, [ - GUI_CFLAGS="$GTK_CFLAGS" - GUI_LIBS="$GTK_LIBS" - WANT_GTK=gtk2 - ], [ - case "x${WANT_GTK}x" in - *gtkx) - AC_MSG_WARN([Could not find GTK+ 2.0, trying with GTK+ 1.2.]) - WANT_GTK=gtk - ;; - *) - AC_MSG_WARN([Could not find GTK+, disabling user interface.]) - WANT_GTK=no - ;; - esac - ]) - ;; -esac -if [[ "x$WANT_GTK" = "xgtk" ]]; then - AM_PATH_GTK(1.2.0, [ - GUI_CFLAGS="$GTK_CFLAGS" +if [[ "x$WANT_GTK" = "xyes" ]]; then + AM_PATH_GTK_2_0(2.6.0, [ + GUI_CFLAGS="$GTK_CFLAGS -DGTK_DISABLE_SINGLE_INCLUDES" + GUI_CFLAGS="$GUI_CFLAGS -DGDK_DISABLE_DEPRECATED" + #GUI_CFLAGS="$GUI_CFLAGS -DGTK_DISABLE_DEPRECATED" GUI_LIBS="$GTK_LIBS" ], [ - AC_MSG_WARN([Could not find GTK+, disabling user interface.]) + AC_MSG_WARN([Could not find GTK+ 2.x, disabling user interface.]) WANT_GTK=no ]) fi diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 9b3d2f0d9..a041e4091 100755 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -375,7 +375,6 @@ int main(int argc, char **argv){ #ifdef ENABLE_GTK if (!gui_connection) { // Init GTK - gtk_set_locale(); gtk_init(&argc, &argv); g_set_application_name("Basilisk II"); } @@ -863,16 +862,13 @@ static void dl_quit(GtkWidget *dialog) gtk_widget_destroy(dialog); } -void display_alert(int title_id, int prefix_id, int button_id, const char *text) -{ +void display_alert(int title_id, int prefix_id, int button_id, const char *text){ char str[256]; sprintf(str, GetString(prefix_id), text); GtkWidget *dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id)); - gtk_container_border_width(GTK_CONTAINER(dialog), 5); - gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL); + g_signal_connect(GTK_OBJECT(dialog), "destroy", G_CALLBACK(dl_destroyed), NULL); GtkWidget *label = gtk_label_new(str); gtk_widget_show(label); @@ -880,9 +876,9 @@ void display_alert(int title_id, int prefix_id, int button_id, const char *text) GtkWidget *button = gtk_button_new_with_label(GetString(button_id)); gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); + g_signal_connect_swapped(GTK_OBJECT(button), "clicked", G_CALLBACK(dl_quit), GTK_OBJECT(dialog)); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_widget_set_can_default(button,true); gtk_widget_grab_default(button); gtk_widget_show(dialog); diff --git a/BasiliskII/src/Unix/prefs_editor_gtk.cpp b/BasiliskII/src/Unix/prefs_editor_gtk.cpp index a90dd4d0c..4f2d837b8 100644 --- a/BasiliskII/src/Unix/prefs_editor_gtk.cpp +++ b/BasiliskII/src/Unix/prefs_editor_gtk.cpp @@ -64,7 +64,7 @@ static void read_settings(void); struct opt_desc { int label_id; - GtkSignalFunc func; + GCallback func; }; struct combo_desc { @@ -77,39 +77,35 @@ struct file_req_assoc { GtkWidget *entry; }; -static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc) -{ +static void cb_browse_ok(GtkWidget *button, file_req_assoc *assoc){ gchar *file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); gtk_entry_set_text(GTK_ENTRY(assoc->entry), file); gtk_widget_destroy(assoc->req); delete assoc; } -static void cb_browse(GtkWidget *widget, void *user_data) -{ +static void cb_browse(GtkWidget *widget, void *user_data){ GtkWidget *req = gtk_file_selection_new(GetString(STR_BROWSE_TITLE)); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + g_signal_connect_swapped(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(cb_browse_ok), new file_req_assoc(req, (GtkWidget *)user_data)); + g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); gtk_widget_show(req); } -static GtkWidget *make_browse_button(GtkWidget *entry) -{ +static GtkWidget *make_browse_button(GtkWidget *entry){ GtkWidget *button; button = gtk_button_new_with_label(GetString(STR_BROWSE_CTRL)); gtk_widget_show(button); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc)cb_browse, (void *)entry); + g_signal_connect(GTK_OBJECT(button), "clicked", (GCallback)cb_browse, (void *)entry); return button; } -static void add_menu_item(GtkWidget *menu, int label_id, GtkSignalFunc func) -{ +static void add_menu_item(GtkWidget *menu, int label_id, GCallback func){ GtkWidget *item = gtk_menu_item_new_with_label(GetString(label_id)); gtk_widget_show(item); - gtk_signal_connect(GTK_OBJECT(item), "activate", func, NULL); - gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", func, NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } static GtkWidget *make_pane(GtkWidget *notebook, int title_id) @@ -130,8 +126,7 @@ static GtkWidget *make_pane(GtkWidget *notebook, int title_id) return box; } -static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons) -{ +static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *buttons){ GtkWidget *bb, *button; bb = gtk_hbutton_box_new(); @@ -144,7 +139,7 @@ static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *bu while (buttons->label_id) { button = gtk_button_new_with_label(GetString(buttons->label_id)); gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL); + g_signal_connect_swapped(GTK_OBJECT(button), "clicked", buttons->func, NULL); gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0); buttons++; } @@ -167,8 +162,7 @@ static GtkWidget *make_table(GtkWidget *top, int x, int y) return table; } -static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active) -{ +static GtkWidget *table_make_option_menu(GtkWidget *table, int row, int label_id, const opt_desc *options, int active){ GtkWidget *label, *opt, *menu; label = gtk_label_new(GetString(label_id)); @@ -273,8 +267,7 @@ static GtkWidget *make_option_menu(GtkWidget *top, int label_id, const opt_desc return menu; } -static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false) -{ +static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *prefs_item, bool only_dirs = false){ GtkWidget *box, *label, *entry; box = gtk_hbox_new(FALSE, 4); @@ -289,35 +282,23 @@ static GtkWidget *make_file_entry(GtkWidget *top, int label_id, const char *pref if (str == NULL) str = ""; -#ifdef HAVE_GNOMEUI - entry = gnome_file_entry_new(NULL, GetString(label_id)); - if (only_dirs) - gnome_file_entry_set_directory(GNOME_FILE_ENTRY(entry), true); - gtk_entry_set_text(GTK_ENTRY(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(entry))), str); -#else entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), str); -#endif gtk_widget_show(entry); gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); return entry; } -static const gchar *get_file_entry_path(GtkWidget *entry) -{ -#ifdef HAVE_GNOMEUI - return gnome_file_entry_get_full_path(GNOME_FILE_ENTRY(entry), false); -#else +static const gchar *get_file_entry_path(GtkWidget *entry){ return gtk_entry_get_text(GTK_ENTRY(entry)); -#endif } -static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GtkSignalFunc func) +static GtkWidget *make_checkbox(GtkWidget *top, int label_id, const char *prefs_item, GCallback func) { GtkWidget *button = gtk_check_button_new_with_label(GetString(label_id)); gtk_widget_show(button); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), PrefsFindBool(prefs_item)); - gtk_signal_connect(GTK_OBJECT(button), "toggled", func, button); + g_signal_connect(GTK_OBJECT(button), "toggled", func, button); gtk_box_pack_start(GTK_BOX(top), button, FALSE, FALSE, 0); return button; } @@ -446,8 +427,8 @@ bool PrefsEditor(void){ // Create window win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE)); - gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL); - gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL); + g_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL); + g_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL); // Create window contents GtkWidget *box = gtk_vbox_new(FALSE, 4); @@ -457,11 +438,7 @@ bool PrefsEditor(void){ GtkAccelGroup *accel_group = gtk_accel_group_new(); GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "
", accel_group); gtk_item_factory_create_items(item_factory, sizeof(menu_items) / sizeof(menu_items[0]), menu_items, NULL); -#if GTK_CHECK_VERSION(1,3,15) gtk_window_add_accel_group(GTK_WINDOW(win), accel_group); -#else - gtk_accel_group_attach(accel_group, GTK_OBJECT(win)); -#endif GtkWidget *menu_bar = gtk_item_factory_get_widget(item_factory, "
"); gtk_widget_show(menu_bar); gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0); @@ -509,8 +486,7 @@ static void cl_selected(GtkWidget *list, int row, int column) } // Volume selected for addition -static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc) -{ +static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc){ gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); gtk_clist_append(GTK_CLIST(volume_list), &file); gtk_widget_destroy(assoc->req); @@ -518,8 +494,7 @@ static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc) } // Volume selected for creation -static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc) -{ +static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc){ gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req)); const gchar *str = gtk_entry_get_text(GTK_ENTRY(assoc->entry)); @@ -535,18 +510,16 @@ static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc) } // "Add Volume" button clicked -static void cb_add_volume(...) -{ +static void cb_add_volume(...){ GtkWidget *req = gtk_file_selection_new(GetString(STR_ADD_VOLUME_TITLE)); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + g_signal_connect_swapped(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(add_volume_ok), new file_req_assoc(req, NULL)); + g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); gtk_widget_show(req); } // "Create Hardfile" button clicked -static void cb_create_volume(...) -{ +static void cb_create_volume(...){ GtkWidget *req = gtk_file_selection_new(GetString(STR_CREATE_VOLUME_TITLE)); GtkWidget *box = gtk_hbox_new(FALSE, 4); @@ -562,15 +535,14 @@ static void cb_create_volume(...) gtk_box_pack_start(GTK_BOX(box), entry, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(req)->main_vbox), box, FALSE, FALSE, 0); - gtk_signal_connect_object(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry)); - gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + g_signal_connect_swapped(GTK_OBJECT(req), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(req)->ok_button), "clicked", GTK_SIGNAL_FUNC(create_volume_ok), new file_req_assoc(req, entry)); + g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(req)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(req)); gtk_widget_show(req); } // "Remove Volume" button clicked -static void cb_remove_volume(...) -{ +static void cb_remove_volume(...){ gtk_clist_remove(GTK_CLIST(volume_list), selected_volume); } @@ -579,14 +551,12 @@ static void mn_boot_any(...) {PrefsReplaceInt32("bootdriver", 0);} static void mn_boot_cdrom(...) {PrefsReplaceInt32("bootdriver", CDROMRefNum);} // "No CD-ROM Driver" button toggled -static void tb_nocdrom(GtkWidget *widget) -{ +static void tb_nocdrom(GtkWidget *widget){ PrefsReplaceBool("nocdrom", GTK_TOGGLE_BUTTON(widget)->active); } // Read settings from widgets and set preferences -static void read_volumes_settings(void) -{ +static void read_volumes_settings(void){ while (PrefsFindString("disk")) PrefsRemoveItem("disk"); @@ -600,8 +570,7 @@ static void read_volumes_settings(void) } // Create "Volumes" pane -static void create_volumes_pane(GtkWidget *top) -{ +static void create_volumes_pane(GtkWidget *top){ GtkWidget *box, *scroll; box = make_pane(top, STR_VOLUMES_PANE_TITLE); @@ -614,7 +583,7 @@ static void create_volumes_pane(GtkWidget *top) gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE); gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE); gtk_clist_set_reorderable(GTK_CLIST(volume_list), true); - gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL); + g_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL); char *str; int32 index = 0; while ((str = const_cast(PrefsFindString("disk", index++))) != NULL) @@ -1479,7 +1448,7 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id)); gtk_container_border_width(GTK_CONTAINER(dialog), 5); gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150); - gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL); + g_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL); GtkWidget *label = gtk_label_new(str); gtk_widget_show(label); @@ -1487,7 +1456,7 @@ static void display_alert(int title_id, int prefix_id, int button_id, const char GtkWidget *button = gtk_button_new_with_label(GetString(button_id)); gtk_widget_show(button); - gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); + g_signal_connect_swapped(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog)); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); gtk_widget_grab_default(button); From d715aa8328b050eb122d01387e8a767cbfcab9e1 Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 19 Jun 2021 13:18:05 -0700 Subject: [PATCH 21/24] Use new icon --- BasiliskII/src/Unix/flatpak/BasiliskII128.png | Bin 217 -> 14629 bytes BasiliskII/src/Unix/flatpak/BasiliskII64.png | Bin 207 -> 5026 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/BasiliskII/src/Unix/flatpak/BasiliskII128.png b/BasiliskII/src/Unix/flatpak/BasiliskII128.png index 0aac0f1744433cb7944f5e2d6bc8e94ce9115163..5cccc26b1694b10f07059a95875994e7ca95fca2 100644 GIT binary patch literal 14629 zcmV+=IoigFP)6bAW*hWl3VVAY>*ugO8wr%MR|n$AWA77i zv2OqoHv5Md3vOedzslaPHC{sNNd*A&5>&FmevQ37116Uj9qj-8>{o5{-{5AVn{}6*DHp##5M@2V zApnF)hVT)`+4mb*f0F&}5o0AL5U7Rh&*wlNQ#(C68ZmkD8hVW9!tGMzg+`ocx|1}x@6nQB4>gT4!2fl7M z%_>gxa@I>&_ecU0QHSJw#N^yKq(sP)uMUlYO!+>@dOPdQ{2FH5fxq3l8MptTeQYGc z@Bp|BPcd=yew-^2tvJcrjS*NC=4g)eDEHAjq{w{@c&iC3o{8gwe?0(OOTcFKGisQI zEuNK?Wp;ISCEj=S)mJ;5&gZO`%rnDyAhc>vRb+5FCwz@0yiIa%y98NS5}rxJa1^GK z{oQ8gYC)(5A6HnUEK;VW0*YP!zKQjNZ0J!8KHrZoPoIgOcQH_$_vDCY@wfo+7MqhL zcn|xBR~wivR!6Gk#{vMxFt0igY;scTfIGM2qd#fHbCPFcHk&Q#^?D;d*7Ngn;$2p~{oRW|e?YE!9U%N)RQvNG6dX##H$w=&(r^F8ef8$|S9K*? zB{Y;ZkRyTSk%HgBc*$GkMcJn-aK*>VaY24IBR7Fyil$1H;Yg}sH#fKOWE)=k{C?x+ zE2sHFO+$9m>CTF-*xH&H3mf21Y=S??WPlicG{Y~AQR42=7=0#iT7g0ObuI9dU08kR zZv0phDI&Es@p0$;`STal)YLrAbU&z5yE0afPX)FB6bhQB>G?f^C|xnz_D}A!f8fc+ zXp~BlwZ+_`}C{;FTeAuw z+*pB2e?13}HT8z`p54@x(>oOOxEzM#mg|<;Mo$7y6&foxRmtO>p*3Fx?;Xcsv27|NGN8KZwzg)sx3_2a_xEQF4i07w4Gnq2;joKc&%wZC zlhP!?u1WVxu=l2tF6{3H`<{(D-Ls&#x$I%vrUiLd36 zNNucd1KwWpQIvl2o9OH7_9}|I~ zd*>$H`r3El_793x1{FNAY3?I40?nRmJpT`mV)Fd6lH;b|2LpkBojqsHBPXf?>Unf3 zq|6rCowB>+V7#*XG~uRqho&}0qwCjJ_g30f-OHwZUp*lsTuUSi`<;cHNHp0r=`{J& zcJAECi9y5xGp_GRY(jx2B=oUE5+NcuuXpm9$iC%Eobb$LL{Co-@AU6LAi%Fn1ZI*2 z+1c6f`~Aqz&qqN)0q=!{g(xa2;=Q=In0I<#Qc}XdU$f*Q{Pnz#GmAt@8)Y>lBoJsU z3m6_3cYW(dhyn$evAC+^T0$uC;Gs^K$7zbKy;m~tSsK?di1I!0CnBK zq^3ZqqySxqz!>`dLwN75KZ8r*0{I+}WARDXb2IS7#a}_i#nmxVw^Ai(N6g~m_e^PO>CsAZ({>v8wC5tUxeNJ(>*9a!-o2b4 zL@ZA%gx_KfvMVA&?}wxmp~-)n`QA%Df&34D8O_bjoa>q1PjWq7ldhMOlLKZ;aAGLp zE4xA$|H-+QMkkGnIG8{{pLMr3W6n=Mi30lpv8<$wT)QS+-voBWW?={>a-<74L>f?C$i&k5l4wc_Fsu6Ij#B(6 z_dQ7yLg~!z?rzS-B(A-z-xl10o3on4gexb}BV4d}Ya!nH-2btEXMq`g=T|T2z30GedFM3ZO$jZ;koEHk1f3mPoI4| zHqW{OO_LU((O-jh28bbd4ooMTE$R*@OuOiCFlj)jXOlB(-Q`JkyW5MfHxF$&71&&U z7JlQNE;u%%!MjIz_^&#uU}wLl308z4q7fGpXVPT*LVfsvy;Vf`vNgjiB5a5~GcJNR zzliI7W%w~`pWliIO`J~vpib`z5F};jK8pK~XpphL)Ay*;@2FK>^gi@fED!-FNUn!w z50r?A!;C$z^JgJ-#9nFidCko&KBn3nY;3j>0l@Z>xehO)CU)`VHwI>$yUpp#W(;oQ zVv4#FUHZUjBB|2@=$$4gQzy7_&^)Vh2vC_88|i&U!EBdR_0+HR*YY^OWeP_cT@|_N^lSsFpb!pXxd6 zdV9{e2I!KiS1oWQG)cffu%L4%`dS(|DA^b(bXUYwQx;QEZZ^h|0YEa5`TVY+QCW~n zKJ8&d)(J_7r>+bidR2N*@AR4K*1sK3*RSLAxN)|vU#zs*HRF#-fR*-2B)nopSLc4x z-<cV~A z`5u9e^Iz_e(O2wN+kof)m>pn)xUwMl}gSK@w} zWCiHba5qX^K>>h-ws=JE2iV+~&16EsmUQ)096`7Eb!&eloIhMEsF;kNnnl70k4sQ0 zH4sbX9u#)$<6|2d8p_hb(K*bXa1Ceg9TNbaef94NyUU$WlcgS75nLy%P8{{QB9!&L z0*Dn9$I^8`ksn*opxLQ07K@ zq~qw9){IB99*!RX-1cxfDU2zMB`Mk!m+M_|zv=`KC8qWFC#nXl*O)WZAS3G%0R6)F zTbn-%Svk2$ADntiOH0xdAR?Oa7|t=fMYLWeX+UyXNKE=rc40EoN1|VGzfyZj=PTVk zTHLQ%pmLTV{-CxNqavR&zo0nKgGeYq0Cma8NWPpAuVy`r3;-0z)+K-ffg-9N^x*z9 zn-F?c6Qoa+ZZDi@r+W|q&+6GN@a~io!x%ak^P*$&qNJ!-ow#4UClKUC2T|b;rIvV2 zZFV9;3dG$${yP%=iu)A+ltId+iEV5Wt^E~~1v-NnBme}7bC^4f;2^n>PRaSXvimH_ zX~z!$-FjBWpOuihWlmigi>m8fs1ro*G`T9Ys&@)=4)+^$G@>ZlE`%N=(U{e|(LV#8 zf|4}XPq+M)3djmGKse2m^e_)!?v6&nT=c6jud;=d5xjr@emwWwb6Bxr1)h24nPjIp z!)UaUvNHA@?o?pPuq=o%@_KCvxFbU(q3n|Db7TUVM@BVH2mq$;qNs%p^{Ti@O{@}w z$J@!muCK2@thcqbW&A$1^SZV$_tX?Z&y*|sOmEj!Eaq;j3boRhn1PfA9{Oy7Gaw{~ zSDRF|lF01=JHmz|sr!{G)H(n8=by(*FTI2pUwkpGuUfTgbVPtRhYih^z9?s;FOG4I zAOcA$R_K$Gz^g6hk6Z$%uKTGvp(mo*5;0UZZWiKOt<^JO(B~*bv}`Ju90~vwz)>Mv zUE(axF$Is&@Ne9X{)O%Q@PF-i*B%pbOe<#RRHIOjuN&?t55a>zr?;Zd+Vqr{bs1wGY zM~eSWpvhMOv$Q4|upt1bz>h8g=-)TpbTgZ|SmrEeGo?MVhq{vb->M470{}*7kjR@- zQ@W>O2zPZb?!cfkO94R7if~vG>E0axDDK#U+<`+v`~%4yHmmdJ!s&AJb#)T|q_v)P%aW5j|2ka0^UmJC*Pd;PF6 zyF|-r94?dc-2s3p2i6NaH&0GRFQsSO(LU)6uKN}D)6%V4$I!+0f&~k>A!qmtgzIQp z0HA^_eqdUl6}DjinEClfm3D{rk;N;Vy0{jpRME--V2`g9c9#b@JTKZ9@nX=)+FX$U zDw^LB+^^EKneTrvXEMx!3a;-}(59oK<1mp;?%Qp*-3F(_jx4W3{9d0fLtAkx0dgHd z6!kW8qmRI(XAY0c^B#C7m3pU30J|VQMF{J2Cm(kd@{|QYY5Oi@1-k?QjFk9aQ?vkf z#?`v@PhilEHhNDvc%0r8C-8Vv08m_|R6tBd)mdNMwVhovnoLHaYpW!Vu>^z>i@>#G ztuS=;P_@$XJnHE~ckwi(@~oTU62q90r!D|$4y+U6Q0?38CR@&d&dPa7?x)FUXlO{w zSx{2ol1nZTpW7Ws)>qJEs{Uf z?qaoHgWTR0ih9-}k)6-SqsN7izB?lRt^j~1)X&8KcCp~;mXF2&uqSUi)7K?w;y;t| zMsw?Jnlw0d0Z`Gp4W4M9m=Hs*kTLPUmWh8GBeXIAiAeO` zs{bcXo}8v9 zR>|=p36mgF8`jN}8UW;$sZA4lr)6d?4g=jNYuzQd-;omkTl_O&_ZOv!e_Hslu3M1! zpEYY%+C8I_<{<7b=LsaRhEPnT?=L)qVb3#wYd8EFfsR&@zt8SDWy%y>ef8D2=9+7$ zutc&`w$g}I-R75>__Xq)M@gz2Nzd&(6JpfpQ8DdZ~>q30O^{`&>S*A~sAkbN@vGo1BbT3ULTFK@bi2+ux8q+CUjzPm{I*>O3A zw7|NE34?emE`99>=szTumz6qDUcm_metO%G_xLvi&?n1#t0f*1K6`-GQ!Ynv$+aBl zN)1V%$5MU~cM^v*32v4RAz#IM9aDL%Ri6*d@32F!5hF3$7f0TJ(>C zKl-AL+6gqAPL9mEfO!K<*4AfG1G+~Lm%K!q$`z(qF*wt`_+mFMh!8uPz*3l2Q_ON1o=k2xee*n@%}-hr&Y{YDUf ziu?mlo@%C^nFovHK1Z3XOM0I+vUf8u4zW4N$o;1j01CSg zprmbgDswj^tpANgv*GY%r-gngcV8uf>Ndc|7hinDd&K>v*zw+f0Z=vWvZ-ICHbD|1Jt^5P&`#N%Q zOR)YQ9!23zpXJX+#3#c~alaD%T8cgyf8^8jvG)OK6edn-08DDy1e-H1#6P6?XOsU< z*`mY5KZ!;i0BZ5a>i%VF*;juI15=jpViL)%SoUFz!k88#AV5;Aeu*#;i$j}n-tRt* zlKYpV?ax0!cT;_uN-$zkPWb$veHKLz+ze;eHnAIdhSb=bz_+7!PPqtM|Mib3x#$|c zs!7jA>FH$rDdH37>nZw$g@q&mI?Kw+hS(4~n|##bSustidF} z%LNPI@cNSCU%5icDAEByRXL8emCss$jmz&ALi9~ZU`GaZpa+WL7PXL&?&6ukTd++Y zLSgW26zzNx-iE)y;bbn}+_)h84C&%+716zpDHmh&SD!)YwYPI_SNjoFEdpiVs9FSy z_$2>bW8(-&9cUzR_x^l=pLDS<8qvgPU4s6Bw^qh+G$<-rnS9OO-0ub>@ zBFI7&@dqD#@R)qilO6!Y9lJ%^x2ne*62Z+i`Ez;VhaQ3@Vk`Zx8-O%1$7OR!&=9C5 zF%Z0b>yOYKXY9I$eYi!F2G#;t)-79BAS94p(k|(KKm@nWXGUmlGtPPCVa)yhhjHk+ z-(sM@FS+DQ&!iJyalYD^s#4V1dlSc4vh$<|z~shFsUlDi&P^iXKJ$@VlTopLW|I}o7jEt|g>9XI|PeslTVcq3~G z;#(bJY1X>0AXB;AOzI+GF&vc_5tl|HEnUnvac1{AT>ZqCFu3M<4gk{m`d&<(`0tve z(CUL5Mc6l2a!faytArapmGhEy`E>EG13;e?@{LCvgODOsuZlw4H|5;-qV@7m;!s|> zh#cxgC9LkD%@Rre$w4ZB^|=j20CBF49|H@KU1RJg0JGv_9-n$KXKmIhXe&*jW$+lnk z^)*5@al??AEJO8P)P<(w_l_m_gZ(UQ>#0P1hh2bSoBXb|`nuY_i3~9Xb+!;a4uy;7 z0h6}B2=C9o$lSxhrd4E}&_-Cd-(9A)!a%M6bro?}eINjZcS;54$ zqtU|sy*Tu%Z)4#jH=wHN4H3OtBn>us3Q4#<3(wYEhhJXuHN1Gv?byBGeb_pC8GbeA zX53%jUBoAtqGKxMTP=vt=adON zS|!>%i~=`@ci{b@ea!8YF?+uxkV6umxq*jfT!@z2{*w{K!xwFc_!PcXV^nJsdW}W1 zqY0Ppdl8HK<%W;BNag)oIo`B@Ku=QnJJSw5eyqIhhp3u8pI>|LuAO)N{6{}{BoH$r zue|p9skatT-LN5b*oqYYgZ2VM%crNU{OQ&|JvedPXz6{w8OGOxZ{qq0BR-u0a+V~1 zTykHFAb!WJi_!bfKY}l>fQM^U1rfCbO%h0z)Kev7d11*ZOk%wE)A+^g52Le(p?tM8 z9-W$PV9h~@Tfkw6wFQ^G7n5H6Ap>3)A4C1YM(^tNb>6^0ziZaanYL33067EgC~Mtu zSmH-r;cU2a^3pbaDC19+YSAbEgbdKc5bh7GX6|>FFuG=H#+gS1qe%32)h;n>X1qRJyIfyQWFHq z>C7Z(Sc|rGukta_=_NgV{r-1$?DB+y!I9Sro{-RQ(?&RqaLW3Zi62|b7A0%xD`Q9J ze(OmbCqn$Y18-rnYaq2ouabIP(r{x2Tz^3=>Ti9JR}UqzuU73;lBT|BL;D&i9i50z zU4Ks!p=9a|?7H@=cxu{mzSAeU`e+3~ru79<8DuB1`I=Mr7jy{wgPg{q!9XBqfJuQ9 zsueumt*TM3{AI}pWK7uQE!~3;i-*11ulg9CSaJsvolbtb zSw;{fGI$1VVMxyJ+=_wi>r|~^%0?*c>gmm5^W_?j)+dz_=7|Mv2Aay}Cw*O| z|E=7AqL%;cT`N&jzg}45<-S3ZGx5B8@;NZhxthD1(x{BO6w}Lte-1H|1Q7mgZRtEpJx`PO=JY?QA39oI@S-!@(FcyR>yXjz3t>rkZ(~c zeTyul&M-eYRRHDvRUNDo;$Kz4U~YG#Z!%B($Rz&t3Zy5pB9=4Qf%%(O2z@^dslBwO z=5z0-EF>>>p8pYa_w;h&E1j<&8bQP)qN`fTN-|lCXj%`4&<~iR-%MV1GhTSlKZzjI zZXBMCl(2w6rl95622mYqFP7$EiLefm$@C|0oxsBG1{8HRh~cWdKcD))MDvlyx`weoi$w-!cG#bM%KkErSCUn6NVcE1X{FP1tSGp=zz zO*Cz)Is`oLXLg9w$E|%8j8efKo%rgkpyLImzK)^iAk@xZh;`?EMC|kFMEYhGD*$YQ z*Q*>+M~OSh_13cSX&%A21Auhr#*G`XWy=xqHVfVFv)IT={I@bp^xF_#bXk)4Y7t7EouE!h(Z&9;o*VGH-~A3> z`N~&t_uY5%>f-w9qw*NCmfnJB&Lj~j1k#gC^z#uDB6{j^nV6Hs0pON|SNo|CD;sYc zZ_Yn(-~fM5Rx?@Bb#-;{Z+%tN!11R-zp=O*J(Ct>6#shk??l9ZMaw(z(V5Q`nl4Rf z3of$o^xwj{==bJx(XVzNDN(J$yh`koL^zs6qEkx0^PTVD^Pm4b-hA^-u1=_}T)8q? zUS40-EGn=nDtSu5m zO~)Q2@fsJQ);<2|$%-Gk@n;3Vi5P&DE!&XPlyQsrw@XRH@bOAC7tvTe>FX=euOAmf zl0XqZ(|CxmKl|CwIJZCg=%XC`R#iyXe(0fx(((}0wcO`j!|>@7`xNw)GV8ekvgmbz zlM~w^Kgp6SD+&NfZ(!U2K&x~L>1iu}!4{NK4IGvCCyO3F9WOyk>mhD!TgCrq`2Mut zp!m=p;dMBXUO!6}VPeCI2Mz2ovy)XgRE*zxSX3s9pE#X}e%D=haS=~yFVh_8jh^>= z-}_z~2&ffQ*P>_2Sz@D|x)d-3iEF*d1N78M2&NCPcTEL&Xgox`#~*(j-~8q`@x?EGk#jl`ojyOFd7`3Nhs8Op4o_wl~%h|AD1D<;7 zDbBIP<@eruFW2d0+^Wdnu`~h|tqpwWLm$F}4?Z|-4r91_z8F`(1^}BT{YOpw8C>D5SJUgtho* zkqHX~(WIRbIGCRI*G&PJEcE7-CAnWW{;cN`rPcbAQi9gyDOf{?I8k4>Ze6mII97e& z;J%cGOk_|2vbh#~pVZb16AjF7rg3eqo&I z<>E7J1T&4aEh=_x*~l>=D!|%&!Cq7}ZxfvFloL)TeHG1tzqBH`T4uHWb>bf{$Ej08 zs5>L_peXCwsOoZa#-N#=Xfl#BlZew5(Mes9K{%2Ek~~7l<_1AzsQPPBE9po98p1`3&dukrF+9TsD~A>0HD0Ta?1NFLaO9B zb8pra&4VjDci5Fb3b#_FFEX5HvX?Ab!a+gBpNZp?t9dM;;Q@y?RXjD5B!~+|8ci5! z)<2Dbh<)anXX1k&{2+etgCB6qoj80<2!5ny1+5_sLk5E8FyBgJ904j52Y^Z@{+*=A z^m=~`1iQ=Tr&av0=KW;~{?O7Z5u~=Z7IWv$<-j=m?6WyI7A;zoR&bhf@dzl?-4v5B zGwA=M#l`+HJLwV${Ii z5Ql=1K}lf3R|Bi4+^ejJk<9yZl^{`EJ#6BKem3v1PP(=5G^r8-3UzmJWl91ZfvZd{ z5Mw>Eb|MbTG!ka|IIYLrGFz%MWJ~N0a41;L7EOyAP7DD2z0D{)v@<>Jn~DDoMRVcs zcr)(#(@*FetwWoFzC00liezx7%#^*H#UucM(rN=t#K~cFbd0UHEtMT)TEf>dNVGfQ zj0R(Ag`rIg@sqzCcK}p1Z)V(M$@>c%*j2ueAM`j}+V_dB{2gWkWEUroTT3&I)YQm5 zdpU?D@2B6}`Z_KEh=yVB?Gyk2($6`PX9toxT@}g-#8ZFO*9zkkDgo$d(@84tPZR&m zUgq~_$oo@)A8X#F#2 zjO_&sY%+PNSZlQ+RjNwgd^WxSDCnWQzj|T(sk}cr=&?W?^r)6w)ym&!=KWdQkS`zo zxus&4Pa*>VY{Erd@=IEaR+0fs93*g@Ly6xk<}^xXhoCgk6v5PTL&lD4ikdX-AO0ysDO4*+kD~ z0Pvc^4oEGujQ_cT+%efFE2d;w0HDg}bWs-793*&deOdvUsJ7anpB!S28vrQpj|YE< z_*%8^W={oBJn5M7{zjV%n=0ptiR(dntv@9Nn5ruB#4*(o^b0lc9%q0r2I+@Ip2&d^BjWzu>)>eJBer@ZkbZU`&1Dnt zM&Ue!{N*%{2GT1Jg^@ZuDmo!5pqh+7ubE1~P~yL0Zd&k1Exe4C^{=;x(~J7r_lPvB zAx#RXsiW0G=B+IE4ZsYDyaRPspt4oQO9J>_|Gg0X`A9!Ikc>atvNmADj+*ln1L?I$ zBa-+-@-;N>MqpaKKTo>&H;X1EWB5H_>LaV%=FR4@5j4ou08Vpg<+ zk407O)XUS3H3*#bo8f)yd2x89N}N%a|9}9%>WU?Zluu9YQbKC)a1g1}!vaVZp&LIp zuvD-2XQYdN+V!J+f2IFNEA9JO+F*7uwlEOz6bU`!RuyI<&@!*(AKe{@2L_U-k*JNG z;~@odp8qKfcOZk6MmJ^RRn*-&`R!uBdW( zHu;`JKT}^X&Atw{f-;`xpdB5nME`(p~w;y(^-LbSaxnHr`zZmiURy{8p<|9iiP znoiQV-z6fb#Qi%;7a_Rl3Z5IOt)C?1$cH5Hdo>9V8`nr6PyC4Yi%CQ(_P?cYHWUAz z39-T=^HWCAyG81GnxIB6~U!j{)q7403Wk{Ox9=%# zTI_$ccm0f{y}tM(=(H7y^LkWCctcJb#V%$5X9Vj}wf;{@uVu7P3{}nl+q;?Hzeb!L zm?O8Hj*^bOIhU^d{$;l5aiPO#es-|Y9LkP;bH+#C>htl!;r^B9gx1HK_%ia5)6cin9)|Zy6lSw{LL(q*|KF^qAoWqskO~5w%MJ#_I&Q^HF%JD00vK4S4pcX@Ir?; zGOywB7VP@;9(=nm%E{7s_1Uv}^Ye1TkH5S=;~|Yl#p7j|3Y+~E2FPlj_FawCp;e|N zK69qNa{xd6+FmfrkXJOQ7Jf?dI4$CKvS#Wf0LZ_gU4?^4mAe{y6=2@W7$6$EiMvtR zNNxLK-1O&m{2?knRa=&owhbb=IZPaOJYK}7_NR6G%wQ;H{y|VL21FX%ibZCZU`9;jviYZU=0=-3A2J1DN(*P z6GG7d!Yev?MZ7|!YS%zMZa@-0=yJItOt+11yp_?S?m%~<$YaM{d-1J1J1bTV_Bh1k zcS#VKa->rQ|4lE2|M`XZuh$piiA84r(m%YmGy9WsBDSrcopw|Zn9ERXUS+=rL8HkC zhVDfflQpDv%B11xlK0)f=Pv$0J?{C^9{f(;y%edFlr;026TM9WpqHtijJki!Re*UV ze#wabF<#}$Cns$k@MZ%xUAzHzYU1CoiGLDXyQSFbM5fmaJoZ2SgkDCm>9YM6N8N}Lmg7|BH7~8JMNAJ>N*o3jcAY?G% zZsJ@<;7eJb!LH#-9uZ%ltw%(~0uRkZcK}_tZO5mc@8tTNU5Vff{ zlKXVBCHV?ufXuE1a62U{uM_~3_SY99EQGppU#Nv;o%LAg9TEU2L#nQUnn|^iIHWDR=(FuXvWNpWF4ek&I`F+k zXzk`fG~Is?_x!pEe-Ec>lvjw5R8sVta-KRR(=^K0wv@$n@I zjI=K_;^nJ0;vUKUH4^()@!ufz*o26Gz0IvIcTAo(bD_g<1d`hH*ERu@CFO6oE4l*P;zfE#|i)0*~^Ai&S01kqS z;qSF$(a#SeyCaOjA2nicP@tFso3%*o3mTL}-z~+z5?`^C0RYo$r`l%Cne!iPs=mS{ zfVLdm)z!80op;`O+Gj_}!fceCn~UnjIVha#Lw2zXF0YZ)?50Nl2=i?Q>w{>1tq(hP z1@Q7qUD(?j(~E#AP{g%vyK;FaMFUN zfrQOO#N>Ip2$;n421163K*B&E8plvv5YsJXh6kxC9$slFc#+!Cn?N#+md{z61VD%U z_kd>b9rN6cIRJ`Wum|JFW=~rpot;{w7iR0wqE@Y%{yM4Jb=O_@JbSrHt^BEcfR>h) z=b04vv((Ri`CR%rV5-Eko|UVg8EW0Wt#9Ktw8(?LxYI7hf48(ChG0qeKGrtoi$VP{ z7{NqZhH6BjwO4X`mnOc#CyVIM(7vSa3{ra*%FD|ylJWL^Qj)c3&!e9-;MK&s-c_Bl zY^08mQtSDH@>(s@OWG$HrNN@}BS-S}CsYDRB&#w|rP7u0BegR?S+VU%RtY$H#J}E_ zFJDd(%=uy+iDw4AxqJ8SPwd;bFQgGy5mXgsR77KU^%!%dZDQ@UIi?baQM`sR(0M&vAqItYP z@XRyMtXKaoEG)Ez!(kf%fpuEeR@Jz?NH5Li(saDta#?-rRz!0Y)x4;jex2h-WuC@s zzms0+UN2UxACGv_6aPrf$!vcaEOKauoC~QkZ7yvdY!(TihlipXhpVpglFZSbqw(DE zW<5Y%7k?S*T%FQQ5m-MiT3Px>ngi?6kqM1a#*8SZ+xUUvNS@c26Z>>K-A=dD?Q}cc bwD$i1x*X9kt6Wet00000NkvXXu0mjf`3Tr$ delta 201 zcmZ2lbdzy{L_HHT0|UdpfX)aY#Tnoe;(Fk~0U#4d`si)!0qgjHQ053HqS;!DtgL_aj7DV&f7qzCC;z z+#Q`93>OL>lsN=8_%av$atO2{xjGCEXq`$Xk?{m+kh4N@w|60ji>st>Vk9*Jl&bRm3d!O?J;g9Q&>;L6t zZ*M;qvHbUHd}l-v0uX0^j|4pC#>04fyH{2J2IGX$6)+P9wCICjf}jU-ArchAN_}?@mVRT+?g+_Yg=R^2dCUE#5K0`zy!Vn(#424jLpP$rp0<46WFdJ_ck4QnJBUU0- z)Ihq1sQN#2pVb_z5bgrxn+pEj+X@DMGBVQb-?y)py`A09WW2wfIlPhUs+i$35je|b zHo~jxCc=TQ`U`8e_Z2o=9wuCTtq|U*tvLZi#8Ls&u7bKmA)I;YAQ(190WV-4zgZ+A z1`*2<(+n)pi4 zTt9>*!V3|Mm}S>l_~NOVP^=>5MvKo=qtgCkA>55H*6+A}in+Gt1lR}CEd-UjWxOeZ~dwcfm`GrEEfJt_8D7DlE2*=O( zYD2kO=fXo9*96DJ#LV>f_m4vt*=S~FmV?-4X=#}wm&>=Bo11S}j4}QCzM@@8xv!S^ z93))jrv-TqU2pwkeOADYs~0`;^S&Rgi30XB|6IedisN%cL=`M+1X8&>By;2Oy&@|a zOc^hS@#DvXv$Hdpnwo-*+yZ{IY6GxPU<9bG4d7wk_i**XC zjvYG&=g*&qD_5?-<;$1h?Afz$c>g~5$-SHS|B>RvmAJNnE9(>C_U+qnFF*fzg9M;I z#ZsVB1?fPslL7NR!hLI_CZohs2a2p^qLK(0WA0lSNl_j~jT!|bM~;O3ig%$DXPpRA zE8D`$f5yY5OP65t=FO0llmx3+uZFL`{u;jf?mM`D|2{l^{1~1*dBX7M(Id#u&xaew z_CdM5f%qJ9y(I#?aP10*4<9D7ew^g#DXW)&0&l(cDqHOzE`?f`teYPKlP6DxDoaw6 zvCw7&{Nkj`23F)QgH-EJ*!vC+4lroYAg~-aMkG5%3}h;&j&SYTHQ2g!D=c5W98yzL z;lP0daO>7BW~^j*P0-&8=9*UqMRdU;2YuKYJs)=M+V#rF$fy&#n^wIf9Go*=D`U-? z=kf9J;OFNDj*gB@rfzO-;Njr`US3`>Y0{)dA#;KW6nn{-G)pXWnBhdgh!G=T*sx)+ zPu>m6{B*=Y6XQ;txQblx8VHGr zi3Mn$vA({(L4&TaK0Esvu|8|oESNH73QV6q9p=oL0}B=`fTc^9LPSJFqj1Z!H^2-W z%v1qRP3*&nBoaRPOeiX7as~MR;+- zhLE)&6aoVS+3b`2y(~yxtLmbtGTW zkPw{6A~bCgqCY~nK?2sVUk?)S_Xa`g`0TUK7>F?G{bS2Qp~T$~D8G2^)QJ&Fsv0n0 z01JL|7v|Fz78WpY;6T9S z2e#RLET*~fqR*DPw}nl!l+69o($e7ExpT~LDWI-ewW>)3U@Rg6HgY%U@|zLBwJ?4SX7x0l*wg8 zKna?*1wlnqw|e71OA$~Ze=LBWdG~iGUnL2;%>K69Sn0adykR^x>O@K1}{&#*6`DV`IP+7Q({9 zL;|MqOfiaQj%Ywr74YMkgP?Y4FV-KZC{>^?9GPlem4M*ii~uHoN^BG|$Vy9O@~6l@ zeE4vn+@G?#mwVQNN{Itb;{;$0QS74&XWaTVDF*x!<0%pv#oY?YjEVSMBH&AeAL4H< z9s_Ew0;d)$+04`WUse7T{Alf`T!04r?AlpSJGK$aD)9aP;U=jaPxE z5AIiHlrdBgwSoK@=4?sjK`tpbY{Evgu}YC^}# zQaO_QFOu=brVZ@bxE5~QxKSwf@WMySB<@x&h5&;PaQ-ndQ z67Xf_Dkgi9Ke+)VP&5cidreGCnEYvGtIAd#tS2^3q|!NA{JF@kEnLaTVg*n`(pP!6 zX9TMK^`L0_P&j$?Fv~k=Nu4%rS|RuU4-h)7N8|AKw$w;T5?6-O32orT5+`_+pI5i>liIWFk6w#s41?TjS6DGc@+b0RVq#vSX=7wE zS%(H|f#wn*$-l(S5Dte2!Lnt`SO6P5crcTHKtMq4Mg;I!ki=CGUD=FL1?V!8UPpVt ziz7KKc2EE<4d?|bulB6WR$J+@``o>I7Y-dd#E7SQB0W7Fa&mHh($mv>8!w$!C7`DK zsfM7mmI5E8zE)ON5E~m?>r58S7z(PXx?%$*k*h%JBJot2x=AYc4xk?2rqXbfJQ4Bq z##PA6%Y$#e`G(ajL_8T!WL&&>@!!_g)_NMX#+pOGg?VmJ?jx&^Klvanja2+l5VW*vLaQ`0s5;_=EQ*_0AAc-5zE5!=eh~~dXi*bV1eNx8Vo4IiEMf6 ztxrIO{HF+TJ7_deS83|hsVwM8^2hbK!S$SG>~`*V@OX~3SW8eb<*fsSPWlXNbA=aA zEIvpr`~<#=go_#An5B>9JihBipRPn#2&0cxcl zGnRts@en)63~`5*0nYI4#J`KnW*E;G5;y@;`kTt%$Is+nJ}bJwqerbvKu!5m^rd2l zjKGWl$^oRbwkD>yI>Jr6E>PqlV^y5mPfTcToIcKagcR7wrRcuP!a`ZqSm?}M zM2Z!>1ZFDh1DE)@7#Hwk(#8{Y6RQ~9>b(hE^vO1E0aHUeyIILE?{S8S8wN- zHbq!(FpL{9Utmic1x0Fz?%%(k)fkjgQ>%_DManR@%%8&QeYPKv!rekjr!l7}K^5iC zw15*QPQ2*W_3ie3KK@v%RS2M2r$LYkHYdka$bZI+8BF#X881cmXxbRjhkIAfv4$vh zg{cZ8(9fq%onmD&uI;R4wktaW9(jBK5c55bq3UxbUlu5i**}Tv}BK5(z|7 zxznF2^Mp9j4azLFp{s##6wRZ9S0?rL1R5fMW=3j%U3Ge&<^3fddax(h0U{$KHJ1OK zkTK!`2&vG)`(&DSW#ucWhg5Lz;6Ya4NJf*oXuGXuAg!8Uy^iq^R}-nAN~gG@3$A|^ za?!jjgk!y3p@s+`BWae2fKp4b@+(7$O;>t@lamuGd0kyyVabvuEFG@vK5RRCDbMB- zDS*nrZ^++a=FFLF_USnb7cOMWsEdnBovR4_jfjy5V0}j4_LUu`G?4(ew}e~V4Fc+I zjcXbN_s&;Bk&D>(yX(-E?Iu&cPa7T+Cr)Hakdz|z3u&MdSinlF>;M&7>415^51~(= zKG3gUKh`?8v9YPuXxg-;S+A`}SkY%ptvsW^3Al~s?L^E*^r$lqXi7lUw)fspCpJ^G z*+FS9Wq(u$NCeadMnG!y9h@FLdN5G))XdDRS^`BgO{CV3th>eY+&4`>IOk|;7*3UZCwAx^1OKsg4% zzv&Bf=yEUObHspV5x^q2n_)%cgWBFSSgQSL>8iR+R$V=4O_xwXKvZS%Lh>iS-?V8{ zqmBL*0n%nmf*7OFv=c2xKto61#S0ak^Me^qk=_HY;I+vFHfSKFIrpZ4@9XV)l(1Po$(fzmO$ z0!JP2>er3s4>>tGaP#KPCK13^0iVk4u`;CreCaW&3{5+Z*g?nZ5Fa&}fZE#LB!3D} zq=a?r)@ejQMIt2C^T7h759!1LXmb?6w#TMd%AedJBshpRMvhh49($+B%OI2gbW#3N z+nZ*eNT67t>7j~>R5+Rkt8f9HnCr5ov^g<=?KDO3sxnXy?uLw|$sq!cAl4$rBRV!I z5n}SE`a8UO+nb_4xdFLDqY5d^2Fn9vqFfOL4%!ejvNubi=^S8Vji+vs+OKUz|4?P6 z51Ff0(DeMw3`6KQiGYf}UugBVHz}Yo@|W~-*ZLMO407bym;+vWz4mY4vi zPoIW|4PHk2(B(=RM2Ao_lxmohB+D>C_ zaNgxD@zH|IlLxal7F`l;9sDmV(b*96X|A}ycojZ53!&ayOA|Q#M5vso&MkC}1 zWd*XclwW3~D^G`eFI8J>i|krzsRNy?l8lXwzry6@xQU5LHu_muN=k|!sz8ZFkh0o6 zY6E^|!@3OR#`HM9Bc4OQD8yAjI^FfgSqsi9y1c}?Aa>ubZ9%s#pY_Yny{3Hp{VnB_ zyxYpBcWx-3-nypzA@_pv)q$)T-aieIh_GmfS5uGbyY~N!ZtTczhYJ-t;@M;j zilv?cyfhPDA2!wsTVnO$ua35XrO;h%tGg8}1Qpvvp+M>;z|R)Kv+iw#vG|b%{8UH| zKO#4@!4qQj9;Q|ZCF~(y0vtDHb#*8rlP4Af8r*iS=ko5^PHWWQ{_lEQehMWP+ED7P zC8_}pQ%w|?GPRZP9IS*Vh^J_D8CVPAcM2l-7d$KlcsyFTV4y7wAlGaB02U+;6P7jOe4Skjo!fS(w3&F{}2M#QV{y_Nl!f>JBzvle=K^*0Bp&Z|Pac;1%e|C4) z;Gm^#BA0q5Z+wI!tofNB-4^*`l}RTSKtAFuuR$#4@^6_3h+mv4ClaWv?%cU^Dv#b- zTy3#DmG$RcUdrmGb7NEZXOg&kn({-DvX&Z~Ak$(u`w-!SSjZ0@z1?Krs!auUcDt$m z$5+*$L4(N6o!3$*|!Kj}Fb2eJz(Z@2AnM59ep@^jq=)Xm}UI zS-D)^1utD49UUWnwr3cZv$K?y4}vNB{r;07*qoM6N<$f-@SBF8}}l delta 191 zcmZ3aex7lHL_HHT0|Uc#_L;swiZj3`#1%*b!GQw@oPx6IfGoz6AirP+hi5m^fSeLf z7sn8b-m_P3^EN2(uwJlgIrmuLkigvIo1EWIsbh4L^Hp(q|J*Z*OGS0j)ul2nA%`AK zRH_!WXf|_5_Rn+d5KYw6(AMr}T=2)@DQgGkv!@nJQ+_Wvx0wHMe%628pna@~3=?c3 o80}|Xxf{fKtLUWXj?`U2!IPgg&ebxsLQ0CT!W$p8QV From 8959de589906a110f4a622f22a5e39a719622a35 Mon Sep 17 00:00:00 2001 From: Seg Date: Sat, 19 Jun 2021 14:53:41 -0700 Subject: [PATCH 22/24] Merge SDL UI changes from windows --- BasiliskII/src/Unix/prefs_editor_gtk.cpp | 102 ++++++++++++++++++++--- BasiliskII/src/Unix/prefs_unix.cpp | 31 ++----- 2 files changed, 97 insertions(+), 36 deletions(-) diff --git a/BasiliskII/src/Unix/prefs_editor_gtk.cpp b/BasiliskII/src/Unix/prefs_editor_gtk.cpp index 4f2d837b8..966a369a2 100644 --- a/BasiliskII/src/Unix/prefs_editor_gtk.cpp +++ b/BasiliskII/src/Unix/prefs_editor_gtk.cpp @@ -790,15 +790,13 @@ static void hide_show_graphics_widgets(void) } // "Window" video type selected -static void mn_window(...) -{ +static void mn_window(...){ display_type = DISPLAY_WINDOW; hide_show_graphics_widgets(); } // "Fullscreen" video type selected -static void mn_fullscreen(...) -{ +static void mn_fullscreen(...){ display_type = DISPLAY_SCREEN; hide_show_graphics_widgets(); } @@ -818,15 +816,37 @@ static void set_graphics_sensitive(void){ } // "Disable Sound Output" button toggled -static void tb_nosound(GtkWidget *widget) -{ +static void tb_nosound(GtkWidget *widget){ PrefsReplaceBool("nosound", GTK_TOGGLE_BUTTON(widget)->active); set_graphics_sensitive(); } +// SDL Graphics +#ifdef USE_SDL_VIDEO + +// SDL Renderer Render driver +enum { + RENDER_SOFTWARE = 0, + RENDER_OPENGL = 1 +}; + +GtkWidget *w_render_driver; +GtkWidget *l_render_driver; +static int render_driver; +static int sdl_vsync; + +// Render Driver selected +static void mn_sdl_software(...) {render_driver = RENDER_SOFTWARE;} +static void mn_sdl_opengl(...) {render_driver = RENDER_OPENGL;} + +// SDL Renderer Vertical Sync +static void tb_sdl_vsync(GtkWidget *widget){ + PrefsReplaceBool("sdl_vsync", GTK_TOGGLE_BUTTON(widget)->active); +} +#endif + // Read graphics preferences -static void parse_graphics_prefs(void) -{ +static void parse_graphics_prefs(void){ display_type = DISPLAY_WINDOW; dis_width = 512; dis_height = 384; @@ -838,11 +858,38 @@ static void parse_graphics_prefs(void) if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2) display_type = DISPLAY_SCREEN; } + +#ifdef USE_SDL_VIDEO + render_driver = RENDER_SOFTWARE; + + const char *drv = PrefsFindString("sdlrender"); + if (drv && drv[0]) { + if (strcmp(drv, "software") == 0) + render_driver = RENDER_SOFTWARE; + else if (strcmp(drv, "opengl") == 0) + render_driver = RENDER_OPENGL; + } +#endif +} + +static void read_SDL_graphics_settings(void){ + const char *rpref; + switch (render_driver) { + case RENDER_SOFTWARE: + rpref = "software"; + break; + case RENDER_OPENGL: + rpref = "opengl"; + break; + default: + PrefsRemoveItem("sdlrender"); + return; + } + PrefsReplaceString("sdlrender", rpref); } // Read settings from widgets and set preferences -static void read_graphics_settings(void) -{ +static void read_graphics_settings(void){ const char *str; str = gtk_entry_get_text(GTK_ENTRY(w_display_x)); @@ -864,11 +911,13 @@ static void read_graphics_settings(void) return; } PrefsReplaceString("screen", pref); +#ifdef USE_SDL_VIDEO + read_SDL_graphics_settings(); +#endif } // Create "Graphics/Sound" pane -static void create_graphics_pane(GtkWidget *top) -{ +static void create_graphics_pane(GtkWidget *top){ GtkWidget *box, *table, *label, *opt, *menu, *combo; char str[32]; @@ -969,6 +1018,35 @@ static void create_graphics_pane(GtkWidget *top) gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); w_display_y = GTK_COMBO(combo)->entry; +#ifdef USE_SDL_VIDEO + make_separator(box); + + table = make_table(box, 2, 5); + + l_render_driver = gtk_label_new(GetString(STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL)); + gtk_widget_show(l_render_driver); + gtk_table_attach(GTK_TABLE(table), l_render_driver, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4); + + w_render_driver = gtk_option_menu_new(); + gtk_widget_show(w_render_driver); + menu = gtk_menu_new(); + + add_menu_item(menu, STR_SOFTWARE_LAB, GTK_SIGNAL_FUNC(mn_sdl_software)); + add_menu_item(menu, STR_OPENGL_LAB, GTK_SIGNAL_FUNC(mn_sdl_opengl)); + switch (render_driver) { + case RENDER_SOFTWARE: + gtk_menu_set_active(GTK_MENU(menu), 0); + break; + case RENDER_OPENGL: + gtk_menu_set_active(GTK_MENU(menu), 1); + break; + } + gtk_option_menu_set_menu(GTK_OPTION_MENU(w_render_driver), menu); + gtk_table_attach(GTK_TABLE(table), w_render_driver, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4); + + opt = make_checkbox(box, STR_GRAPHICS_SDL_VSYNC_CTRL, "sdl_vsync", GTK_SIGNAL_FUNC(tb_sdl_vsync)); +#endif + make_separator(box); make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound)); diff --git a/BasiliskII/src/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index 4ca5fa284..5d2ab5327 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -28,7 +28,6 @@ using std::string; #include "prefs.h" - // Platform-specific preferences items prefs_desc platform_prefs_items[] = { {"fbdevicefile", TYPE_STRING, false, "path of frame buffer device specification file"}, @@ -37,17 +36,16 @@ prefs_desc platform_prefs_items[] = { {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, #ifdef USE_SDL_VIDEO {"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"}, + {"sdl_vsync", TYPE_BOOLEAN, false, "Make SDL_Renderer vertical sync frames to host (eg. with software renderer)"}, #endif {NULL, TYPE_END, false, NULL} // End of list }; - // Prefs file name and path const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs"; string UserPrefsPath; static string prefs_path; - /* * Load preferences from settings file */ @@ -90,13 +88,11 @@ void LoadPrefs(const char *vmdir) } } - /* * Save preferences to settings file */ -void SavePrefs(void) -{ +void SavePrefs(void){ FILE *f; if ((f = fopen(prefs_path.c_str(), "w")) != NULL) { SavePrefsToStream(f); @@ -104,32 +100,19 @@ void SavePrefs(void) } } - /* * Add defaults of platform-specific prefs items * You may also override the defaults set in PrefsInit() */ -void AddPlatformPrefsDefaults(void) -{ +void AddPlatformPrefsDefaults(void){ PrefsAddBool("keycodes", false); PrefsReplaceString("extfs", "/"); PrefsReplaceInt32("mousewheelmode", 1); PrefsReplaceInt32("mousewheellines", 3); -#ifdef __linux__ - if (access("/dev/sound/dsp", F_OK) == 0) { - PrefsReplaceString("dsp", "/dev/sound/dsp"); - } else { - PrefsReplaceString("dsp", "/dev/dsp"); - } - if (access("/dev/sound/mixer", F_OK) == 0) { - PrefsReplaceString("mixer", "/dev/sound/mixer"); - } else { - PrefsReplaceString("mixer", "/dev/mixer"); - } -#else - PrefsReplaceString("dsp", "/dev/dsp"); - PrefsReplaceString("mixer", "/dev/mixer"); -#endif PrefsAddBool("idlewait", true); +#ifdef USE_SDL_VIDEO + PrefsReplaceString("sdlrender", "software"); + PrefsReplaceBool("sdl_vsync", true); +#endif } From 42ed1c915a79fc31e9e27c59bda5260a564bbbd1 Mon Sep 17 00:00:00 2001 From: Seg Date: Sun, 20 Jun 2021 03:18:02 -0700 Subject: [PATCH 23/24] Sync memory changes to uae_cpu_2021 --- BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp | 234 ++++++++++++++---- .../src/uae_cpu_2021/compiler/compemu.h | 4 +- .../uae_cpu_2021/compiler/compemu_support.cpp | 105 ++------ BasiliskII/src/uae_cpu_2021/cpu_emulation.h | 3 + BasiliskII/src/uae_cpu_2021/memory.h | 4 +- 5 files changed, 205 insertions(+), 145 deletions(-) diff --git a/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp b/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp index 9a794b487..2cdbc8c89 100644 --- a/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp @@ -31,29 +31,39 @@ #include "readcpu.h" #include "newcpu.h" #include "compiler/compemu.h" +#include "vm_alloc.h" +#include "user_strings.h" +#include "debug.h" + +#if DIRECT_ADDRESSING +size_t MEMBaseDiff = 0; // Global offset between a Mac address and its Host equivalent +#endif // RAM and ROM pointers -uint32 RAMBaseMac = 0; // RAM base (Mac address space) gb-- initializer is important -uint8 *RAMBaseHost; // RAM base (host address space) -uint32 RAMSize; // Size of RAM -uint32 ROMBaseMac; // ROM base (Mac address space) -uint8 *ROMBaseHost; // ROM base (host address space) -uint32 ROMSize; // Size of ROM - -#if !REAL_ADDRESSING +uint8* RAMBaseHost = 0; // RAM base (host address space) +uint8* ROMBaseHost = 0; // ROM base (host address space) +const uint32 RAMBaseMac = 0; // RAM base (Mac address space) +uint32 ROMBaseMac = 0; // ROM base (Mac address space) +uint32 RAMSize = 0; // Size of RAM +uint32 ROMSize = 0; // Size of ROM + // Mac frame buffer -uint8 *MacFrameBaseHost; // Frame buffer base (host address space) -uint32 MacFrameSize; // Size of frame buffer -int MacFrameLayout; // Frame buffer layout -#endif +uint8* MacFrameBaseHost = 0; // Frame buffer base (host address space) +uint32 MacFrameSize = 0; // Size of current frame buffer +int MacFrameLayout = 0; // Frame buffer layout +uint32 VRAMSize = 0; // Size of VRAM -#if DIRECT_ADDRESSING -uintptr MEMBaseDiff; // Global offset between a Mac address and its Host equivalent -#endif +uint32 JITCacheSize=0; -#if USE_JIT -bool UseJIT = false; +const char ROM_FILE_NAME[] = "ROM"; +const int MAX_ROM_SIZE = 1024*1024; // 1mb + +#if USE_SCRATCHMEM_SUBTERFUGE +uint8* ScratchMem = NULL; // Scratch memory for Mac ROM writes +int ScratchMemSize = 64*1024; // 64k +#else +int ScratchMemSize = 0; #endif // #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) @@ -63,26 +73,120 @@ B2_mutex *spcflags_lock = NULL; // From newcpu.cpp extern int quit_program; +// Create our virtual Macintosh memory map and load ROM +bool InitMacMem(void){ + assert(RAMBaseHost==0); // don't call us twice -/* - * Initialize 680x0 emulation, CheckROM() must have been called first - */ + // Read RAM size + RAMSize = PrefsFindInt32("ramsize"); + if (RAMSize <= 1000) { + RAMSize *= 1024 * 1024; + } + RAMSize &= 0xfff00000; // Round down to 1MB boundary + if (RAMSize < 1024*1024) { + WarningAlert(GetString(STR_SMALL_RAM_WARN)); + RAMSize = 1024*1024; + } + if (RAMSize > 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) + RAMSize = 1023*1024*1024; -bool Init680x0(void) -{ - spcflags_lock = B2_create_mutex(); -#if REAL_ADDRESSING - // Mac address space = host address space - RAMBaseMac = (uintptr)RAMBaseHost; - ROMBaseMac = (uintptr)ROMBaseHost; -#elif DIRECT_ADDRESSING + VRAMSize = 16*1024*1024; // 16mb, more than enough for 1920x1440x32 + +#if USE_JIT + JITCacheSize = compiler_get_jit_cache_size(); +#endif + + // Initialize VM system + vm_init(); + + // Create our virtual Macintosh memory map + RAMBaseHost = (uint8*)vm_acquire( + RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize, +#if USE_JIT + // FIXME: JIT is not 64bit clean + ((JITCacheSize>0)?VM_MAP_32BIT:0)| +#endif + VM_MAP_DEFAULT); + if (RAMBaseHost == VM_MAP_FAILED) { + ErrorAlert(STR_NO_MEM_ERR); + return false; + } + ROMBaseHost = RAMBaseHost + RAMSize + ScratchMemSize; + MacFrameBaseHost = ROMBaseHost + MAX_ROM_SIZE; + +#if USE_SCRATCHMEM_SUBTERFUGE + // points to middle of scratch memory + ScratchMem = RAMBaseHost + RAMSize + ScratchMemSize/2; +#endif + + // Get rom file path from preferences + const char *rom_path = PrefsFindString("rom"); + // Load Mac ROM +#ifdef WIN32 + HANDLE rom_fh = CreateFile( + rom_path ? rom_path : ROM_FILE_NAME, + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (rom_fh == INVALID_HANDLE_VALUE) { + ErrorAlert(STR_NO_ROM_FILE_ERR); + return false; + } +#else + int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY); + if (rom_fd < 0) { + ErrorAlert(STR_NO_ROM_FILE_ERR); + return false; + } +#endif + printf("%s", GetString(STR_READING_ROM_FILE)); +#ifdef WIN32 + ROMSize = GetFileSize(rom_fh, NULL); +#else + ROMSize = lseek(rom_fd, 0, SEEK_END); +#endif + switch(ROMSize){ + case 64*1024: + case 128*1024: + case 256*1024: + case 512*1024: + case MAX_ROM_SIZE: + break; + default: + ErrorAlert(STR_ROM_SIZE_ERR); +#ifdef WIN32 + CloseHandle(rom_fh); +#else + close(rom_fd); +#endif + return false; + } +#ifdef WIN32 + DWORD bytes_read; + if (ReadFile(rom_fh, ROMBaseHost, ROMSize, &bytes_read, NULL) == 0 || bytes_read != ROMSize) { +#else + lseek(rom_fd, 0, SEEK_SET); + if (read(rom_fd, ROMBaseHost, ROMSize) != ROMSize) { +#endif + ErrorAlert(STR_ROM_FILE_READ_ERR); +#ifdef WIN32 + CloseHandle(rom_fh); +#else + close(rom_fd); +#endif + return false; + } + + if (!CheckROM()) { + ErrorAlert(STR_UNSUPPORTED_ROM_TYPE_ERR); + return false; + } + +#if DIRECT_ADDRESSING // Mac address space = host address space minus constant offset (MEMBaseDiff) - // NOTE: MEMBaseDiff is set up in main_unix.cpp/main() - RAMBaseMac = 0; ROMBaseMac = Host2MacAddr(ROMBaseHost); #else // Initialize UAE memory banks - RAMBaseMac = 0; switch (ROMVersion) { case ROM_VERSION_64K: case ROM_VERSION_PLUS: @@ -100,58 +204,62 @@ bool Init680x0(void) } memory_init(); #endif + D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac)); + D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac)); - init_m68k(); -#if USE_JIT - UseJIT = compiler_use_jit(); - if (UseJIT) - compiler_init(); -#endif return true; } +void MacMemExit(void){ + if(RAMBaseHost){ + vm_release(RAMBaseHost, + RAMSize + ScratchMemSize + MAX_ROM_SIZE + VRAMSize + JITCacheSize); + } + RAMBaseHost = NULL; + ROMBaseHost = NULL; + //Exit VM wrappers + vm_exit(); +} /* - * Deinitialize 680x0 emulation + * Initialize 680x0 emulation, CheckROM() must have been called first */ -void Exit680x0(void) -{ +bool Init680x0(void){ + init_m68k(); #if USE_JIT - if (UseJIT) - compiler_exit(); + if(JITCacheSize>0) + compiler_init(MacFrameBaseHost + VRAMSize, JITCacheSize); // put JIT cache after VRAM #endif - exit_m68k(); + return true; } - /* - * Initialize memory mapping of frame buffer (called upon video mode change) + * Deinitialize 680x0 emulation */ -void InitFrameBufferMapping(void) -{ -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING - memory_init(); +void Exit680x0(void){ +#if USE_JIT + if(JITCacheSize>0) + compiler_exit(); #endif + exit_m68k(); } /* * Reset and start 680x0 emulation (doesn't return) */ -void Start680x0(void) -{ +void Start680x0(void){ m68k_reset(); #if USE_JIT - if (UseJIT) - m68k_compile_execute(); - else + if (JITCacheSize>0) + m68k_compile_execute(); + else #endif m68k_execute(); } - /* * Trigger interrupt */ @@ -283,3 +391,19 @@ void report_double_bus_error() CPU_ACTION; #endif } + +#if USE_JIT +extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp +#endif + +/* + * Code was patched, flush caches if neccessary (i.e. when using a real 680x0 + * or a dynamically recompiling emulator) + */ + +void FlushCodeCache(void *start, uint32 size){ +#if USE_JIT + if (JITCacheSize>0) + flush_icache_range((uint8 *)start, size); +#endif +} diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu.h b/BasiliskII/src/uae_cpu_2021/compiler/compemu.h index 62ee94e44..4da6acae0 100644 --- a/BasiliskII/src/uae_cpu_2021/compiler/compemu.h +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu.h @@ -164,9 +164,9 @@ union cacheline { /* Functions exposed to newcpu, or to what was moved from newcpu.c to * compemu_support.c */ #ifdef WINUAE_ARANYM -extern void compiler_init(void); +extern void compiler_init(void*,int); extern void compiler_exit(void); -extern bool compiler_use_jit(void); +extern uint32 compiler_get_jit_cache_size(void); #endif extern void flush(int save_regs); void flush_reg(int reg); diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp index c44fd730c..64f1ea53a 100644 --- a/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp @@ -2899,11 +2899,13 @@ static inline const char *str_on_off(bool b) #ifdef UAE static #endif -void compiler_init(void) -{ +void compiler_init(void* buf, int JITCacheSize){ static bool initialized = false; if (initialized) return; + + compiled_code=(uint8*)buf; + cache_size=JITCacheSize; #ifdef UAE #else @@ -2922,10 +2924,6 @@ void compiler_init(void) #endif jit_log(" : compile FPU instructions : %s", !avoid_fpu ? "yes" : "no"); - // Get size of the translation cache (in KB) - cache_size = PrefsFindInt32("jitcachesize"); - jit_log(" : requested translation cache size : %d KB", cache_size); - setzflg_uses_bsf = target_check_bsf(); jit_log(" : target processor has CMOV instructions : %s", have_cmov ? "yes" : "no"); jit_log(" : target processor can suffer from partial register stalls : %s", have_rat_stall ? "yes" : "no"); @@ -2970,8 +2968,7 @@ void compiler_init(void) #ifdef UAE static #endif -void compiler_exit(void) -{ +void compiler_exit(void){ #ifdef PROFILE_COMPILE_TIME emul_end_time = clock(); #endif @@ -2983,18 +2980,6 @@ void compiler_exit(void) jit_log("data_wasted = %ld bytes", data_wasted); #endif #endif - - // Deallocate translation cache - if (compiled_code) { - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } - - // Deallocate popallspace - if (popallspace) { - vm_release(popallspace, POPALLSPACE_SIZE); - popallspace = 0; - } #endif #ifdef PROFILE_COMPILE_TIME @@ -3051,19 +3036,21 @@ void compiler_exit(void) #ifdef UAE #else -bool compiler_use_jit(void) -{ +// Return bytes needed for JIT cache +uint32 compiler_get_jit_cache_size(void){ // Check for the "jit" prefs item if (!PrefsFindBool("jit")) - return false; - + return 0; + // Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB - if (PrefsFindInt32("jitcachesize") < MIN_CACHE_SIZE) { + uint32 JITCacheSize=PrefsFindInt32("jitcachesize"); + if (JITCacheSize < MIN_CACHE_SIZE) { write_log(" : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE); - return false; + return 0; } - return true; + write_log(" : translation cache size : %d KB\n", JITCacheSize); + return (1024*JITCacheSize) + POPALLSPACE_SIZE; } #endif @@ -3669,10 +3656,6 @@ void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp) forget_about(tmp); } - - - - void set_cache_state(int enabled) { if (enabled!=cache_enabled) @@ -3692,45 +3675,13 @@ uae_u32 get_jitted_size(void) return 0; } -static uint8 *do_alloc_code(uint32 size, int depth) -{ - UNUSED(depth); - uint8 *code = (uint8 *)vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT); - return code == VM_MAP_FAILED ? NULL : code; -} +void alloc_cache(void){ + assert(compiled_code); + assert(cache_size); -static inline uint8 *alloc_code(uint32 size) -{ - uint8 *ptr = do_alloc_code(size, 0); - /* allocated code must fit in 32-bit boundaries */ - assert((uintptr)ptr <= 0xffffffff); - return ptr; -} - -void alloc_cache(void) -{ - if (compiled_code) { - flush_icache_hard(); - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } - -#ifdef UAE - cache_size = currprefs.cachesize; -#endif - if (cache_size == 0) - return; - - while (!compiled_code && cache_size) { - if ((compiled_code = alloc_code(cache_size * 1024)) == NULL) { - compiled_code = 0; - cache_size /= 2; - } - } vm_protect(compiled_code, cache_size * 1024, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE); if (compiled_code) { - jit_log(" : actual translation cache size : %d KB at %p-%p", cache_size, compiled_code, compiled_code + cache_size*1024); #ifdef USE_DATA_BUFFER max_compile_start = compiled_code + cache_size*1024 - BYTES_PER_INST - DATA_BUFFER_SIZE; #else @@ -3979,27 +3930,9 @@ static inline void match_states(blockinfo* bi) } } -static inline void create_popalls(void) -{ +static inline void create_popalls(void){ int i,r; - if (popallspace == NULL) { - if ((popallspace = alloc_code(POPALLSPACE_SIZE)) == NULL) { - jit_log("WARNING: Could not allocate popallspace!"); -#ifdef UAE - if (currprefs.cachesize > 0) -#endif - { - jit_abort("Could not allocate popallspace!"); - } -#ifdef UAE - /* This is not fatal if JIT is not used. If JIT is - * turned on, it will crash, but it would have crashed - * anyway. */ - return; -#endif - } - } vm_protect(popallspace, POPALLSPACE_SIZE, VM_PAGE_READ | VM_PAGE_WRITE); int stack_space = STACK_OFFSET; @@ -4487,8 +4420,8 @@ void build_comp(void) jit_log(" : supposedly %d compileable opcodes!",count); /* Initialise state */ - create_popalls(); alloc_cache(); + create_popalls(); reset_lists(); for (i=0;i Date: Sun, 20 Jun 2021 03:20:36 -0700 Subject: [PATCH 24/24] Fix SheepShaver xcode build --- .../src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj b/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj index 2e90ac44d..f3505a2b8 100755 --- a/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj +++ b/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj @@ -114,7 +114,6 @@ E456E2AD20C82B61006C8DC2 /* clip_macosx64.mm in Sources */ = {isa = PBXBuildFile; fileRef = E456E2AC20C82B60006C8DC2 /* clip_macosx64.mm */; }; E4C9A03E1FD55CDC00CABBF9 /* basic-dyngen-ops-x86_64_macos.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E4C9A03D1FD55CDC00CABBF9 /* basic-dyngen-ops-x86_64_macos.hpp */; }; E4C9A0401FD55CE700CABBF9 /* ppc-dyngen-ops-x86_64_macos.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E4C9A03F1FD55CE700CABBF9 /* ppc-dyngen-ops-x86_64_macos.hpp */; }; - E4CBF46120CFC451009F40CC /* video_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4CBF46020CFC451009F40CC /* video_sdl.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -395,7 +394,6 @@ E4989F3224DE4438004D43E2 /* config-macosx-aarch64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "config-macosx-aarch64.h"; sourceTree = ""; }; E4C9A03D1FD55CDC00CABBF9 /* basic-dyngen-ops-x86_64_macos.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "basic-dyngen-ops-x86_64_macos.hpp"; path = "dyngen_precompiled/basic-dyngen-ops-x86_64_macos.hpp"; sourceTree = ""; }; E4C9A03F1FD55CE700CABBF9 /* ppc-dyngen-ops-x86_64_macos.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "ppc-dyngen-ops-x86_64_macos.hpp"; path = "dyngen_precompiled/ppc-dyngen-ops-x86_64_macos.hpp"; sourceTree = ""; }; - E4CBF46020CFC451009F40CC /* video_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = video_sdl.cpp; path = ../../../BasiliskII/src/SDL/video_sdl.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -763,7 +761,6 @@ 0856CE9114A99EF0000B1711 /* keycodes */, E41936C220CFE64D003A7654 /* SDLMain.h */, E41936C320CFE64D003A7654 /* SDLMain.m */, - E4CBF46020CFC451009F40CC /* video_sdl.cpp */, E413A40220CF7E6D00FBE967 /* video_sdl2.cpp */, ); name = SDL; @@ -1118,7 +1115,6 @@ 0856D07D14A99EF1000B1711 /* timer.cpp in Sources */, 0856D07E14A99EF1000B1711 /* about_window_unix.cpp in Sources */, E44C460720D262B0000583AE /* ip_icmp.c in Sources */, - E4CBF46120CFC451009F40CC /* video_sdl.cpp in Sources */, 0856D09814A99EF1000B1711 /* ether_unix.cpp in Sources */, 0856D0AA14A99EF1000B1711 /* main_unix.cpp in Sources */, E413A40320CF7E6D00FBE967 /* video_sdl2.cpp in Sources */,