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 diff --git a/.gitignore b/.gitignore index 2a6e2f0cb..125df6d3a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,34 @@ # Mac OS X metadata *.DS_Store + +# +# Xcode gitignore settings are from https://github.com/github/gitignore/blob/master/Global/Xcode.gitignore +# + +## Xcode, Build generated +build/ +DerivedData/ + +## Xcode, Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ +xcschemes/ +project.xcworkspace/ + +## Xcode, Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +# +# JetBrains IDE settings +# +*.idea diff --git a/.travis.yml b/.travis.yml index 105af5c06..2529b7120 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,100 +1,61 @@ language: cpp -matrix: +# 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 : - - WITH_SDL=1 - - SDL_MAJOR_VERSION=1 - - ADDRESSING_MODE=direct - - os: linux - dist: bionic - sudo: required - compiler: gcc - env : - - WITH_SDL=1 - - SDL_MAJOR_VERSION=1 - - ADDRESSING_MODE=banks - - os: linux - dist: bionic - sudo: required - compiler: gcc - env : - - WITH_SDL=1 - - SDL_MAJOR_VERSION=2 - - ADDRESSING_MODE=direct + 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 : - - WITH_SDL=1 - - SDL_MAJOR_VERSION=2 - - ADDRESSING_MODE=banks + 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 : - - WITH_SDL=0 - - ADDRESSING_MODE=direct - - os: linux - dist: bionic - sudo: required - compiler: gcc - env : - - WITH_SDL=0 - - ADDRESSING_MODE=banks - - os: osx - compiler: clang - osx_image: xcode12 - env : - - WITH_SDL=0 - - os: osx - compiler: clang - osx_image: xcode12 - env : - - WITH_SDL=1 - -addons: - apt: - packages: - - libsdl1.2-dev - - libgtk2.0-dev - - libsdl2-dev - homebrew: - packages: - - sdl2 - - autoconf - - make - -script: - - ERR_CODE=0 - - cd BasiliskII/src/Unix - - NO_CONFIGURE=1 ./autogen.sh - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - if [[ $WITH_SDL == *"1"* ]]; then - if [[ $SDL_MAJOR_VERSION == *"1"* ]]; then - ./configure --enable-sdl-video --enable-sdl-audio --disable-vosf --disable-jit-compiler --with-x --with-gtk --with-mon --enable-addressing=$ADDRESSING_MODE; - make -j 4 || ERR_CODE=$?; - else - ./configure --enable-sdl-video --enable-sdl-audio --disable-vosf --disable-jit-compiler --with-x --with-gtk --with-mon --with-sdl2 --enable-addressing=$ADDRESSING_MODE; - make -j 4 || ERR_CODE=$?; - fi - else - ./configure --disable-jit-compiler --with-x --with-gtk --with-mon --enable-addressing=$ADDRESSING_MODE; - make -j 4 || ERR_CODE=$?; - fi - else - if [[ $WITH_SDL == *"1"* ]]; then - ./configure --enable-sdl-video --enable-sdl-audio --disable-vosf --disable-jit-compiler --with-gtk=no --with-mon --with-sdl2 --enable-addressing=banks; - make -j 4 || ERR_CODE=$?; - else - ./configure --disable-vosf --disable-jit-compiler --with-gtk=no --with-mon --enable-addressing=banks; - make -j 4 || ERR_CODE=$?; - fi - fi - - (exit $ERR_CODE) + 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 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 /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_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/CrossPlatform/sigsegv.cpp b/BasiliskII/src/CrossPlatform/sigsegv.cpp old mode 100644 new mode 100755 index 0286076f7..fd440c85f --- a/BasiliskII/src/CrossPlatform/sigsegv.cpp +++ b/BasiliskII/src/CrossPlatform/sigsegv.cpp @@ -1019,8 +1019,9 @@ static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs) } #if defined(__x86_64__) || defined(_M_X64) - // addr32 + // Address size override if (*eip == 0x67) { + // 32-bit address eip++; len++; } @@ -2507,6 +2508,14 @@ static bool arm_skip_instruction(unsigned long * regs) } #endif +#ifdef _STRUCT_ARM_THREAD_STATE64 +static bool aarch64_skip_instruction(unsigned long *regs) { + _STRUCT_ARM_THREAD_STATE64 *ts = (_STRUCT_ARM_THREAD_STATE64 *)regs; + if (!ts->__pc) return false; + ts->__pc += 4; + return true; +} +#endif // Fallbacks #ifndef SIGSEGV_FAULT_ADDRESS_FAST @@ -2915,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/sigsegv.h b/BasiliskII/src/CrossPlatform/sigsegv.h index d95ca8340..5bfbfe8e7 100644 --- a/BasiliskII/src/CrossPlatform/sigsegv.h +++ b/BasiliskII/src/CrossPlatform/sigsegv.h @@ -105,6 +105,22 @@ extern "C" { #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction #define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */ #endif + +#ifdef __aarch64__ +#if __DARWIN_UNIX03 && defined _STRUCT_ARM_THREAD_STATE64 +#define MACH_FIELD_NAME(X) __CONCAT(__,X) +#endif +#define SIGSEGV_EXCEPTION_STATE_TYPE arm_exception_state64_t +#define SIGSEGV_EXCEPTION_STATE_FLAVOR ARM_EXCEPTION_STATE64 +#define SIGSEGV_EXCEPTION_STATE_COUNT ARM_EXCEPTION_STATE64_COUNT +#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(far) +#define SIGSEGV_THREAD_STATE_TYPE arm_thread_state64_t +#define SIGSEGV_THREAD_STATE_FLAVOR ARM_THREAD_STATE64 +#define SIGSEGV_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(x[0])) /* x[0] is the first GPR we consider */ +#define SIGSEGV_SKIP_INSTRUCTION aarch64_skip_instruction +#endif + #ifdef __x86_64__ #define SIGSEGV_FAULT_ADDRESS_FAST (((uint64_t)code[1])|0x100000000) #else diff --git a/BasiliskII/src/CrossPlatform/video_blit.cpp b/BasiliskII/src/CrossPlatform/video_blit.cpp old mode 100644 new mode 100755 index 83c12e076..eab372241 --- a/BasiliskII/src/CrossPlatform/video_blit.cpp +++ b/BasiliskII/src/CrossPlatform/video_blit.cpp @@ -22,6 +22,10 @@ #include "video.h" #include "video_blit.h" +#if USE_SDL_VIDEO +#include +#endif + #include #include @@ -512,18 +516,25 @@ 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 +#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 Screen_blit = Blit_Copy_Raw; + +#if !DIRECT_ADDRESSING + } else if (mac_depth == 16) { + + Screen_blit = Blit_Copy_Raw; + +#endif + } else { // Compute RGB shift values diff --git a/BasiliskII/src/CrossPlatform/video_vosf.h b/BasiliskII/src/CrossPlatform/video_vosf.h index f99b44bf5..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; @@ -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 @@ -246,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() } @@ -263,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))); } @@ -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 = MacFrameBaseHost; mainBuffer.memLength = the_buffer_size; mainBuffer.pageSize = page_size; @@ -349,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); @@ -388,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); } } @@ -416,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; @@ -513,7 +513,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; } @@ -535,13 +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 @@ -555,11 +554,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; } @@ -574,8 +573,10 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) 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 = src_bytes_per_row / n_chunks; - const uint32 dst_chunk_size = dst_bytes_per_row / n_chunks; + 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); @@ -605,7 +606,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 @@ -619,9 +620,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) { @@ -639,12 +640,10 @@ 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); } - i1 += src_chunk_size_left; - i2 += dst_chunk_size_left; #ifdef USE_SDL_VIDEO const int x = n_chunks * n_pixels; if (x < bb[bbi].x) { @@ -658,7 +657,8 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT) bb[bbi].w = x + n_pixels_left - bb[bbi].x; #endif } - i2 += scr_bytes_left; + 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)) { diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp old mode 100644 new mode 100755 index 005cb727c..c85835905 --- 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,27 +76,16 @@ typedef unsigned long vm_uintptr_t; #define MAP_ANONYMOUS 0 #endif -#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 -#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 @@ -112,15 +94,12 @@ 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; 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; @@ -226,16 +205,10 @@ 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; - // 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; @@ -252,14 +225,14 @@ 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) - return VM_MAP_FAILED; - - // Sanity checks for 64-bit platforms - if (sizeof(void *) == 8 && (options & VM_MAP_32BIT) && !((char *)addr <= (char *)0xffffffff)) + if ((addr = mmap(addr, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0))==(void*)MAP_FAILED) return VM_MAP_FAILED; - next_address = (char *)addr + size; + // 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); + #elif defined(HAVE_WIN32_VM) int alloc_type = MEM_RESERVE | MEM_COMMIT; if (options & VM_MAP_WRITE_WATCH) @@ -283,63 +256,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 c44e853be..ec0b594b0 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) @@ -55,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 @@ -99,11 +100,6 @@ extern void vm_exit(void); extern void * vm_acquire(size_t size, int options = VM_MAP_DEFAULT); -/* 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/AudioDevice.cpp b/BasiliskII/src/MacOSX/AudioDevice.cpp index 9fe065f67..7b6e860e6 100644 --- a/BasiliskII/src/MacOSX/AudioDevice.cpp +++ b/BasiliskII/src/MacOSX/AudioDevice.cpp @@ -51,23 +51,23 @@ void AudioDevice::Init(AudioDeviceID devid, bool isInput) UInt32 propsize; propsize = sizeof(UInt32); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset)); + __Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset)); propsize = sizeof(UInt32); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames)); + __Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames)); propsize = sizeof(AudioStreamBasicDescription); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat)); + __Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat)); } void AudioDevice::SetBufferSize(UInt32 size) { UInt32 propsize = sizeof(UInt32); - verify_noerr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size)); + __Verify_noErr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size)); propsize = sizeof(UInt32); - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames)); + __Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames)); } int AudioDevice::CountChannels() @@ -92,6 +92,6 @@ int AudioDevice::CountChannels() char * AudioDevice::GetName(char *buf, UInt32 maxlen) { - verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf)); + __Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf)); return buf; } diff --git a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj index 54a3e0473..a52057595 100644 --- a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj +++ b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj @@ -7,15 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 5D5C3B0A24B2DF3500CDAB41 /* bincue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D5C3B0924B2DF3400CDAB41 /* bincue.cpp */; }; 752F26F91F240E51001032B4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 752F26F81F240E51001032B4 /* Foundation.framework */; }; 752F26FB1F240E69001032B4 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 752F26FA1F240E69001032B4 /* IOKit.framework */; }; 752F27011F242BAF001032B4 /* prefs_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 752F27001F242BAF001032B4 /* prefs_sdl.cpp */; }; 752F27031F242F51001032B4 /* xpram_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 752F27021F242F51001032B4 /* xpram_sdl.cpp */; }; - 753253311F5368370024025B /* cpuemu_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7532532C1F5368370024025B /* cpuemu_nf.cpp */; }; - 753253321F5368370024025B /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7532532D1F5368370024025B /* cpuemu.cpp */; }; - 753253331F5368370024025B /* cpustbl_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7532532E1F5368370024025B /* cpustbl_nf.cpp */; }; - 753253341F5368370024025B /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7532532F1F5368370024025B /* cpustbl.cpp */; }; - 753253351F53688D0024025B /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0CE1F23B25A006B2DF2 /* readcpu.cpp */; }; 7539E1251F23B25A006B2DF2 /* adb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539DFC91F23B25A006B2DF2 /* adb.cpp */; }; 7539E1261F23B25A006B2DF2 /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539DFCA1F23B25A006B2DF2 /* audio.cpp */; }; 7539E1271F23B25A006B2DF2 /* cdrom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539DFCB1F23B25A006B2DF2 /* cdrom.cpp */; }; @@ -40,16 +36,9 @@ 7539E18D1F23B25A006B2DF2 /* slot_rom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0A21F23B25A006B2DF2 /* slot_rom.cpp */; }; 7539E18E1F23B25A006B2DF2 /* sony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0A31F23B25A006B2DF2 /* sony.cpp */; }; 7539E18F1F23B25A006B2DF2 /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0A41F23B25A006B2DF2 /* timer.cpp */; }; - 7539E1901F23B25A006B2DF2 /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0A61F23B25A006B2DF2 /* basilisk_glue.cpp */; }; - 7539E1981F23B25A006B2DF2 /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0B51F23B25A006B2DF2 /* exceptions.cpp */; }; - 7539E1991F23B25A006B2DF2 /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0B71F23B25A006B2DF2 /* flags.cpp */; }; - 7539E19D1F23B25A006B2DF2 /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0C21F23B25A006B2DF2 /* mathlib.cpp */; }; - 7539E19E1F23B25A006B2DF2 /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0C41F23B25A006B2DF2 /* rounding.cpp */; }; - 7539E1A01F23B25A006B2DF2 /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0C91F23B25A006B2DF2 /* memory.cpp */; }; 7539E1E11F23B25A006B2DF2 /* user_strings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E1221F23B25A006B2DF2 /* user_strings.cpp */; }; 7539E1E21F23B25A006B2DF2 /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E1231F23B25A006B2DF2 /* video.cpp */; }; 7539E1E31F23B25A006B2DF2 /* xpram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E1241F23B25A006B2DF2 /* xpram.cpp */; }; - 7539E23F1F23B32A006B2DF2 /* bincue_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E1F01F23B329006B2DF2 /* bincue_unix.cpp */; }; 7539E24A1F23B32A006B2DF2 /* disk_sparsebundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E1FD1F23B32A006B2DF2 /* disk_sparsebundle.cpp */; }; 7539E2681F23B32A006B2DF2 /* rpc_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2241F23B32A006B2DF2 /* rpc_unix.cpp */; }; 7539E26C1F23B32A006B2DF2 /* sshpty.c in Sources */ = {isa = PBXBuildFile; fileRef = 7539E22A1F23B32A006B2DF2 /* sshpty.c */; }; @@ -61,13 +50,11 @@ 7539E2911F23C56F006B2DF2 /* prefs_editor_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2881F23C56F006B2DF2 /* prefs_editor_dummy.cpp */; }; 7539E2921F23C56F006B2DF2 /* scsi_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2891F23C56F006B2DF2 /* scsi_dummy.cpp */; }; 7539E2931F23C56F006B2DF2 /* serial_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E28A1F23C56F006B2DF2 /* serial_dummy.cpp */; }; - 7539E2971F23C5FD006B2DF2 /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2961F23C5FD006B2DF2 /* newcpu.cpp */; }; 7539E29D1F23C83F006B2DF2 /* sys_darwin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E29C1F23C83F006B2DF2 /* sys_darwin.cpp */; }; 756C1B341F252FC100620917 /* utils_macosx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 756C1B331F252FC100620917 /* utils_macosx.mm */; }; 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 */; }; @@ -94,12 +81,42 @@ E416BEE82410AA4E00751E6D /* runtool.c in Sources */ = {isa = PBXBuildFile; fileRef = E416BEE72410AA4E00751E6D /* runtool.c */; }; E416BEEA2410AA9800751E6D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E416BEE92410AA9800751E6D /* Security.framework */; }; E416BEED2410AE0900751E6D /* etherhelpertool in Resources */ = {isa = PBXBuildFile; fileRef = E416BEEC2410AE0000751E6D /* etherhelpertool */; }; + E447066D25D8FCB400EA2C14 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E447066C25D8FCB400EA2C14 /* Metal.framework */; }; E4555EED2354434B00139FCE /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = 7539E00A1F23B25A006B2DF2 /* Credits.html */; }; E490334E20D3A5890012DD5F /* clip_macosx64.mm in Sources */ = {isa = PBXBuildFile; fileRef = E490334D20D3A5890012DD5F /* clip_macosx64.mm */; }; - E4D8245323543D9800849B78 /* fpu_ieee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D8245223543D9700849B78 /* fpu_ieee.cpp */; }; - E4EE777523D7D71400BAE63A /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E417913123D7D67C0009AD63 /* defs68k.c */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + E45769AC2643A65B0063BAF1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E45769A82643A65B0063BAF1 /* uae_cpu.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E4F537C02642A86D008B27DF; + remoteInfo = uae_cpu_x86_64; + }; + E45769B92643A6740063BAF1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E45769B52643A6740063BAF1 /* uae_cpu_2021.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E41D7AA12642C004005E8093; + remoteInfo = uae_cpu_arm64; + }; + E45769BC2643A6870063BAF1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E45769A82643A65B0063BAF1 /* uae_cpu.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = E4F537BF2642A86D008B27DF; + remoteInfo = uae_cpu_x86_64; + }; + E45769BE2643A68B0063BAF1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E45769B52643A6740063BAF1 /* uae_cpu_2021.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = E41D7AA02642C004005E8093; + remoteInfo = uae_cpu_arm64; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 752F26F31F240140001032B4 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -115,17 +132,19 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 5D5C3B0924B2DF3400CDAB41 /* bincue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bincue.cpp; path = ../bincue.cpp; sourceTree = ""; }; + 5D5C3B0B24B2DF4200CDAB41 /* bincue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bincue.h; sourceTree = ""; }; + 5DDE95122255D075004D0E79 /* AudioBackEnd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioBackEnd.h; sourceTree = ""; }; + 5DDE95132255D076004D0E79 /* AudioDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDevice.cpp; sourceTree = ""; }; + 5DDE95142255D076004D0E79 /* AudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDevice.h; sourceTree = ""; }; + 5DDE95152255D076004D0E79 /* audio_macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio_macosx.cpp; sourceTree = ""; }; + 5DDE95162255D076004D0E79 /* MacOSX_sound_if.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacOSX_sound_if.cpp; sourceTree = ""; }; + 5DDE95172255D076004D0E79 /* AudioBackEnd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioBackEnd.cpp; sourceTree = ""; }; + 5DDE95182255D076004D0E79 /* MacOSX_sound_if.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacOSX_sound_if.h; sourceTree = ""; }; 752F26F81F240E51001032B4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 752F26FA1F240E69001032B4 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 752F27001F242BAF001032B4 /* prefs_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prefs_sdl.cpp; sourceTree = ""; }; 752F27021F242F51001032B4 /* xpram_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xpram_sdl.cpp; sourceTree = ""; }; - 753252E51F5359040024025B /* build68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = build68k.c; sourceTree = ""; }; - 753253011F535F210024025B /* gencpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gencpu.c; sourceTree = ""; }; - 7532532C1F5368370024025B /* cpuemu_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu_nf.cpp; path = gencpu_output/cpuemu_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; - 7532532D1F5368370024025B /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; - 7532532E1F5368370024025B /* cpustbl_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl_nf.cpp; path = gencpu_output/cpustbl_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; - 7532532F1F5368370024025B /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; - 753253301F5368370024025B /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; }; 7539DFB21F23B17E006B2DF2 /* BasiliskII.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BasiliskII.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7539DFC91F23B25A006B2DF2 /* adb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adb.cpp; path = ../adb.cpp; sourceTree = ""; }; 7539DFCA1F23B25A006B2DF2 /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio.cpp; path = ../audio.cpp; sourceTree = ""; }; @@ -194,40 +213,9 @@ 7539E0A21F23B25A006B2DF2 /* slot_rom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = slot_rom.cpp; path = ../slot_rom.cpp; sourceTree = ""; }; 7539E0A31F23B25A006B2DF2 /* sony.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sony.cpp; path = ../sony.cpp; sourceTree = ""; }; 7539E0A41F23B25A006B2DF2 /* timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timer.cpp; path = ../timer.cpp; sourceTree = ""; }; - 7539E0A61F23B25A006B2DF2 /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = basilisk_glue.cpp; sourceTree = ""; }; - 7539E0AB1F23B25A006B2DF2 /* compemu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compemu.h; sourceTree = ""; }; - 7539E0AE1F23B25A006B2DF2 /* flags_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flags_x86.h; sourceTree = ""; }; - 7539E0B11F23B25A006B2DF2 /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu_emulation.h; sourceTree = ""; }; - 7539E0B41F23B25A006B2DF2 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = core.h; sourceTree = ""; }; - 7539E0B51F23B25A006B2DF2 /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exceptions.cpp; sourceTree = ""; }; - 7539E0B61F23B25A006B2DF2 /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exceptions.h; sourceTree = ""; }; - 7539E0B71F23B25A006B2DF2 /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = flags.cpp; sourceTree = ""; }; - 7539E0B81F23B25A006B2DF2 /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flags.h; sourceTree = ""; }; - 7539E0B91F23B25A006B2DF2 /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fpu.h; sourceTree = ""; }; - 7539E0BB1F23B25A006B2DF2 /* fpu_ieee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fpu_ieee.h; sourceTree = ""; }; - 7539E0BD1F23B25A006B2DF2 /* fpu_uae.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fpu_uae.h; sourceTree = ""; }; - 7539E0BF1F23B25A006B2DF2 /* fpu_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fpu_x86.h; sourceTree = ""; }; - 7539E0C01F23B25A006B2DF2 /* fpu_x86_asm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fpu_x86_asm.h; sourceTree = ""; }; - 7539E0C11F23B25A006B2DF2 /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = impl.h; sourceTree = ""; }; - 7539E0C21F23B25A006B2DF2 /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mathlib.cpp; sourceTree = ""; }; - 7539E0C31F23B25A006B2DF2 /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mathlib.h; sourceTree = ""; }; - 7539E0C41F23B25A006B2DF2 /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rounding.cpp; sourceTree = ""; }; - 7539E0C51F23B25A006B2DF2 /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rounding.h; sourceTree = ""; }; - 7539E0C61F23B25A006B2DF2 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; - 7539E0C81F23B25A006B2DF2 /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m68k.h; sourceTree = ""; }; - 7539E0C91F23B25A006B2DF2 /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = ""; }; - 7539E0CA1F23B25A006B2DF2 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = ""; }; - 7539E0CC1F23B25A006B2DF2 /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = newcpu.h; sourceTree = ""; }; - 7539E0CD1F23B25A006B2DF2 /* noflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noflags.h; sourceTree = ""; }; - 7539E0CE1F23B25A006B2DF2 /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = readcpu.cpp; sourceTree = ""; }; - 7539E0CF1F23B25A006B2DF2 /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = readcpu.h; sourceTree = ""; }; - 7539E0D01F23B25A006B2DF2 /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spcflags.h; sourceTree = ""; }; - 7539E0D11F23B25A006B2DF2 /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = table68k; sourceTree = ""; }; 7539E1221F23B25A006B2DF2 /* user_strings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = user_strings.cpp; path = ../user_strings.cpp; sourceTree = ""; }; 7539E1231F23B25A006B2DF2 /* video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = video.cpp; path = ../video.cpp; sourceTree = ""; }; 7539E1241F23B25A006B2DF2 /* xpram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xpram.cpp; path = ../xpram.cpp; sourceTree = ""; }; - 7539E1F01F23B329006B2DF2 /* bincue_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bincue_unix.cpp; sourceTree = ""; }; - 7539E1F11F23B329006B2DF2 /* bincue_unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bincue_unix.h; sourceTree = ""; }; 7539E1F81F23B329006B2DF2 /* gtk-osx.patch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "gtk-osx.patch"; sourceTree = ""; }; 7539E1FA1F23B32A006B2DF2 /* mkstandalone */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = mkstandalone; sourceTree = ""; }; 7539E1FC1F23B32A006B2DF2 /* testlmem.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = testlmem.sh; sourceTree = ""; }; @@ -239,7 +227,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 = ""; }; @@ -267,7 +254,6 @@ 7539E2881F23C56F006B2DF2 /* prefs_editor_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prefs_editor_dummy.cpp; sourceTree = ""; }; 7539E2891F23C56F006B2DF2 /* scsi_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scsi_dummy.cpp; sourceTree = ""; }; 7539E28A1F23C56F006B2DF2 /* serial_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = serial_dummy.cpp; sourceTree = ""; }; - 7539E2961F23C5FD006B2DF2 /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = newcpu.cpp; sourceTree = ""; }; 7539E29C1F23C83F006B2DF2 /* sys_darwin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sys_darwin.cpp; sourceTree = ""; }; 7539E2AA1F23CDB7006B2DF2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 756C1B321F252FC100620917 /* utils_macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils_macosx.h; sourceTree = ""; }; @@ -275,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 = ""; }; @@ -284,7 +269,7 @@ E413D8FB20D260B900E437D8 /* ip_icmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ip_icmp.c; sourceTree = ""; }; E413D8FC20D260B900E437D8 /* bootp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootp.h; sourceTree = ""; }; E413D8FD20D260B900E437D8 /* tcpip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcpip.h; sourceTree = ""; }; - E413D8FE20D260B900E437D8 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = ""; }; + E413D8FE20D260B900E437D8 /* VERSION_ */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION_; sourceTree = ""; }; E413D8FF20D260B900E437D8 /* ip_icmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ip_icmp.h; sourceTree = ""; }; E413D90020D260B900E437D8 /* slirp_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slirp_config.h; sourceTree = ""; }; E413D90120D260B900E437D8 /* tcp_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp_input.c; sourceTree = ""; }; @@ -327,9 +312,10 @@ E416BEE92410AA9800751E6D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; E416BEEB2410AB0E00751E6D /* etherhelpertool.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = etherhelpertool.c; sourceTree = ""; }; E416BEEC2410AE0000751E6D /* etherhelpertool */ = {isa = PBXFileReference; lastKnownFileType = text; path = etherhelpertool; sourceTree = BUILT_PRODUCTS_DIR; }; - E417913123D7D67C0009AD63 /* defs68k.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; }; + E447066C25D8FCB400EA2C14 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + E45769A82643A65B0063BAF1 /* uae_cpu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = uae_cpu.xcodeproj; sourceTree = ""; }; + E45769B52643A6740063BAF1 /* uae_cpu_2021.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = uae_cpu_2021.xcodeproj; sourceTree = ""; }; E490334D20D3A5890012DD5F /* clip_macosx64.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = clip_macosx64.mm; sourceTree = ""; }; - E4D8245223543D9700849B78 /* fpu_ieee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fpu_ieee.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -341,6 +327,7 @@ E416BEEA2410AA9800751E6D /* Security.framework in Frameworks */, 756C1B391F25306A00620917 /* AppKit.framework in Frameworks */, 752F26FB1F240E69001032B4 /* IOKit.framework in Frameworks */, + E447066D25D8FCB400EA2C14 /* Metal.framework in Frameworks */, 752F26F91F240E51001032B4 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -391,7 +378,7 @@ E413D8FA20D260B900E437D8 /* tftp.h */, E413D90720D260BA00E437D8 /* udp.c */, E413D90320D260BA00E437D8 /* udp.h */, - E413D8FE20D260B900E437D8 /* VERSION */, + E413D8FE20D260B900E437D8 /* VERSION_ */, ); name = slirp; path = ../slirp; @@ -400,6 +387,7 @@ 752F26F71F240E51001032B4 /* Frameworks */ = { isa = PBXGroup; children = ( + E447066C25D8FCB400EA2C14 /* Metal.framework */, E416BEE92410AA9800751E6D /* Security.framework */, E413D93520D260DA00E437D8 /* SDL2.framework */, 756C1B381F25306A00620917 /* AppKit.framework */, @@ -413,27 +401,15 @@ isa = PBXGroup; children = ( E416BEEC2410AE0000751E6D /* etherhelpertool */, - 7532532B1F53675E0024025B /* gencpu output */, ); name = "generated src"; sourceTree = ""; }; - 7532532B1F53675E0024025B /* gencpu output */ = { - isa = PBXGroup; - children = ( - 7532532C1F5368370024025B /* cpuemu_nf.cpp */, - 7532532D1F5368370024025B /* cpuemu.cpp */, - 7532532E1F5368370024025B /* cpustbl_nf.cpp */, - 7532532F1F5368370024025B /* cpustbl.cpp */, - 753253301F5368370024025B /* cputbl.h */, - E417913123D7D67C0009AD63 /* defs68k.c */, - ); - name = "gencpu output"; - sourceTree = ""; - }; 7539DFA91F23B17E006B2DF2 = { isa = PBXGroup; children = ( + E45769A82643A65B0063BAF1 /* uae_cpu.xcodeproj */, + E45769B52643A6740063BAF1 /* uae_cpu_2021.xcodeproj */, E4150D1320D559800077C51A /* SDL2.framework */, 7539E1E41F23B25E006B2DF2 /* src */, 753252FF1F535E5D0024025B /* generated src */, @@ -472,6 +448,7 @@ 7539DFD91F23B25A006B2DF2 /* adb.h */, 7539DFDA1F23B25A006B2DF2 /* audio.h */, 7539DFDB1F23B25A006B2DF2 /* audio_defs.h */, + 5D5C3B0B24B2DF4200CDAB41 /* bincue.h */, 7539DFDC1F23B25A006B2DF2 /* cdrom.h */, 7539DFDD1F23B25A006B2DF2 /* clip.h */, 7539DFDE1F23B25A006B2DF2 /* debug.h */, @@ -525,6 +502,13 @@ 756C1B321F252FC100620917 /* utils_macosx.h */, 756C1B331F252FC100620917 /* utils_macosx.mm */, 7539E02E1F23B25A006B2DF2 /* Versions.html */, + 5DDE95152255D076004D0E79 /* audio_macosx.cpp */, + 5DDE95172255D076004D0E79 /* AudioBackEnd.cpp */, + 5DDE95122255D075004D0E79 /* AudioBackEnd.h */, + 5DDE95132255D076004D0E79 /* AudioDevice.cpp */, + 5DDE95142255D076004D0E79 /* AudioDevice.h */, + 5DDE95162255D076004D0E79 /* MacOSX_sound_if.cpp */, + 5DDE95182255D076004D0E79 /* MacOSX_sound_if.h */, ); name = MacOSX; sourceTree = ""; @@ -537,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 */, ); @@ -545,68 +528,12 @@ path = ../SDL; sourceTree = ""; }; - 7539E0A51F23B25A006B2DF2 /* uae_cpu */ = { - isa = PBXGroup; - children = ( - 7539E0A61F23B25A006B2DF2 /* basilisk_glue.cpp */, - 753252E51F5359040024025B /* build68k.c */, - 7539E0A81F23B25A006B2DF2 /* compiler */, - 7539E0B11F23B25A006B2DF2 /* cpu_emulation.h */, - 7539E0B31F23B25A006B2DF2 /* fpu */, - 753253011F535F210024025B /* gencpu.c */, - 7539E0C81F23B25A006B2DF2 /* m68k.h */, - 7539E0C91F23B25A006B2DF2 /* memory.cpp */, - 7539E0CA1F23B25A006B2DF2 /* memory.h */, - 7539E2961F23C5FD006B2DF2 /* newcpu.cpp */, - 7539E0CC1F23B25A006B2DF2 /* newcpu.h */, - 7539E0CD1F23B25A006B2DF2 /* noflags.h */, - 7539E0CE1F23B25A006B2DF2 /* readcpu.cpp */, - 7539E0CF1F23B25A006B2DF2 /* readcpu.h */, - 7539E0D01F23B25A006B2DF2 /* spcflags.h */, - 7539E0D11F23B25A006B2DF2 /* table68k */, - ); - name = uae_cpu; - path = ../uae_cpu; - sourceTree = ""; - }; - 7539E0A81F23B25A006B2DF2 /* compiler */ = { - isa = PBXGroup; - children = ( - 7539E0AB1F23B25A006B2DF2 /* compemu.h */, - 7539E0AE1F23B25A006B2DF2 /* flags_x86.h */, - ); - path = compiler; - sourceTree = ""; - }; - 7539E0B31F23B25A006B2DF2 /* fpu */ = { - isa = PBXGroup; - children = ( - E4D8245223543D9700849B78 /* fpu_ieee.cpp */, - 7539E0B41F23B25A006B2DF2 /* core.h */, - 7539E0B51F23B25A006B2DF2 /* exceptions.cpp */, - 7539E0B61F23B25A006B2DF2 /* exceptions.h */, - 7539E0B71F23B25A006B2DF2 /* flags.cpp */, - 7539E0B81F23B25A006B2DF2 /* flags.h */, - 7539E0B91F23B25A006B2DF2 /* fpu.h */, - 7539E0BB1F23B25A006B2DF2 /* fpu_ieee.h */, - 7539E0BD1F23B25A006B2DF2 /* fpu_uae.h */, - 7539E0BF1F23B25A006B2DF2 /* fpu_x86.h */, - 7539E0C01F23B25A006B2DF2 /* fpu_x86_asm.h */, - 7539E0C11F23B25A006B2DF2 /* impl.h */, - 7539E0C21F23B25A006B2DF2 /* mathlib.cpp */, - 7539E0C31F23B25A006B2DF2 /* mathlib.h */, - 7539E0C41F23B25A006B2DF2 /* rounding.cpp */, - 7539E0C51F23B25A006B2DF2 /* rounding.h */, - 7539E0C61F23B25A006B2DF2 /* types.h */, - ); - path = fpu; - sourceTree = ""; - }; 7539E1E41F23B25E006B2DF2 /* src */ = { isa = PBXGroup; children = ( 7539DFC91F23B25A006B2DF2 /* adb.cpp */, 7539DFCA1F23B25A006B2DF2 /* audio.cpp */, + 5D5C3B0924B2DF3400CDAB41 /* bincue.cpp */, 7539DFCB1F23B25A006B2DF2 /* cdrom.cpp */, 7539DFCC1F23B25A006B2DF2 /* CrossPlatform */, 7539DFD41F23B25A006B2DF2 /* disk.cpp */, @@ -630,7 +557,6 @@ 7539E0A21F23B25A006B2DF2 /* slot_rom.cpp */, 7539E0A31F23B25A006B2DF2 /* sony.cpp */, 7539E0A41F23B25A006B2DF2 /* timer.cpp */, - 7539E0A51F23B25A006B2DF2 /* uae_cpu */, 7539E1E91F23B329006B2DF2 /* Unix */, 7539E1221F23B25A006B2DF2 /* user_strings.cpp */, 7539E1231F23B25A006B2DF2 /* video.cpp */, @@ -642,8 +568,6 @@ 7539E1E91F23B329006B2DF2 /* Unix */ = { isa = PBXGroup; children = ( - 7539E1F01F23B329006B2DF2 /* bincue_unix.cpp */, - 7539E1F11F23B329006B2DF2 /* bincue_unix.h */, 7539E1F71F23B329006B2DF2 /* Darwin */, 7539E1FD1F23B32A006B2DF2 /* disk_sparsebundle.cpp */, 7539E1FE1F23B32A006B2DF2 /* disk_unix.h */, @@ -692,7 +616,6 @@ 7539E20C1F23B32A006B2DF2 /* freebsd-i386.ld */, 7539E20D1F23B32A006B2DF2 /* linux-i386.ld */, 7539E20E1F23B32A006B2DF2 /* linux-ppc.ld */, - 7539E20F1F23B32A006B2DF2 /* linux-x86_64.ld */, ); path = ldscripts; sourceTree = ""; @@ -721,6 +644,22 @@ path = ../dummy; sourceTree = ""; }; + E45769A92643A65B0063BAF1 /* Products */ = { + isa = PBXGroup; + children = ( + E45769AD2643A65B0063BAF1 /* libuae_cpu_x86_64.a */, + ); + name = Products; + sourceTree = ""; + }; + E45769B62643A6740063BAF1 /* Products */ = { + isa = PBXGroup; + children = ( + E45769BA2643A6740063BAF1 /* libuae_cpu_arm64.a */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -737,6 +676,8 @@ buildRules = ( ); dependencies = ( + E45769BF2643A68B0063BAF1 /* PBXTargetDependency */, + E45769BD2643A6870063BAF1 /* PBXTargetDependency */, ); name = BasiliskII; productName = BasiliskII; @@ -769,6 +710,16 @@ mainGroup = 7539DFA91F23B17E006B2DF2; productRefGroup = 7539DFB31F23B17E006B2DF2 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = E45769A92643A65B0063BAF1 /* Products */; + ProjectRef = E45769A82643A65B0063BAF1 /* uae_cpu.xcodeproj */; + }, + { + ProductGroup = E45769B62643A6740063BAF1 /* Products */; + ProjectRef = E45769B52643A6740063BAF1 /* uae_cpu_2021.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 7539DFB11F23B17E006B2DF2 /* BasiliskII */, @@ -776,6 +727,23 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + E45769AD2643A65B0063BAF1 /* libuae_cpu_x86_64.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libuae_cpu_x86_64.a; + remoteRef = E45769AC2643A65B0063BAF1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E45769BA2643A6740063BAF1 /* libuae_cpu_arm64.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libuae_cpu_arm64.a; + remoteRef = E45769B92643A6740063BAF1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 7539DFB01F23B17E006B2DF2 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -799,15 +767,10 @@ ); name = "Run Script"; outputPaths = ( - $BUILT_PRODUCTS_DIR/gencpu_output/cpuemu.cpp, - $BUILT_PRODUCTS_DIR/gencpu_output/cpuemu_nf.cpp, - $BUILT_PRODUCTS_DIR/gencpu_output/cpustbl.cpp, - $BUILT_PRODUCTS_DIR/gencpu_output/cpustbl_nf.cpp, - $BUILT_PRODUCTS_DIR/gencpu_output/defs68k.c, ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "make -f Makefile.gencpu\ncc etherhelpertool.c -framework Security -o $BUILT_PRODUCTS_DIR/etherhelpertool\n"; + shellScript = "cc etherhelpertool.c -framework Security -o $BUILT_PRODUCTS_DIR/etherhelpertool\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -816,47 +779,35 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E4EE777523D7D71400BAE63A /* defs68k.c in Sources */, - 7539E19E1F23B25A006B2DF2 /* rounding.cpp in Sources */, 7539E29D1F23C83F006B2DF2 /* sys_darwin.cpp in Sources */, 7539E1291F23B25A006B2DF2 /* video_blit.cpp in Sources */, E413D93320D260BC00E437D8 /* cksum.c in Sources */, E413D92920D260BC00E437D8 /* udp.c in Sources */, - E4D8245323543D9800849B78 /* fpu_ieee.cpp in Sources */, - 7539E1A01F23B25A006B2DF2 /* memory.cpp in Sources */, E40CEEC620D7910E00BCB88D /* SDLMain.m in Sources */, - 753253351F53688D0024025B /* readcpu.cpp in Sources */, 7539E1741F23B25A006B2DF2 /* audio_sdl.cpp in Sources */, E413D93120D260BC00E437D8 /* ip_output.c in Sources */, 7539E1E21F23B25A006B2DF2 /* video.cpp in Sources */, 7539E18F1F23B25A006B2DF2 /* timer.cpp in Sources */, 7539E1711F23B25A006B2DF2 /* rom_patches.cpp in Sources */, 7539E1281F23B25A006B2DF2 /* sigsegv.cpp in Sources */, - 753253341F5368370024025B /* cpustbl.cpp in Sources */, 756C1B341F252FC100620917 /* utils_macosx.mm in Sources */, E413D92620D260BC00E437D8 /* misc.c in Sources */, - 753253321F5368370024025B /* cpuemu.cpp in Sources */, 7539E2701F23B32A006B2DF2 /* tinyxml2.cpp in Sources */, 7539E1721F23B25A006B2DF2 /* rsrc_patches.cpp in Sources */, + 5D5C3B0A24B2DF3500CDAB41 /* bincue.cpp in Sources */, 7539E2931F23C56F006B2DF2 /* serial_dummy.cpp in Sources */, - 7539E1981F23B25A006B2DF2 /* exceptions.cpp in Sources */, - 75CBCF771F5DB65E00830063 /* video_sdl.cpp in Sources */, - 7539E1901F23B25A006B2DF2 /* basilisk_glue.cpp in Sources */, 7539E2801F23C4CA006B2DF2 /* main_unix.cpp in Sources */, 7539E1E11F23B25A006B2DF2 /* user_strings.cpp in Sources */, 75CBCF751F5DB3AD00830063 /* video_sdl2.cpp in Sources */, 752F27011F242BAF001032B4 /* prefs_sdl.cpp in Sources */, - 7539E2971F23C5FD006B2DF2 /* newcpu.cpp in Sources */, 7539E12A1F23B25A006B2DF2 /* vm_alloc.cpp in Sources */, E413D93220D260BC00E437D8 /* if.c in Sources */, - 753253331F5368370024025B /* cpustbl_nf.cpp in Sources */, 7539E16C1F23B25A006B2DF2 /* main.cpp in Sources */, 7539E26D1F23B32A006B2DF2 /* strlcpy.c in Sources */, E413D93420D260BC00E437D8 /* tcp_output.c in Sources */, 7539E26E1F23B32A006B2DF2 /* sys_unix.cpp in Sources */, 7539E1271F23B25A006B2DF2 /* cdrom.cpp in Sources */, E413D92A20D260BC00E437D8 /* sbuf.c in Sources */, - 753253311F5368370024025B /* cpuemu_nf.cpp in Sources */, 7539E1261F23B25A006B2DF2 /* audio.cpp in Sources */, E413D93820D2613500E437D8 /* ether_unix.cpp in Sources */, 7539E1701F23B25A006B2DF2 /* prefs.cpp in Sources */, @@ -867,18 +818,15 @@ 757A2BF01F5AF9D6003EDB01 /* user_strings_unix.cpp in Sources */, E413D92D20D260BC00E437D8 /* tcp_timer.c in Sources */, E413D92820D260BC00E437D8 /* tcp_subr.c in Sources */, - 7539E1991F23B25A006B2DF2 /* flags.cpp in Sources */, 7539E2921F23C56F006B2DF2 /* scsi_dummy.cpp in Sources */, E413D93A20D2614E00E437D8 /* extfs_macosx.cpp in Sources */, 7539E16F1F23B25A006B2DF2 /* prefs_items.cpp in Sources */, 7539E18E1F23B25A006B2DF2 /* sony.cpp in Sources */, 7539E26F1F23B32A006B2DF2 /* timer_unix.cpp in Sources */, 7539E12E1F23B25A006B2DF2 /* extfs.cpp in Sources */, - 7539E23F1F23B32A006B2DF2 /* bincue_unix.cpp in Sources */, 7539E12C1F23B25A006B2DF2 /* emul_op.cpp in Sources */, E413D92720D260BC00E437D8 /* debug.c in Sources */, E413D92220D260BC00E437D8 /* mbuf.c in Sources */, - 7539E19D1F23B25A006B2DF2 /* mathlib.cpp in Sources */, E416BEE82410AA4E00751E6D /* runtool.c in Sources */, E413D93020D260BC00E437D8 /* ip_input.c in Sources */, 752F27031F242F51001032B4 /* xpram_sdl.cpp in Sources */, @@ -903,6 +851,19 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + E45769BD2643A6870063BAF1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = uae_cpu_x86_64; + targetProxy = E45769BC2643A6870063BAF1 /* PBXContainerItemProxy */; + }; + E45769BF2643A68B0063BAF1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = uae_cpu_arm64; + targetProxy = E45769BE2643A68B0063BAF1 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 7539E00F1F23B25A006B2DF2 /* InfoPlist.strings */ = { isa = PBXVariantGroup; @@ -1039,6 +1000,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES; CLANG_WARN_SUSPICIOUS_MOVE = NO; CLANG_WARN__DUPLICATE_METHOD_MATCH = NO; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = NO; ENABLE_NS_ASSERTIONS = YES; ENABLE_TESTABILITY = NO; @@ -1050,15 +1012,30 @@ GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_ENABLE_PASCAL_STRINGS = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; + "GCC_PREPROCESSOR_DEFINITIONS[arch=arm64]" = "$(inherited)"; + "GCC_PREPROCESSOR_DEFINITIONS[arch=x86_64]" = ( "$(inherited)", - ENABLE_MACOSX_ETHERHELPER, - HAVE_CONFIG_H, + CPU_x86_64, + JIT, + "USE_JIT=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_USE_STANDARD_INCLUDE_SEARCHING = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_CHECK_SWITCH_STATEMENTS = NO; - HEADER_SEARCH_PATHS = ( + GCC_WARN_UNUSED_VARIABLE = NO; + HEADER_SEARCH_PATHS = ""; + "HEADER_SEARCH_PATHS[arch=arm64]" = ( + /Library/Frameworks/SDL2.framework/Headers, + ../MacOSX, + ../include, + ../uae_cpu_2021, + ../Unix, + ../slirp, + ); + "HEADER_SEARCH_PATHS[arch=x86_64]" = ( /Library/Frameworks/SDL2.framework/Headers, ../MacOSX, ../include, @@ -1069,14 +1046,27 @@ INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + "OTHER_LDFLAGS[arch=arm64]" = ( + "-luae_cpu_arm64", + "-lgmp", + "-lmpfr", + ); + "OTHER_LDFLAGS[arch=x86_64]" = ( + "-luae_cpu_x86_64", + "-Wl,-no_pie", + "-pagezero_size", + 0x1000, + ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; PRODUCT_BUNDLE_IDENTIFIER = net.cebix.basilisk; PRODUCT_NAME = "$(TARGET_NAME)"; USE_HEADERMAP = YES; - VALID_ARCHS = x86_64; + VALID_ARCHS = "x86_64 arm64"; WARNING_CFLAGS = ""; }; name = Debug; @@ -1093,6 +1083,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES; CLANG_WARN_SUSPICIOUS_MOVE = NO; CLANG_WARN__DUPLICATE_METHOD_MATCH = NO; + CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_NS_ASSERTIONS = YES; @@ -1107,15 +1098,29 @@ GCC_ENABLE_PASCAL_STRINGS = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = ( + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; + "GCC_PREPROCESSOR_DEFINITIONS[arch=arm64]" = "$(inherited)"; + "GCC_PREPROCESSOR_DEFINITIONS[arch=x86_64]" = ( "$(inherited)", - ENABLE_MACOSX_ETHERHELPER, - HAVE_CONFIG_H, + CPU_x86_64, + JIT, + "USE_JIT=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_USE_STANDARD_INCLUDE_SEARCHING = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_CHECK_SWITCH_STATEMENTS = NO; - HEADER_SEARCH_PATHS = ( + GCC_WARN_UNUSED_VARIABLE = NO; + HEADER_SEARCH_PATHS = ""; + "HEADER_SEARCH_PATHS[arch=arm64]" = ( + /Library/Frameworks/SDL2.framework/Headers, + ../MacOSX, + ../include, + ../uae_cpu_2021, + ../Unix, + ../slirp, + ); + "HEADER_SEARCH_PATHS[arch=x86_64]" = ( /Library/Frameworks/SDL2.framework/Headers, ../MacOSX, ../include, @@ -1126,13 +1131,26 @@ INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.7; OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + "OTHER_LDFLAGS[arch=arm64]" = ( + "-luae_cpu_arm64", + "-lgmp", + "-lmpfr", + ); + "OTHER_LDFLAGS[arch=x86_64]" = ( + "-luae_cpu_x86_64", + "-Wl,-no_pie", + "-pagezero_size", + 0x1000, + ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; PRODUCT_BUNDLE_IDENTIFIER = net.cebix.basilisk; PRODUCT_NAME = "$(TARGET_NAME)"; USE_HEADERMAP = YES; - VALID_ARCHS = x86_64; + VALID_ARCHS = "x86_64 arm64"; WARNING_CFLAGS = ""; }; name = Release; diff --git a/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings b/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings index c3ef149ea..5b8ae8d04 100755 --- a/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings +++ b/BasiliskII/src/MacOSX/English.lproj/InfoPlist.strings @@ -1,3 +1,3 @@ /* Localized versions of Info.plist keys */ -NSHumanReadableCopyright = "Copyright © 1997-2020 Christian Bauer et al. Freely distributable under the terms of the GNU GPL."; +NSHumanReadableCopyright = "Copyright © 1997-2017 Christian Bauer et al. Freely distributable under the terms of the GNU GPL."; diff --git a/BasiliskII/src/MacOSX/Info.plist b/BasiliskII/src/MacOSX/Info.plist index b879fccd5..da3aae247 100644 --- a/BasiliskII/src/MacOSX/Info.plist +++ b/BasiliskII/src/MacOSX/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable BasiliskII CFBundleGetInfoString - Basilisk II version 1.0, Copyright © 1997-2020 Christian Bauer et al. SDL2 port + Basilisk II version 1.0, Copyright © 1997-2017 Christian Bauer et al. SDL2 port CFBundleIconFile BasiliskII.icns CFBundleIdentifier diff --git a/BasiliskII/src/MacOSX/MacOSX_sound_if.h b/BasiliskII/src/MacOSX/MacOSX_sound_if.h index 5cfdd438a..06e06da47 100644 --- a/BasiliskII/src/MacOSX/MacOSX_sound_if.h +++ b/BasiliskII/src/MacOSX/MacOSX_sound_if.h @@ -18,6 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef MACOSX_SOUND_IF +#define MACOSX_SOUND_IF typedef int (*audioCallback)(void); @@ -39,3 +41,5 @@ class OSXsoundOutput { unsigned int bufferSizeFrames(); int sendAudioBuffer(void *buffer, int numFrames); }; + +#endif diff --git a/BasiliskII/src/MacOSX/Makefile.gencpu b/BasiliskII/src/MacOSX/Makefile.gencpu index 2e2ec45e0..3762cb5d1 100644 --- a/BasiliskII/src/MacOSX/Makefile.gencpu +++ b/BasiliskII/src/MacOSX/Makefile.gencpu @@ -1,14 +1,16 @@ SRC = $(PROJECT_DIR)/../uae_cpu DST = $(BUILT_PRODUCTS_DIR)/gencpu_output -VPATH = $(SRC) -CFLAGS = -DUSE_XCODE=1 -I. -I../uae_cpu -I../UNIX +VPATH = $(SRC) $(SRC)/compiler +CFLAGS = -DUSE_XCODE=1 -DUSE_JIT_FPU -I. -I../uae_cpu -I../UNIX CXXFLAGS = -stdlib=libc++ $(CFLAGS) -OBJS = $(addprefix $(DST)/, defs68k.o gencpu.o readcpu.o) -all: $(DST)/gencpu - cd $(DST); ./gencpu +all: $(DST)/gencpu $(DST)/gencomp + cd $(DST); ./gencpu; ./gencomp -$(DST)/gencpu: $(OBJS) +$(DST)/gencpu: $(addprefix $(DST)/, defs68k.o readcpu.o gencpu.o) + $(CXX) $(CXXFLAGS) -o $@ $^ + +$(DST)/gencomp: $(addprefix $(DST)/, defs68k.o readcpu.o gencomp.o) $(CXX) $(CXXFLAGS) -o $@ $^ $(DST)/%.o: %.c diff --git a/BasiliskII/src/MacOSX/Makefile.gencpu_2021 b/BasiliskII/src/MacOSX/Makefile.gencpu_2021 new file mode 100644 index 000000000..e5d495fcb --- /dev/null +++ b/BasiliskII/src/MacOSX/Makefile.gencpu_2021 @@ -0,0 +1,29 @@ +SRC = $(PROJECT_DIR)/../uae_cpu_2021 +DST = $(BUILT_PRODUCTS_DIR)/gencpu_output_2021 +VPATH = $(SRC) $(SRC)/compiler +CFLAGS = -DUSE_XCODE=1 -DUSE_JIT_FPU -I. -I../uae_cpu_2021 -I../UNIX +CXXFLAGS = -stdlib=libc++ $(CFLAGS) + +all: $(DST)/gencpu $(DST)/gencomp + cd $(DST); ./gencpu; ./gencomp + +$(DST)/gencpu: $(addprefix $(DST)/, defs68k.o readcpu.o gencpu.o) + $(CXX) $(CXXFLAGS) -o $@ $^ + +$(DST)/gencomp: $(addprefix $(DST)/, defs68k.o readcpu.o gencomp.o) + $(CXX) $(CXXFLAGS) -o $@ $^ + +$(DST)/%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +$(DST)/%.o: %.cpp + $(CXX) $(CXXFLAGS) -o $@ -c $< + +$(DST)/defs68k.c: $(DST)/build68k + $< < $(SRC)/table68k > $@ + +$(DST)/build68k: $(SRC)/build68k.c + mkdir -p $(DST) + $(CC) $(CFLAGS) -o $@ $< + +clean:; rm -fr $(DST) 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/audio_macosx.cpp b/BasiliskII/src/MacOSX/audio_macosx.cpp index 840d2f13f..5e5d25a3d 100644 --- a/BasiliskII/src/MacOSX/audio_macosx.cpp +++ b/BasiliskII/src/MacOSX/audio_macosx.cpp @@ -19,6 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef USE_SDL_AUDIO + #include "sysdeps.h" #include @@ -269,3 +271,5 @@ static int audioInt(void) TriggerInterrupt(); return 0; } + +#endif diff --git a/BasiliskII/src/MacOSX/config.h b/BasiliskII/src/MacOSX/config.h index 9b853b472..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 */ @@ -681,7 +678,11 @@ #define SIZEOF_LONG 8 /* The size of `long double', as computed by sizeof. */ +#ifdef CPU_x86_64 #define SIZEOF_LONG_DOUBLE 16 +#else +#define SIZEOF_LONG_DOUBLE 8 +#endif /* The size of `long long', as computed by sizeof. */ #define SIZEOF_LONG_LONG 8 @@ -815,6 +816,32 @@ don't define. */ /* #undef uintmax_t */ +#ifndef CPU_x86_64 +#define UPDATE_UAE +#endif + +#ifdef UPDATE_UAE +#define DIRECT_ADDRESSING 1 +#define CPU_64_BIT +#define USE_INLINING +#ifdef CPU_x86_64 #define FPU_IEEE +#define WINUAE_ARANYM +#else +#define FPU_MPFR +#endif +#else +#define FPU_IEEE +#endif + +#if USE_JIT +#define DIRECT_ADDRESSING 1 +#define USE_JIT_FPU +#define X86_64_ASSEMBLY +#define OPTIMIZED_FLAGS +#endif + +#define ENABLE_MACOSX_ETHERHELPER +#define BINCUE 1 #endif diff --git a/BasiliskII/src/MacOSX/extfs_macosx.cpp b/BasiliskII/src/MacOSX/extfs_macosx.cpp index 34f57058c..0521c07fb 100644 --- a/BasiliskII/src/MacOSX/extfs_macosx.cpp +++ b/BasiliskII/src/MacOSX/extfs_macosx.cpp @@ -252,8 +252,7 @@ static int open_rsrc(const char *path, int flag) make_rsrc_path(path, rsrc_path); int fd = open(rsrc_path, flag); - if (fd < 0 && flag == O_WRONLY) - fd = open(rsrc_path, O_WRONLY | O_CREAT); // for APFS + if (fd < 0 && (flag == O_WRONLY || flag == O_RDWR)) fd = open(rsrc_path, flag | O_CREAT); // for APFS return fd; } @@ -627,11 +626,11 @@ const char *convert_string(const char *str, CFStringEncoding from, CFStringEncod // Convert from the host OS filename encoding to MacRoman const char *host_encoding_to_macroman(const char *filename) { - return convert_string(filename, kCFStringEncodingUTF8, kCFStringEncodingMacRoman); + return convert_string(filename, kCFStringEncodingUTF8, PrefsFindInt32("name_encoding")); } // Convert from MacRoman to host OS filename encoding const char *macroman_to_host_encoding(const char *filename) { - return convert_string(filename, kCFStringEncodingMacRoman, kCFStringEncodingUTF8); + return convert_string(filename, PrefsFindInt32("name_encoding"), kCFStringEncodingUTF8); } diff --git a/BasiliskII/src/MacOSX/main_macosx.mm b/BasiliskII/src/MacOSX/main_macosx.mm index b14a2ede4..3eadf09f8 100644 --- a/BasiliskII/src/MacOSX/main_macosx.mm +++ b/BasiliskII/src/MacOSX/main_macosx.mm @@ -32,14 +32,13 @@ # include #endif -#if REAL_ADDRESSING || DIRECT_ADDRESSING +#if DIRECT_ADDRESSING # include #endif #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,36 +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 -#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 - */ - -// 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 */ @@ -211,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(); @@ -325,135 +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 REAL_ADDRESSING || 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) { - 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 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)); - - // 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); @@ -462,7 +299,6 @@ bool InitEmulator (void) sigaction(SIGINT, &sigint_sa, NULL); #endif - return YES; } @@ -473,8 +309,7 @@ bool InitEmulator (void) * Quit emulator */ -void QuitEmuNoExit() -{ +void QuitEmuNoExit(){ D(bug("QuitEmulator\n")); // Exit 680x0 emulation @@ -483,30 +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 - -#if REAL_ADDRESSING - // Delete Low Memory area - if (lm_area_mapped) - vm_release(0, 0x2000); -#endif - - // Exit VM wrappers - vm_exit(); - // Exit system routines SysExit(); @@ -514,8 +325,7 @@ void QuitEmuNoExit() PrefsExit(); } -void QuitEmulator(void) -{ +void QuitEmulator(void){ QuitEmuNoExit(); // Stop run loop? diff --git a/BasiliskII/src/MacOSX/runtool.c b/BasiliskII/src/MacOSX/runtool.c new file mode 100644 index 000000000..77c38a437 --- /dev/null +++ b/BasiliskII/src/MacOSX/runtool.c @@ -0,0 +1,136 @@ +/* + * runtool.m - Run an external program as root for networking + * Copyright (C) 2010, Daniel Sumorok + * + * 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 +#include + +#include + +#include + +FILE * run_tool(const char *if_name, const char *tool_name); + +FILE * run_tool(const char *if_name, const char *tool_name) +{ + OSStatus auth_status; + FILE *fp = NULL; + char *args[] = {NULL, NULL, NULL}; + int ret; + char path_buffer[256]; + AuthorizationFlags auth_flags; + AuthorizationRef auth_ref; + AuthorizationItem auth_items[1]; + AuthorizationRights auth_rights; + CFBundleRef bundle_ref; + CFURLRef url_ref; + CFStringRef path_str; + CFStringRef tool_name_str; + char c; + + bundle_ref = CFBundleGetMainBundle(); + if(bundle_ref == NULL) { + return NULL; + } + + tool_name_str = CFStringCreateWithCString(NULL, tool_name, + kCFStringEncodingUTF8); + + url_ref = CFBundleCopyResourceURL(bundle_ref, tool_name_str, + NULL, NULL); + CFRelease(tool_name_str); + + if(url_ref == NULL) { + return NULL; + } + + path_str = CFURLCopyFileSystemPath(url_ref, kCFURLPOSIXPathStyle); + CFRelease(url_ref); + + if(path_str == NULL) { + return NULL; + } + + if(!CFStringGetCString(path_str, path_buffer, sizeof(path_buffer), + kCFStringEncodingUTF8)) { + CFRelease(path_str); + return NULL; + } + CFRelease(path_str); + + args[0] = (char *)tool_name; + args[1] = (char *)if_name; + + auth_flags = kAuthorizationFlagExtendRights | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize; + + auth_items[0].name = "system.privilege.admin"; + auth_items[0].valueLength = 0; + auth_items[0].value = NULL; + auth_items[0].flags = 0; + + auth_rights.count = sizeof (auth_items) / sizeof (auth_items[0]); + auth_rights.items = auth_items; + + auth_status = AuthorizationCreate(&auth_rights, + kAuthorizationEmptyEnvironment, + auth_flags, + &auth_ref); + + if (auth_status != errAuthorizationSuccess) { + fprintf(stderr, "%s: AuthorizationCreate() failed.\n", + __func__); + return NULL; + } + + auth_status = AuthorizationExecuteWithPrivileges(auth_ref, + path_buffer, + kAuthorizationFlagDefaults, + args + 1, + &fp); + + if (auth_status != errAuthorizationSuccess) { + fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", + __func__); + return NULL; + } + + if(fread(&c, 1, 1, fp) != 1) { + fclose(fp); + return NULL; + } + + return fp; +} diff --git a/BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj b/BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj new file mode 100644 index 000000000..fde86798a --- /dev/null +++ b/BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj @@ -0,0 +1,481 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E4C1B4A32642B05A00EB55A0 /* compemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49A2642B05A00EB55A0 /* compemu.cpp */; }; + E4C1B4A42642B05A00EB55A0 /* compstbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */; }; + E4C1B4A52642B05A00EB55A0 /* comptbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C1B49C2642B05A00EB55A0 /* comptbl.h */; }; + E4C1B4A62642B05A00EB55A0 /* cpuemu_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */; }; + E4C1B4A72642B05A00EB55A0 /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */; }; + E4C1B4A82642B05A00EB55A0 /* cpustbl_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */; }; + E4C1B4A92642B05A00EB55A0 /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */; }; + E4C1B4AA2642B05A00EB55A0 /* cputbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C1B4A12642B05A00EB55A0 /* cputbl.h */; }; + E4C1B4AB2642B05A00EB55A0 /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B4A22642B05A00EB55A0 /* defs68k.c */; }; + E4F537C92642A8BA008B27DF /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */; }; + E4F537CD2642A8C2008B27DF /* cpu_emulation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537CB2642A8C2008B27DF /* cpu_emulation.h */; }; + E4F537DB2642A8CC008B27DF /* m68k.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D02642A8CC008B27DF /* m68k.h */; }; + E4F537DC2642A8CC008B27DF /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D12642A8CC008B27DF /* memory.cpp */; }; + E4F537DD2642A8CC008B27DF /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D22642A8CC008B27DF /* memory.h */; }; + E4F537DE2642A8CC008B27DF /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D32642A8CC008B27DF /* newcpu.cpp */; }; + E4F537DF2642A8CC008B27DF /* newcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D42642A8CC008B27DF /* newcpu.h */; }; + E4F537E02642A8CC008B27DF /* noflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D52642A8CC008B27DF /* noflags.h */; }; + E4F537E12642A8CC008B27DF /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D62642A8CC008B27DF /* readcpu.cpp */; }; + E4F537E22642A8CC008B27DF /* readcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D72642A8CC008B27DF /* readcpu.h */; }; + E4F537E32642A8CC008B27DF /* spcflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D82642A8CC008B27DF /* spcflags.h */; }; + E4F537EE2642A8E8008B27DF /* codegen_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537E62642A8E8008B27DF /* codegen_x86.h */; }; + E4F537EF2642A8E8008B27DF /* compemu_fpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */; }; + E4F537F02642A8E8008B27DF /* compemu_support.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537E82642A8E8008B27DF /* compemu_support.cpp */; }; + E4F537F12642A8E8008B27DF /* compemu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537E92642A8E8008B27DF /* compemu.h */; }; + E4F537F22642A8E8008B27DF /* flags_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537EA2642A8E8008B27DF /* flags_x86.h */; }; + E4F537F32642A8E8008B27DF /* gencomp.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F537EB2642A8E8008B27DF /* gencomp.c */; }; + E4F538092642A904008B27DF /* core.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537F62642A904008B27DF /* core.h */; }; + E4F5380A2642A904008B27DF /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537F72642A904008B27DF /* exceptions.cpp */; }; + E4F5380B2642A904008B27DF /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537F82642A904008B27DF /* exceptions.h */; }; + E4F5380C2642A904008B27DF /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537F92642A904008B27DF /* flags.cpp */; }; + E4F5380D2642A904008B27DF /* flags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537FA2642A904008B27DF /* flags.h */; }; + E4F5380E2642A904008B27DF /* fpu_ieee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537FB2642A904008B27DF /* fpu_ieee.cpp */; }; + E4F5380F2642A904008B27DF /* fpu_ieee.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537FC2642A904008B27DF /* fpu_ieee.h */; }; + E4F538152642A904008B27DF /* fpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538022642A904008B27DF /* fpu.h */; }; + E4F538162642A904008B27DF /* impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538032642A904008B27DF /* impl.h */; }; + E4F538172642A904008B27DF /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F538042642A904008B27DF /* mathlib.cpp */; }; + E4F538182642A904008B27DF /* mathlib.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538052642A904008B27DF /* mathlib.h */; }; + E4F538192642A904008B27DF /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F538062642A904008B27DF /* rounding.cpp */; }; + E4F5381A2642A904008B27DF /* rounding.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538072642A904008B27DF /* rounding.h */; }; + E4F5381B2642A904008B27DF /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538082642A904008B27DF /* types.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E4C1B49A2642B05A00EB55A0 /* compemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu.cpp; path = gencpu_output/compemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compstbl.cpp; path = gencpu_output/compstbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B49C2642B05A00EB55A0 /* comptbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = comptbl.h; path = gencpu_output/comptbl.h; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu_nf.cpp; path = gencpu_output/cpuemu_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl_nf.cpp; path = gencpu_output/cpustbl_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B4A12642B05A00EB55A0 /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; }; + E4C1B4A22642B05A00EB55A0 /* defs68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; }; + E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libuae_cpu_x86_64.a; sourceTree = BUILT_PRODUCTS_DIR; }; + E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basilisk_glue.cpp; path = ../uae_cpu/basilisk_glue.cpp; sourceTree = ""; }; + E4F537CB2642A8C2008B27DF /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpu_emulation.h; path = ../uae_cpu/cpu_emulation.h; sourceTree = ""; }; + E4F537D02642A8CC008B27DF /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68k.h; path = ../uae_cpu/m68k.h; sourceTree = ""; }; + E4F537D12642A8CC008B27DF /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.cpp; path = ../uae_cpu/memory.cpp; sourceTree = ""; }; + E4F537D22642A8CC008B27DF /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../uae_cpu/memory.h; sourceTree = ""; }; + E4F537D32642A8CC008B27DF /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = newcpu.cpp; path = ../uae_cpu/newcpu.cpp; sourceTree = ""; }; + E4F537D42642A8CC008B27DF /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = newcpu.h; path = ../uae_cpu/newcpu.h; sourceTree = ""; }; + E4F537D52642A8CC008B27DF /* noflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = noflags.h; path = ../uae_cpu/noflags.h; sourceTree = ""; }; + E4F537D62642A8CC008B27DF /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readcpu.cpp; path = ../uae_cpu/readcpu.cpp; sourceTree = ""; }; + E4F537D72642A8CC008B27DF /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = readcpu.h; path = ../uae_cpu/readcpu.h; sourceTree = ""; }; + E4F537D82642A8CC008B27DF /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spcflags.h; path = ../uae_cpu/spcflags.h; sourceTree = ""; }; + E4F537D92642A8CC008B27DF /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = table68k; path = ../uae_cpu/table68k; sourceTree = ""; }; + E4F537E62642A8E8008B27DF /* codegen_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codegen_x86.h; path = ../uae_cpu/compiler/codegen_x86.h; sourceTree = ""; }; + E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu_fpp.cpp; path = ../uae_cpu/compiler/compemu_fpp.cpp; sourceTree = ""; }; + E4F537E82642A8E8008B27DF /* compemu_support.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu_support.cpp; path = ../uae_cpu/compiler/compemu_support.cpp; sourceTree = ""; }; + E4F537E92642A8E8008B27DF /* compemu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = compemu.h; path = ../uae_cpu/compiler/compemu.h; sourceTree = ""; }; + E4F537EA2642A8E8008B27DF /* flags_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags_x86.h; path = ../uae_cpu/compiler/flags_x86.h; sourceTree = ""; }; + E4F537EB2642A8E8008B27DF /* gencomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gencomp.c; path = ../uae_cpu/compiler/gencomp.c; sourceTree = ""; }; + E4F537F62642A904008B27DF /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../uae_cpu/fpu/core.h; sourceTree = ""; }; + E4F537F72642A904008B27DF /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exceptions.cpp; path = ../uae_cpu/fpu/exceptions.cpp; sourceTree = ""; }; + E4F537F82642A904008B27DF /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exceptions.h; path = ../uae_cpu/fpu/exceptions.h; sourceTree = ""; }; + E4F537F92642A904008B27DF /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flags.cpp; path = ../uae_cpu/fpu/flags.cpp; sourceTree = ""; }; + E4F537FA2642A904008B27DF /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags.h; path = ../uae_cpu/fpu/flags.h; sourceTree = ""; }; + E4F537FB2642A904008B27DF /* fpu_ieee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fpu_ieee.cpp; path = ../uae_cpu/fpu/fpu_ieee.cpp; sourceTree = ""; }; + E4F537FC2642A904008B27DF /* fpu_ieee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu_ieee.h; path = ../uae_cpu/fpu/fpu_ieee.h; sourceTree = ""; }; + E4F538022642A904008B27DF /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu.h; path = ../uae_cpu/fpu/fpu.h; sourceTree = ""; }; + E4F538032642A904008B27DF /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = impl.h; path = ../uae_cpu/fpu/impl.h; sourceTree = ""; }; + E4F538042642A904008B27DF /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mathlib.cpp; path = ../uae_cpu/fpu/mathlib.cpp; sourceTree = ""; }; + E4F538052642A904008B27DF /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mathlib.h; path = ../uae_cpu/fpu/mathlib.h; sourceTree = ""; }; + E4F538062642A904008B27DF /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rounding.cpp; path = ../uae_cpu/fpu/rounding.cpp; sourceTree = ""; }; + E4F538072642A904008B27DF /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rounding.h; path = ../uae_cpu/fpu/rounding.h; sourceTree = ""; }; + E4F538082642A904008B27DF /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../uae_cpu/fpu/types.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E4F537BD2642A86D008B27DF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E4C1B4982642AF3400EB55A0 /* generated */ = { + isa = PBXGroup; + children = ( + E4C1B49A2642B05A00EB55A0 /* compemu.cpp */, + E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */, + E4C1B49C2642B05A00EB55A0 /* comptbl.h */, + E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */, + E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */, + E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */, + E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */, + E4C1B4A12642B05A00EB55A0 /* cputbl.h */, + E4C1B4A22642B05A00EB55A0 /* defs68k.c */, + ); + name = generated; + sourceTree = ""; + }; + E4F537B72642A86D008B27DF = { + isa = PBXGroup; + children = ( + E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */, + E4F537E42642A8D2008B27DF /* compiler */, + E4F537CB2642A8C2008B27DF /* cpu_emulation.h */, + E4F537F52642A8ED008B27DF /* fpu */, + E4F537D02642A8CC008B27DF /* m68k.h */, + E4F537D12642A8CC008B27DF /* memory.cpp */, + E4F537D22642A8CC008B27DF /* memory.h */, + E4F537D32642A8CC008B27DF /* newcpu.cpp */, + E4F537D42642A8CC008B27DF /* newcpu.h */, + E4F537D52642A8CC008B27DF /* noflags.h */, + E4F537D62642A8CC008B27DF /* readcpu.cpp */, + E4F537D72642A8CC008B27DF /* readcpu.h */, + E4F537D82642A8CC008B27DF /* spcflags.h */, + E4F537D92642A8CC008B27DF /* table68k */, + E4C1B4982642AF3400EB55A0 /* generated */, + E4F537C12642A86D008B27DF /* Products */, + ); + sourceTree = ""; + }; + E4F537C12642A86D008B27DF /* Products */ = { + isa = PBXGroup; + children = ( + E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */, + ); + name = Products; + sourceTree = ""; + }; + E4F537E42642A8D2008B27DF /* compiler */ = { + isa = PBXGroup; + children = ( + E4F537E62642A8E8008B27DF /* codegen_x86.h */, + E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */, + E4F537E82642A8E8008B27DF /* compemu_support.cpp */, + E4F537E92642A8E8008B27DF /* compemu.h */, + E4F537EA2642A8E8008B27DF /* flags_x86.h */, + E4F537EB2642A8E8008B27DF /* gencomp.c */, + ); + name = compiler; + sourceTree = ""; + }; + E4F537F52642A8ED008B27DF /* fpu */ = { + isa = PBXGroup; + children = ( + E4F537F62642A904008B27DF /* core.h */, + E4F537F72642A904008B27DF /* exceptions.cpp */, + E4F537F82642A904008B27DF /* exceptions.h */, + E4F537F92642A904008B27DF /* flags.cpp */, + E4F537FA2642A904008B27DF /* flags.h */, + E4F537FB2642A904008B27DF /* fpu_ieee.cpp */, + E4F537FC2642A904008B27DF /* fpu_ieee.h */, + E4F538022642A904008B27DF /* fpu.h */, + E4F538032642A904008B27DF /* impl.h */, + E4F538042642A904008B27DF /* mathlib.cpp */, + E4F538052642A904008B27DF /* mathlib.h */, + E4F538062642A904008B27DF /* rounding.cpp */, + E4F538072642A904008B27DF /* rounding.h */, + E4F538082642A904008B27DF /* types.h */, + ); + name = fpu; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + E4F537BE2642A86D008B27DF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E4F538182642A904008B27DF /* mathlib.h in Headers */, + E4F538152642A904008B27DF /* fpu.h in Headers */, + E4F5380F2642A904008B27DF /* fpu_ieee.h in Headers */, + E4F537F12642A8E8008B27DF /* compemu.h in Headers */, + E4F538092642A904008B27DF /* core.h in Headers */, + E4C1B4AA2642B05A00EB55A0 /* cputbl.h in Headers */, + E4F5381B2642A904008B27DF /* types.h in Headers */, + E4F537DF2642A8CC008B27DF /* newcpu.h in Headers */, + E4F5380D2642A904008B27DF /* flags.h in Headers */, + E4F537E22642A8CC008B27DF /* readcpu.h in Headers */, + E4F5381A2642A904008B27DF /* rounding.h in Headers */, + E4C1B4A52642B05A00EB55A0 /* comptbl.h in Headers */, + E4F5380B2642A904008B27DF /* exceptions.h in Headers */, + E4F537E32642A8CC008B27DF /* spcflags.h in Headers */, + E4F537DB2642A8CC008B27DF /* m68k.h in Headers */, + E4F537F22642A8E8008B27DF /* flags_x86.h in Headers */, + E4F538162642A904008B27DF /* impl.h in Headers */, + E4F537CD2642A8C2008B27DF /* cpu_emulation.h in Headers */, + E4F537EE2642A8E8008B27DF /* codegen_x86.h in Headers */, + E4F537DD2642A8CC008B27DF /* memory.h in Headers */, + E4F537E02642A8CC008B27DF /* noflags.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + E4F537BF2642A86D008B27DF /* uae_cpu_x86_64 */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4F537C42642A86D008B27DF /* Build configuration list for PBXNativeTarget "uae_cpu_x86_64" */; + buildPhases = ( + E4C1B4992642AF5100EB55A0 /* ShellScript */, + E4F537BC2642A86D008B27DF /* Sources */, + E4F537BD2642A86D008B27DF /* Frameworks */, + E4F537BE2642A86D008B27DF /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = uae_cpu_x86_64; + productName = uae_cpu; + productReference = E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E4F537B82642A86D008B27DF /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0820; + TargetAttributes = { + E4F537BF2642A86D008B27DF = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = E4F537BB2642A86D008B27DF /* Build configuration list for PBXProject "uae_cpu" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + ); + mainGroup = E4F537B72642A86D008B27DF; + productRefGroup = E4F537C12642A86D008B27DF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E4F537BF2642A86D008B27DF /* uae_cpu_x86_64 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + E4C1B4992642AF5100EB55A0 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + $BUILT_PRODUCTS_DIR/gencpu_output/cpuemu.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output/cpuemu_nf.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output/cpustbl.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output/cpustbl_nf.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output/defs68k.c, + $BUILT_PRODUCTS_DIR/gencpu_output/compemu.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output/compstbl.cpp, + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "make -f Makefile.gencpu\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E4F537BC2642A86D008B27DF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E4C1B4A62642B05A00EB55A0 /* cpuemu_nf.cpp in Sources */, + E4C1B4A32642B05A00EB55A0 /* compemu.cpp in Sources */, + E4F538192642A904008B27DF /* rounding.cpp in Sources */, + E4F537E12642A8CC008B27DF /* readcpu.cpp in Sources */, + E4F5380C2642A904008B27DF /* flags.cpp in Sources */, + E4F537EF2642A8E8008B27DF /* compemu_fpp.cpp in Sources */, + E4F538172642A904008B27DF /* mathlib.cpp in Sources */, + E4F537F02642A8E8008B27DF /* compemu_support.cpp in Sources */, + E4F537DC2642A8CC008B27DF /* memory.cpp in Sources */, + E4C1B4A42642B05A00EB55A0 /* compstbl.cpp in Sources */, + E4C1B4AB2642B05A00EB55A0 /* defs68k.c in Sources */, + E4C1B4A92642B05A00EB55A0 /* cpustbl.cpp in Sources */, + E4F537C92642A8BA008B27DF /* basilisk_glue.cpp in Sources */, + E4F537F32642A8E8008B27DF /* gencomp.c in Sources */, + E4F5380E2642A904008B27DF /* fpu_ieee.cpp in Sources */, + E4C1B4A72642B05A00EB55A0 /* cpuemu.cpp in Sources */, + E4C1B4A82642B05A00EB55A0 /* cpustbl_nf.cpp in Sources */, + E4F537DE2642A8CC008B27DF /* newcpu.cpp in Sources */, + E4F5380A2642A904008B27DF /* exceptions.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E4F537C22642A86D008B27DF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + E4F537C32642A86D008B27DF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + E4F537C52642A86D008B27DF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = x86_64; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "USE_XCODE=1", + CPU_x86_64, + JIT, + "USE_JIT=1", + ); + HEADER_SEARCH_PATHS = ( + ../CrossPlatform, + ../include, + ../MacOSX, + ../uae_cpu, + ../Unix, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E4F537C62642A86D008B27DF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = x86_64; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_XCODE=1", + CPU_x86_64, + JIT, + "USE_JIT=1", + ); + HEADER_SEARCH_PATHS = ( + ../CrossPlatform, + ../include, + ../MacOSX, + ../uae_cpu, + ../Unix, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E4F537BB2642A86D008B27DF /* Build configuration list for PBXProject "uae_cpu" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4F537C22642A86D008B27DF /* Debug */, + E4F537C32642A86D008B27DF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4F537C42642A86D008B27DF /* Build configuration list for PBXNativeTarget "uae_cpu_x86_64" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4F537C52642A86D008B27DF /* Debug */, + E4F537C62642A86D008B27DF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E4F537B82642A86D008B27DF /* Project object */; +} diff --git a/BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj b/BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj new file mode 100644 index 000000000..6a46b4523 --- /dev/null +++ b/BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj @@ -0,0 +1,427 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E41D7AAA2642C070005E8093 /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AA82642C070005E8093 /* basilisk_glue.cpp */; }; + E41D7AAE2642C07C005E8093 /* cpu_emulation.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AAC2642C07C005E8093 /* cpu_emulation.h */; }; + E41D7AAF2642C07C005E8093 /* cpummu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AAD2642C07C005E8093 /* cpummu.h */; }; + E41D7ABB2642C087005E8093 /* m68k.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB12642C087005E8093 /* m68k.h */; }; + E41D7ABC2642C087005E8093 /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB22642C087005E8093 /* memory.h */; }; + E41D7ABD2642C087005E8093 /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AB32642C087005E8093 /* newcpu.cpp */; }; + E41D7ABE2642C087005E8093 /* newcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB42642C087005E8093 /* newcpu.h */; }; + E41D7ABF2642C087005E8093 /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AB52642C087005E8093 /* readcpu.cpp */; }; + E41D7AC02642C087005E8093 /* readcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB62642C087005E8093 /* readcpu.h */; }; + E41D7AC12642C087005E8093 /* registers.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB72642C087005E8093 /* registers.h */; }; + E41D7AC22642C087005E8093 /* spcflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB82642C087005E8093 /* spcflags.h */; }; + E41D7AD82642C0A4005E8093 /* core.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC42642C0A4005E8093 /* core.h */; }; + E41D7AD92642C0A4005E8093 /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AC52642C0A4005E8093 /* exceptions.cpp */; }; + E41D7ADA2642C0A4005E8093 /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC62642C0A4005E8093 /* exceptions.h */; }; + E41D7ADB2642C0A4005E8093 /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AC72642C0A4005E8093 /* flags.cpp */; }; + E41D7ADC2642C0A4005E8093 /* flags.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC82642C0A4005E8093 /* flags.h */; }; + E41D7ADF2642C0A4005E8093 /* fpu_mpfr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */; }; + E41D7AE52642C0A4005E8093 /* fpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD12642C0A4005E8093 /* fpu.h */; }; + E41D7AE62642C0A4005E8093 /* impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD22642C0A4005E8093 /* impl.h */; }; + E41D7AE72642C0A4005E8093 /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AD32642C0A4005E8093 /* mathlib.cpp */; }; + E41D7AE82642C0A4005E8093 /* mathlib.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD42642C0A4005E8093 /* mathlib.h */; }; + E41D7AE92642C0A4005E8093 /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AD52642C0A4005E8093 /* rounding.cpp */; }; + E41D7AEA2642C0A4005E8093 /* rounding.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD62642C0A4005E8093 /* rounding.h */; }; + E41D7AEB2642C0A4005E8093 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD72642C0A4005E8093 /* types.h */; }; + E4FC27512642C45E00C64E21 /* cpufunctbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */; }; + E4FC27522642C45E00C64E21 /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274D2642C45E00C64E21 /* cpuemu.cpp */; }; + E4FC27532642C45E00C64E21 /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274E2642C45E00C64E21 /* cpustbl.cpp */; }; + E4FC27542642C45E00C64E21 /* cputbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4FC274F2642C45E00C64E21 /* cputbl.h */; }; + E4FC27552642C45E00C64E21 /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E4FC27502642C45E00C64E21 /* defs68k.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libuae_cpu_arm64.a; sourceTree = BUILT_PRODUCTS_DIR; }; + E41D7AA82642C070005E8093 /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basilisk_glue.cpp; path = ../uae_cpu_2021/basilisk_glue.cpp; sourceTree = ""; }; + E41D7AAC2642C07C005E8093 /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpu_emulation.h; path = ../uae_cpu_2021/cpu_emulation.h; sourceTree = ""; }; + E41D7AAD2642C07C005E8093 /* cpummu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpummu.h; path = ../uae_cpu_2021/cpummu.h; sourceTree = ""; }; + E41D7AB12642C087005E8093 /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68k.h; path = ../uae_cpu_2021/m68k.h; sourceTree = ""; }; + E41D7AB22642C087005E8093 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../uae_cpu_2021/memory.h; sourceTree = ""; }; + E41D7AB32642C087005E8093 /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = newcpu.cpp; path = ../uae_cpu_2021/newcpu.cpp; sourceTree = ""; }; + E41D7AB42642C087005E8093 /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = newcpu.h; path = ../uae_cpu_2021/newcpu.h; sourceTree = ""; }; + E41D7AB52642C087005E8093 /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readcpu.cpp; path = ../uae_cpu_2021/readcpu.cpp; sourceTree = ""; }; + E41D7AB62642C087005E8093 /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = readcpu.h; path = ../uae_cpu_2021/readcpu.h; sourceTree = ""; }; + E41D7AB72642C087005E8093 /* registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = registers.h; path = ../uae_cpu_2021/registers.h; sourceTree = ""; }; + E41D7AB82642C087005E8093 /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spcflags.h; path = ../uae_cpu_2021/spcflags.h; sourceTree = ""; }; + E41D7AB92642C087005E8093 /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = table68k; path = ../uae_cpu_2021/table68k; sourceTree = ""; }; + E41D7AC42642C0A4005E8093 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../uae_cpu_2021/fpu/core.h; sourceTree = ""; }; + E41D7AC52642C0A4005E8093 /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exceptions.cpp; path = ../uae_cpu_2021/fpu/exceptions.cpp; sourceTree = ""; }; + E41D7AC62642C0A4005E8093 /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exceptions.h; path = ../uae_cpu_2021/fpu/exceptions.h; sourceTree = ""; }; + E41D7AC72642C0A4005E8093 /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flags.cpp; path = ../uae_cpu_2021/fpu/flags.cpp; sourceTree = ""; }; + E41D7AC82642C0A4005E8093 /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags.h; path = ../uae_cpu_2021/fpu/flags.h; sourceTree = ""; }; + E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fpu_mpfr.cpp; path = ../uae_cpu_2021/fpu/fpu_mpfr.cpp; sourceTree = ""; }; + E41D7AD12642C0A4005E8093 /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu.h; path = ../uae_cpu_2021/fpu/fpu.h; sourceTree = ""; }; + E41D7AD22642C0A4005E8093 /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = impl.h; path = ../uae_cpu_2021/fpu/impl.h; sourceTree = ""; }; + E41D7AD32642C0A4005E8093 /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mathlib.cpp; path = ../uae_cpu_2021/fpu/mathlib.cpp; sourceTree = ""; }; + E41D7AD42642C0A4005E8093 /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mathlib.h; path = ../uae_cpu_2021/fpu/mathlib.h; sourceTree = ""; }; + E41D7AD52642C0A4005E8093 /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rounding.cpp; path = ../uae_cpu_2021/fpu/rounding.cpp; sourceTree = ""; }; + E41D7AD62642C0A4005E8093 /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rounding.h; path = ../uae_cpu_2021/fpu/rounding.h; sourceTree = ""; }; + E41D7AD72642C0A4005E8093 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../uae_cpu_2021/fpu/types.h; sourceTree = ""; }; + E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpufunctbl.cpp; path = gencpu_output_2021/cpufunctbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4FC274D2642C45E00C64E21 /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output_2021/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4FC274E2642C45E00C64E21 /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output_2021/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; + E4FC274F2642C45E00C64E21 /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output_2021/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; }; + E4FC27502642C45E00C64E21 /* defs68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output_2021/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E41D7A9E2642C004005E8093 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E41D7A982642C004005E8093 = { + isa = PBXGroup; + children = ( + E41D7AA82642C070005E8093 /* basilisk_glue.cpp */, + E41D7AC32642C08E005E8093 /* fpu */, + E41D7AAC2642C07C005E8093 /* cpu_emulation.h */, + E41D7AAD2642C07C005E8093 /* cpummu.h */, + E41D7AB12642C087005E8093 /* m68k.h */, + E41D7AB22642C087005E8093 /* memory.h */, + E41D7AB32642C087005E8093 /* newcpu.cpp */, + E41D7AB42642C087005E8093 /* newcpu.h */, + E41D7AB52642C087005E8093 /* readcpu.cpp */, + E41D7AB62642C087005E8093 /* readcpu.h */, + E41D7AB72642C087005E8093 /* registers.h */, + E41D7AB82642C087005E8093 /* spcflags.h */, + E41D7AB92642C087005E8093 /* table68k */, + E4FC274B2642C44A00C64E21 /* generated */, + E41D7AA22642C004005E8093 /* Products */, + ); + sourceTree = ""; + }; + E41D7AA22642C004005E8093 /* Products */ = { + isa = PBXGroup; + children = ( + E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */, + ); + name = Products; + sourceTree = ""; + }; + E41D7AC32642C08E005E8093 /* fpu */ = { + isa = PBXGroup; + children = ( + E41D7AC42642C0A4005E8093 /* core.h */, + E41D7AC52642C0A4005E8093 /* exceptions.cpp */, + E41D7AC62642C0A4005E8093 /* exceptions.h */, + E41D7AC72642C0A4005E8093 /* flags.cpp */, + E41D7AC82642C0A4005E8093 /* flags.h */, + E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */, + E41D7AD12642C0A4005E8093 /* fpu.h */, + E41D7AD22642C0A4005E8093 /* impl.h */, + E41D7AD32642C0A4005E8093 /* mathlib.cpp */, + E41D7AD42642C0A4005E8093 /* mathlib.h */, + E41D7AD52642C0A4005E8093 /* rounding.cpp */, + E41D7AD62642C0A4005E8093 /* rounding.h */, + E41D7AD72642C0A4005E8093 /* types.h */, + ); + name = fpu; + sourceTree = ""; + }; + E4FC274B2642C44A00C64E21 /* generated */ = { + isa = PBXGroup; + children = ( + E4FC274D2642C45E00C64E21 /* cpuemu.cpp */, + E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */, + E4FC274E2642C45E00C64E21 /* cpustbl.cpp */, + E4FC274F2642C45E00C64E21 /* cputbl.h */, + E4FC27502642C45E00C64E21 /* defs68k.c */, + ); + path = generated; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + E41D7A9F2642C004005E8093 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E41D7AE82642C0A4005E8093 /* mathlib.h in Headers */, + E41D7ADA2642C0A4005E8093 /* exceptions.h in Headers */, + E41D7ABB2642C087005E8093 /* m68k.h in Headers */, + E41D7AC02642C087005E8093 /* readcpu.h in Headers */, + E41D7AEA2642C0A4005E8093 /* rounding.h in Headers */, + E41D7AAE2642C07C005E8093 /* cpu_emulation.h in Headers */, + E41D7AC22642C087005E8093 /* spcflags.h in Headers */, + E41D7AE52642C0A4005E8093 /* fpu.h in Headers */, + E41D7AAF2642C07C005E8093 /* cpummu.h in Headers */, + E41D7AC12642C087005E8093 /* registers.h in Headers */, + E41D7AD82642C0A4005E8093 /* core.h in Headers */, + E4FC27542642C45E00C64E21 /* cputbl.h in Headers */, + E41D7ABE2642C087005E8093 /* newcpu.h in Headers */, + E41D7AE62642C0A4005E8093 /* impl.h in Headers */, + E41D7ABC2642C087005E8093 /* memory.h in Headers */, + E41D7AEB2642C0A4005E8093 /* types.h in Headers */, + E41D7ADC2642C0A4005E8093 /* flags.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + E41D7AA02642C004005E8093 /* uae_cpu_arm64 */ = { + isa = PBXNativeTarget; + buildConfigurationList = E41D7AA52642C004005E8093 /* Build configuration list for PBXNativeTarget "uae_cpu_arm64" */; + buildPhases = ( + E4FC27492642C2E600C64E21 /* ShellScript */, + E41D7A9D2642C004005E8093 /* Sources */, + E41D7A9E2642C004005E8093 /* Frameworks */, + E41D7A9F2642C004005E8093 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = uae_cpu_arm64; + productName = uae_cpu_2021; + productReference = E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E41D7A992642C004005E8093 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0820; + TargetAttributes = { + E41D7AA02642C004005E8093 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = E41D7A9C2642C004005E8093 /* Build configuration list for PBXProject "uae_cpu_2021" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + ); + mainGroup = E41D7A982642C004005E8093; + productRefGroup = E41D7AA22642C004005E8093 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E41D7AA02642C004005E8093 /* uae_cpu_arm64 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + E4FC27492642C2E600C64E21 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + $BUILT_PRODUCTS_DIR/gencpu_output_2021/cpuemu.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output_2021/cpufunctbl.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output_2021/cpustbl.cpp, + $BUILT_PRODUCTS_DIR/gencpu_output_2021/cputbl.h, + $BUILT_PRODUCTS_DIR/gencpu_output_2021/defs68k.c, + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "make -f Makefile.gencpu_2021\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E41D7A9D2642C004005E8093 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E4FC27512642C45E00C64E21 /* cpufunctbl.cpp in Sources */, + E41D7ADB2642C0A4005E8093 /* flags.cpp in Sources */, + E41D7ADF2642C0A4005E8093 /* fpu_mpfr.cpp in Sources */, + E41D7ABD2642C087005E8093 /* newcpu.cpp in Sources */, + E4FC27552642C45E00C64E21 /* defs68k.c in Sources */, + E41D7AE72642C0A4005E8093 /* mathlib.cpp in Sources */, + E4FC27522642C45E00C64E21 /* cpuemu.cpp in Sources */, + E4FC27532642C45E00C64E21 /* cpustbl.cpp in Sources */, + E41D7AD92642C0A4005E8093 /* exceptions.cpp in Sources */, + E41D7AAA2642C070005E8093 /* basilisk_glue.cpp in Sources */, + E41D7ABF2642C087005E8093 /* readcpu.cpp in Sources */, + E41D7AE92642C0A4005E8093 /* rounding.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E41D7AA32642C004005E8093 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + E41D7AA42642C004005E8093 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + E41D7AA62642C004005E8093 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "USE_XCODE=1", + ); + HEADER_SEARCH_PATHS = ( + /usr/local/include, + ../CrossPlatform, + ../include, + ../MacOSX, + ../uae_cpu_2021, + ../Unix, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + VALID_ARCHS = arm64; + }; + name = Debug; + }; + E41D7AA72642C004005E8093 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = "USE_XCODE=1"; + HEADER_SEARCH_PATHS = ( + /usr/local/include, + ../CrossPlatform, + ../include, + ../MacOSX, + ../uae_cpu_2021, + ../Unix, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + VALID_ARCHS = arm64; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E41D7A9C2642C004005E8093 /* Build configuration list for PBXProject "uae_cpu_2021" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E41D7AA32642C004005E8093 /* Debug */, + E41D7AA42642C004005E8093 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E41D7AA52642C004005E8093 /* Build configuration list for PBXNativeTarget "uae_cpu_arm64" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E41D7AA62642C004005E8093 /* Debug */, + E41D7AA72642C004005E8093 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E41D7A992642C004005E8093 /* Project object */; +} diff --git a/BasiliskII/src/MacOSX/utils_macosx.h b/BasiliskII/src/MacOSX/utils_macosx.h index fc2c83c69..0b7bb0c8d 100644 --- a/BasiliskII/src/MacOSX/utils_macosx.h +++ b/BasiliskII/src/MacOSX/utils_macosx.h @@ -24,4 +24,6 @@ // Invokes the specified function with an NSAutoReleasePool in place. void NSAutoReleasePool_wrap(void (*fn)(void)); +bool MetalIsAvailable(); + #endif diff --git a/BasiliskII/src/MacOSX/utils_macosx.mm b/BasiliskII/src/MacOSX/utils_macosx.mm index 6fcb8290e..9dbcff693 100644 --- a/BasiliskII/src/MacOSX/utils_macosx.mm +++ b/BasiliskII/src/MacOSX/utils_macosx.mm @@ -27,6 +27,9 @@ #include #endif +#include +#include + // This is used from video_sdl.cpp. void NSAutoReleasePool_wrap(void (*fn)(void)) { @@ -36,6 +39,7 @@ void NSAutoReleasePool_wrap(void (*fn)(void)) } #if SDL_VERSION_ATLEAST(2,0,0) + void disable_SDL2_macosx_menu_bar_keyboard_shortcuts() { for (NSMenuItem * menu_item in [NSApp mainMenu].itemArray) { if (menu_item.hasSubmenu) { @@ -80,3 +84,14 @@ void set_current_directory() [pool release]; } +bool MetalIsAvailable() { + const int EL_CAPITAN = 15; // Darwin major version of El Capitan + char s[16]; + size_t size = sizeof(s); + int v; + if (sysctlbyname("kern.osrelease", s, &size, NULL, 0) || sscanf(s, "%d", &v) != 1 || v < EL_CAPITAN) return false; + id dev = MTLCreateSystemDefaultDevice(); + bool r = dev != nil; + [dev release]; + return r; +} diff --git a/BasiliskII/src/MacOSX/video_macosx.mm b/BasiliskII/src/MacOSX/video_macosx.mm index 8323038c3..991483367 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; @@ -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 @@ -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/SDL/SDLMain.m b/BasiliskII/src/SDL/SDLMain.m index 0f23664dd..811e05e16 100644 --- a/BasiliskII/src/SDL/SDLMain.m +++ b/BasiliskII/src/SDL/SDLMain.m @@ -6,6 +6,8 @@ */ #include "SDL.h" +#if (SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)) // SDLMain.m is not needed in SDL 2.x + #include "SDLMain.h" #include /* for MAXPATHLEN */ #include @@ -379,3 +381,4 @@ int main (int argc, char **argv) return 0; } +#endif // ends: SDL version check diff --git a/BasiliskII/src/SDL/audio_sdl.cpp b/BasiliskII/src/SDL/audio_sdl.cpp index a7e949cfa..42406c2bb 100644 --- a/BasiliskII/src/SDL/audio_sdl.cpp +++ b/BasiliskII/src/SDL/audio_sdl.cpp @@ -28,12 +28,14 @@ #include #include +#include +#include #define DEBUG 0 #include "debug.h" #if defined(BINCUE) -#include "bincue_unix.h" +#include "bincue.h" #endif @@ -53,6 +55,7 @@ static bool audio_mute = false; // Prototypes static void stream_func(void *arg, uint8 *stream, int stream_len); +static int play_startup(void *arg); /* @@ -91,7 +94,7 @@ static bool open_sdl_audio(void) audio_spec.freq = audio_sample_rates[audio_sample_rate_index] >> 16; audio_spec.format = (audio_sample_sizes[audio_sample_size_index] == 8) ? AUDIO_U8 : AUDIO_S16MSB; audio_spec.channels = audio_channel_counts[audio_channel_count_index]; - audio_spec.samples = 4096; + audio_spec.samples = 4096 >> PrefsFindInt32("sound_buffer"); audio_spec.callback = stream_func; audio_spec.userdata = NULL; @@ -101,7 +104,7 @@ static bool open_sdl_audio(void) return false; } -#ifdef ENABLE_SDL2 +#if SDL_VERSION_ATLEAST(2,0,0) // HACK: workaround a bug in SDL pre-2.0.6 (reported via https://bugzilla.libsdl.org/show_bug.cgi?id=3710 ) // whereby SDL does not update audio_spec.size if (audio_spec.size == 0) { @@ -111,10 +114,10 @@ static bool open_sdl_audio(void) #if defined(BINCUE) OpenAudio_bincue(audio_spec.freq, audio_spec.format, audio_spec.channels, - audio_spec.silence); + audio_spec.silence, audio_volume); #endif -#ifdef ENABLE_SDL2 +#if SDL_VERSION_ATLEAST(2,0,0) const char * driver_name = SDL_GetCurrentAudioDriver(); #else char driver_name[32]; @@ -165,6 +168,8 @@ void AudioInit(void) // Open and initialize audio device open_audio(); + + SDL_CreateThread(play_startup, "", NULL); } @@ -248,11 +253,13 @@ static void stream_func(void *arg, uint8 *stream, int stream_len) } else { // Audio not active, play silence -silence: memset(stream, silence_byte, stream_len); + silence: memset(stream, silence_byte, stream_len); } + #if defined(BINCUE) - MixAudio_bincue(stream, stream_len); + MixAudio_bincue(stream, stream_len, audio_volume); #endif + } @@ -356,3 +363,23 @@ void audio_set_speaker_mute(bool mute) void audio_set_speaker_volume(uint32 vol) { } + +static int play_startup(void *arg) { + SDL_AudioSpec wav_spec; + Uint8 *wav_buffer; + Uint32 wav_length; + if (SDL_LoadWAV("startup.wav", &wav_spec, &wav_buffer, &wav_length)) { + SDL_AudioSpec obtained; + SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &obtained, 0); + if (deviceId) { + SDL_QueueAudio(deviceId, wav_buffer, wav_length); + SDL_PauseAudioDevice(deviceId, 0); + while (SDL_GetQueuedAudioSize(deviceId)) SDL_Delay(10); + SDL_Delay(500); + SDL_CloseAudioDevice(deviceId); + } + else printf("play_startup: Audio driver failed to initialize\n"); + SDL_FreeWAV(wav_buffer); + } + return 0; +} diff --git a/BasiliskII/src/SDL/keycodes b/BasiliskII/src/SDL/keycodes index da9185603..1ee627a8a 100644 --- a/BasiliskII/src/SDL/keycodes +++ b/BasiliskII/src/SDL/keycodes @@ -352,6 +352,113 @@ sdl Quartz 82 82 # KP 0 65 65 # KP . +# +# cocoa (SDL2) +# +sdl cocoa +53 53 # Esc +122 122 # F1 +120 120 # F2 +99 99 # F3 +118 118 # F4 +96 96 # F5 +97 97 # F6 +98 98 # F7 +100 100 # F8 +101 101 # F9 +109 109 # F10 +103 103 # F11 +111 111 # F12 +105 105 # F13/PrintScrn +107 107 # F14/Scroll Lock +113 113 # F15/Pause +10 10 # ` +18 18 # 1 +19 19 # 2 +20 20 # 3 +21 21 # 4 +23 23 # 5 +22 22 # 6 +26 26 # 7 +28 28 # 8 +25 25 # 9 +29 29 # 0 +27 27 # - +24 24 # = +51 51 # Backspace +114 114 # Help/Insert +115 115 # Home +116 116 # Page Up +71 71 # Num Lock +81 81 # KP = +75 75 # KP / +67 67 # KP * +48 48 # Tab +12 12 # Q +13 13 # W +14 14 # E +15 15 # R +17 17 # T +16 16 # Y +32 32 # U +34 34 # I +31 31 # O +35 35 # P +33 33 # [ +30 30 # ] +36 36 # Return +117 117 # Delete +119 119 # End +121 121 # Page Down +89 89 # KP 7 +91 91 # KP 8 +92 92 # KP 9 +78 78 # KP - +57 57 # Caps Lock +0 0 # A +1 1 # S +2 2 # D +3 3 # F +5 5 # G +4 4 # H +38 38 # J +40 40 # K +37 37 # L +41 41 # ; +39 39 # ' +42 42 # \ +86 86 # KP 4 +87 87 # KP 5 +88 88 # KP 6 +69 69 # KP + +56 56 # Shift +50 50 # International +6 6 # Z +7 7 # X +8 8 # C +9 9 # V +11 11 # B +45 45 # N +46 46 # M +43 43 # , +47 47 # . +44 44 # / +126 62 # Cursor Up +123 59 # Cursor Left +125 61 # Cursor Down +124 60 # Cursor Right +83 83 # KP 1 +84 84 # KP 2 +85 85 # KP 3 +76 76 # KP Enter +54 54 # Ctrl +58 58 # Option +55 55 # Command +54 54 # Ctrl Left +49 49 # Space +82 82 # KP 0 +65 65 # KP . + # # Windows # diff --git a/BasiliskII/src/BeOS/prefs_beos.cpp b/BasiliskII/src/SDL/prefs_sdl.cpp similarity index 58% rename from BasiliskII/src/BeOS/prefs_beos.cpp rename to BasiliskII/src/SDL/prefs_sdl.cpp index 9a74d6431..5151f7604 100644 --- a/BasiliskII/src/BeOS/prefs_beos.cpp +++ b/BasiliskII/src/SDL/prefs_sdl.cpp @@ -1,5 +1,5 @@ /* - * prefs_beos.cpp - Preferences handling, BeOS specific stuff + * prefs_sdl.cpp - Preferences handling, SDL2 implementation * * Basilisk II (C) 1997-2008 Christian Bauer * @@ -18,55 +18,48 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include "sysdeps.h" + #include #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 + {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, + {"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"}, + {NULL, TYPE_END, false} // End of list }; -// Preferences file name and path -const char PREFS_FILE_NAME[] = "BasiliskII_prefs"; -static BPath prefs_path; +// Prefs file name and path +const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs"; + +std::string UserPrefsPath; /* * Load preferences from settings file */ -void LoadPrefs(const char* vmdir) +void LoadPrefs(const char * vmdir) // TODO: load prefs from '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; + // Build a full-path to the settings file + char prefs_path[4096]; + if (!vmdir) { + vmdir = SDL_getenv("HOME"); } -#endif - - // Construct prefs path - find_directory(B_USER_SETTINGS_DIRECTORY, &prefs_path, true); - prefs_path.Append(PREFS_FILE_NAME); - + if (!vmdir) { + vmdir = "./"; + } + SDL_snprintf(prefs_path, sizeof(prefs_path), "%s/%s", vmdir, PREFS_FILE_NAME); + // Read preferences from settings file - FILE *f = fopen(prefs_path.Path(), "r"); + FILE *f = fopen(UserPrefsPath.empty() ? prefs_path : UserPrefsPath.c_str(), "r"); if (f != NULL) { // Prefs file found, load settings @@ -87,8 +80,16 @@ void LoadPrefs(const char* vmdir) void SavePrefs(void) { + // Build a full-path to the settings file + char prefs_path[4096]; + const char * dir = SDL_getenv("HOME"); + if (!dir) { + dir = "./"; + } + SDL_snprintf(prefs_path, sizeof(prefs_path), "%s/%s", dir, PREFS_FILE_NAME); + FILE *f; - if ((f = fopen(prefs_path.Path(), "w")) != NULL) { + if ((f = fopen(UserPrefsPath.empty() ? prefs_path : UserPrefsPath.c_str(), "w")) != NULL) { SavePrefsToStream(f); fclose(f); } @@ -102,5 +103,4 @@ void SavePrefs(void) void AddPlatformPrefsDefaults(void) { - PrefsReplaceString("extfs", "/boot"); } diff --git a/BasiliskII/src/SDL/video_sdl.cpp b/BasiliskII/src/SDL/video_sdl.cpp deleted file mode 100644 index d5ba4f5d5..000000000 --- a/BasiliskII/src/SDL/video_sdl.cpp +++ /dev/null @@ -1,2292 +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" - -#ifdef ENABLE_SDL1 -#include -#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 -#ifdef WIN32 -const char KEYCODE_FILE_NAME[] = "BasiliskII_keycodes"; -#else -const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; -#endif - -// Mac Screen Width and Height -uint32 MacScreenWidth; -uint32 MacScreenHeight; - -// 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) - -// 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) -{ - void *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) -{ -#ifdef SHEEPSHAVER - // Filter out Classic resolutions - if (width == 512 && height == 384) - return false; -#endif - - // 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; - - if (TwentyFourBitAddressing) - monitor.set_mac_frame_base(MacFrameBaseMac24Bit); - else - 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 - // set Mac screen global variabls - MacScreenWidth = VIDEO_MODE_X; - MacScreenHeight = VIDEO_MODE_Y; - D(bug("Set Mac Screen Width: %d, Mac Screen Height: %d\n", MacScreenWidth, MacScreenHeight)); -} - -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); - if (VM_MAP_FAILED == the_buffer) { - perror("Failed to allocate frame buffer for guest OS."); - abort(); - } - 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); - if (VM_MAP_FAILED == the_buffer) { - perror("Failed to allocate frame buffer for guest OS."); - abort(); - } - 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; - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width, default_height; - if (classic) { - default_width = 512; - default_height = 342; - } - 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(); - - // for classic Mac, make sure the display width is divisible by 8 - if (classic) { - default_width = (default_width / 8) * 8; - } - - // 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; - } - 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, } - }; - 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, default_width, default_height, 0x80, default_width/8, 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(); - - // FIXME: how can we handle the gamma ramp? - if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) - 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 ((int)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 //ifdef ENABLE_SDL1 diff --git a/BasiliskII/src/SDL/video_sdl2.cpp b/BasiliskII/src/SDL/video_sdl2.cpp index a7c5d9153..453dc43e7 100644 --- a/BasiliskII/src/SDL/video_sdl2.cpp +++ b/BasiliskII/src/SDL/video_sdl2.cpp @@ -38,10 +38,11 @@ * - Backport hw cursor acceleration to Basilisk II? * - Factor out code */ + #include "sysdeps.h" -#ifdef ENABLE_SDL2 #include +#if SDL_VERSION_ATLEAST(2,0,0) #include #include @@ -49,6 +50,10 @@ #include #include +#ifdef __MACOSX__ +#include "utils_macosx.h" +#endif + #ifdef WIN32 #include /* alloca() */ #endif @@ -98,18 +103,16 @@ const char KEYCODE_FILE_NAME[] = DATADIR "/keycodes"; const char KEYCODE_FILE_NAME2[] = DATADIR "/BasiliskII_keycodes"; #endif -// Mac Screen Width and Height -uint32 MacScreenWidth; -uint32 MacScreenHeight; // 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 +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 @@ -170,6 +173,17 @@ 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); @@ -190,44 +204,27 @@ extern void SysMountFirstFloppy(void); */ #ifdef ENABLE_VOSF -#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ +#define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ if (sdl_window && SDL_GetWindowFlags(sdl_window) & (SDL_WINDOW_FULLSCREEN)) \ - the_host_buffer = (uint8 *)(SURFACE)->pixels; \ + 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); \ - } \ +#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); \ + if (SDL_MUSTLOCK(SURFACE)) \ + SDL_UnlockSurface(SURFACE); \ } while (0) - -/* - * Framebuffer allocation routines - */ - -static void *vm_acquire_framebuffer(uint32 size) -{ - void *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) -{ +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)); @@ -321,8 +318,10 @@ class monitor_desc { 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; + + // 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() @@ -367,6 +366,7 @@ class SDL_monitor_desc : public 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); @@ -486,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) @@ -499,52 +499,33 @@ static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool nati MacFrameLayout = layout; else MacFrameLayout = FLAYOUT_DIRECT; - - if (TwentyFourBitAddressing) - monitor.set_mac_frame_base(MacFrameBaseMac24Bit); - else - monitor.set_mac_frame_base(MacFrameBaseMac); + 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(); + memory_init(); #else - monitor.set_mac_frame_base(Host2MacAddr(the_buffer)); + monitor.set_mac_frame_base(Host2MacAddr(MacFrameBaseHost)); #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) -{ - if (!sdl_window) { - return; - } - const char *str = GetString(name); - SDL_SetWindowTitle(sdl_window, str); -} - -static void set_window_name_grabbed() { +static void set_window_name() { if (!sdl_window) return; - int hotkey = PrefsFindInt32("hotkey"); - if (!hotkey) hotkey = 1; - std::string s = GetString(STR_WINDOW_TITLE_GRABBED0); - 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()); -} - -// Set mouse grab mode -static void set_grab_mode(bool grab) -{ - 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_SetWindowGrab(sdl_window, grab ? SDL_TRUE : SDL_FALSE); + SDL_SetWindowTitle(sdl_window, s.c_str()); } // Migrate preferences items (XXX to be handled in MigratePrefs()) @@ -644,7 +625,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; } @@ -689,15 +669,21 @@ static void shutdown_sdl_video() delete_sdl_video_window(); } -static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags) +static int get_mag_rate() { - if (guest_surface) { - delete_sdl_video_surfaces(); - } + 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 | SDL_WINDOW_RESIZABLE; + Uint32 window_flags = SDL_WINDOW_ALLOW_HIGHDPI; const int window_flags_to_monitor = SDL_WINDOW_FULLSCREEN; if (flags & SDL_WINDOW_FULLSCREEN) { @@ -708,11 +694,11 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags } #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 - window_width = desktop_mode.w; - window_height = desktop_mode.h; } if (sdl_window) { @@ -720,8 +706,8 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 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)) + old_window_height != window_height || + (old_window_flags & window_flags_to_monitor) != (window_flags & window_flags_to_monitor)) { delete_sdl_video_window(); } @@ -729,23 +715,24 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, PrefsFindBool("scale_nearest") ? "nearest" : "linear"); - /* - // Always use a resize-able window. This helps allow SDL to manage - // transitions involving fullscreen to or from windowed-mode. - window_flags |= SDL_WINDOW_RESIZABLE; -*/ +#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( - "Basilisk II", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - window_width, - window_height, - window_flags); + "", + 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); @@ -765,11 +752,20 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags 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; @@ -781,82 +777,78 @@ static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags 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(); - } + + 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_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; - } - } + 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()); + width, height, SDL_GetError()); shutdown_sdl_video(); return NULL; } SDL_RenderSetIntegerScale(sdl_renderer, PrefsFindBool("scale_integer") ? SDL_TRUE : SDL_FALSE); - // set Mac screen global variabls - MacScreenWidth = width; - MacScreenHeight = height; - D(bug("Set Mac Screen Width: %d, Mac Screen Height: %d\n", MacScreenWidth, MacScreenHeight)); - return guest_surface; + return guest_surface; } static int present_sdl_video() @@ -887,10 +879,10 @@ static int present_sdl_video() // 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) + // 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); @@ -902,52 +894,52 @@ static int present_sdl_video() } 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); + // 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); + 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); + // 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) { + // Copy the texture to the display + if (SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL) != 0) { return -1; } - // Update the display + // Update the display SDL_RenderPresent(sdl_renderer); - - // Indicate success to the caller! - return 0; + + // 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); + // 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); + SDL_Rect temp = {x, y, w, h}; + update_sdl_video(s, 1, &temp); } #ifdef SHEEPSHAVER @@ -991,34 +983,16 @@ void driver_base::set_video_mode(int flags) void driver_base::init() { set_video_mode(display_type == DISPLAY_SCREEN ? SDL_WINDOW_FULLSCREEN : 0); -#ifndef SHEEPSHAVER - // manually set palette for 24bit ROM - // 24 bit ROM Macintosh is BW screen. It doesn't setup palette by the ROM. - if (TwentyFourBitAddressing && !sdl_palette) { - const int nColor = 256; - sdl_palette = SDL_AllocPalette(nColor); - SDL_Color *p = sdl_palette->colors; - for (int i = 0; i < nColor; i++) { - p->r = p->g = p->b = i; - p++; - } - update_palette(); - } -#endif - 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); + assert(the_buffer_size<=VRAMSize); + assert(MacFrameBaseHost); the_buffer_copy = (uint8 *)malloc(the_buffer_size); - if (VM_MAP_FAILED == the_buffer) { - perror("Failed to allocate frame buffer for guest OS."); - abort(); - } - 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)) { @@ -1030,28 +1004,29 @@ void driver_base::init() printf("VOSF acceleration is not profitable on this platform, disabling it\n"); use_vosf = false; } - if (!use_vosf) { + 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); - if (VM_MAP_FAILED == the_buffer) { - perror("Failed to allocate frame buffer for guest OS."); - abort(); - } - 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 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() { @@ -1096,7 +1071,7 @@ void driver_base::adapt_to_video_mode() { SDL_ShowCursor(hardware_cursor); // Set window name/class - mouse_grabbed ? set_window_name_grabbed() : set_window_name((int)STR_WINDOW_TITLE); + set_window_name(); // Everything went well init_ok = true; @@ -1114,14 +1089,7 @@ driver_base::~driver_base() // 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; - } + // instances of SDL_Surface and SDL_Texture. // Free frame buffer(s) if (!use_vosf) { @@ -1196,7 +1164,7 @@ void driver_base::grab_mouse(void) if (!mouse_grabbed) { mouse_grabbed = true; update_mouse_grab(); - set_window_name_grabbed(); + set_window_name(); disable_mouse_accel(); ADBSetRelMouseMode(true); } @@ -1208,7 +1176,7 @@ void driver_base::ungrab_mouse(void) if (mouse_grabbed) { mouse_grabbed = false; update_mouse_grab(); - set_window_name(STR_WINDOW_TITLE); + set_window_name(); restore_mouse_accel(); ADBSetRelMouseMode(false); } @@ -1376,17 +1344,22 @@ bool VideoInit(bool classic) 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"); - mode_str = PrefsFindString("screen"); // Determine display type and default dimensions int default_width, default_height; if (classic) { default_width = 512; - default_height = 342; + default_height = 384; } else { default_width = 640; @@ -1408,10 +1381,6 @@ bool VideoInit(bool classic) else if (default_height > sdl_display_height()) default_height = sdl_display_height(); - // for classic Mac, make sure the display width is divisible by 8 - if (classic) { - default_width = (default_width / 8) * 8; - } // Mac screen depth follows X depth screen_depth = 32; SDL_DisplayMode desktop_mode; @@ -1471,7 +1440,7 @@ bool VideoInit(bool classic) // Construct list of supported modes if (display_type == DISPLAY_WINDOW) { if (classic) - add_mode(display_type, default_width, default_height, 0x80, default_width/8, VIDEO_DEPTH_1BIT); + 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; @@ -1618,6 +1587,26 @@ void VideoQuitFullScreen(void) 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 @@ -1633,7 +1622,8 @@ static void do_toggle_fullscreen(void) display_type = DISPLAY_WINDOW; SDL_SetWindowFullscreen(sdl_window, 0); const VIDEO_MODE &mode = drv->mode; - SDL_SetWindowSize(sdl_window, VIDEO_MODE_X, VIDEO_MODE_Y); + 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; @@ -1653,6 +1643,7 @@ static void do_toggle_fullscreen(void) #ifdef SHEEPSHAVER video_set_palette(); #endif + ApplyGammaRamp(); drv->update_palette(); // reset the video refresh handler @@ -1757,16 +1748,25 @@ void video_set_palette(void) } 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(); - - // FIXME: how can we handle the gamma ramp? - if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) - return; - + LOCK_PALETTE; // Convert colors to XColor array @@ -1809,6 +1809,48 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) 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(); + } + +} + /* @@ -1820,12 +1862,12 @@ 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; + (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)) { + (ReadMacInt32(ParamPtr + csData) == VModes[i].viAppleID)) { csSave->saveMode = ReadMacInt16(ParamPtr + csMode); csSave->saveData = ReadMacInt32(ParamPtr + csData); csSave->savePage = ReadMacInt16(ParamPtr + csPage); @@ -1855,6 +1897,38 @@ int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr) } #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 @@ -1910,10 +1984,14 @@ void video_set_cursor(void) if (move) { int visible = SDL_ShowCursor(-1); if (visible) { - int x, y; - SDL_GetMouseState(&x, &y); - printf("WarpMouse to {%d,%d} via video_set_cursor\n", x, y); - SDL_WarpMouseGlobal(x, y); + 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); + } } } } @@ -1935,6 +2013,20 @@ static bool is_hotkey_down(SDL_Keysym const & ks) (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 @@ -2010,17 +2102,8 @@ static int kc_decode(SDL_Keysym const & ks, bool key_down) case SDLK_RCTRL: return 0x36; case SDLK_LSHIFT: return 0x38; case SDLK_RSHIFT: return 0x38; -#ifdef __APPLE__ - case SDLK_LALT: return 0x3a; - case SDLK_RALT: return 0x3a; - case SDLK_LGUI: return 0x37; - case SDLK_RGUI: return 0x37; -#else - case SDLK_LALT: return 0x37; - case SDLK_RALT: return 0x37; - case SDLK_LGUI: return 0x3a; - case SDLK_RGUI: return 0x3a; -#endif + 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; @@ -2086,11 +2169,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]; } } @@ -2113,55 +2196,48 @@ enum { 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; + 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; - } - } break; - - case SDL_WINDOWEVENT: { - switch (event->window.event) { - case SDL_WINDOWEVENT_RESIZED: { - // 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(); - + + 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); - } + // 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; // end of SDL_WINDOWEVENT_RESIZED - case SDL_WINDOWEVENT_RESTORED: { - // When the user minimizes the window and then restore it, - // we restore the scale factor to 1. - if (sdl_window) { - const VIDEO_MODE &mode = drv->mode; - SDL_SetWindowSize(sdl_window, VIDEO_MODE_X, VIDEO_MODE_Y); - } - } break; // end of SDL_WINDOWEVENT_RESTORED - } - } break; // end of SDL_WINDOWEVENT + } break; } return EVENT_ADD_TO_QUEUE; @@ -2202,7 +2278,7 @@ static void handle_events(void) break; } - // Mouse moved + // Mouse moved case SDL_MOUSEMOTION: if (mouse_grabbed) { drv->mouse_moved(event.motion.xrel, event.motion.yrel); @@ -2214,21 +2290,23 @@ static void handle_events(void) case SDL_MOUSEWHEEL: if (!event.wheel.y) break; if (!mouse_wheel_mode) { - int key = event.wheel.y < 0 ? 0x79 : 0x74; // Page up/down + 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 ? 0x3d : 0x3e; // Cursor up/down + 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; + break; - // Keyboard + // 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]; @@ -2236,27 +2314,21 @@ static void handle_events(void) code = event2keycode(event.key, true); if (code >= 0) { if (!emul_suspended) { -#ifdef WIN32 + code = modify_opt_cmd(code); +#ifdef __MACOSX__ + ADBKeyDown(code); +#else if (code == 0x39) (SDL_GetModState() & KMOD_CAPS ? ADBKeyDown : ADBKeyUp)(code); else ADBKeyDown(code); -#else - ADBKeyDown(code); #endif if (code == 0x36) ctrl_down = true; -#ifdef __APPLE__ if (code == 0x3a) opt_down = true; if (code == 0x37) cmd_down = true; -#else - if (code == 0x37) - opt_down = true; - if (code == 0x3a) - cmd_down = true; -#endif } else { if (code == 0x31) @@ -2272,46 +2344,40 @@ static void handle_events(void) if (code == CODE_INVALID) code = event2keycode(event.key, false); if (code >= 0) { -#ifdef WIN32 + code = modify_opt_cmd(code); +#ifdef __MACOSX__ + ADBKeyUp(code); +#else if (code != 0x39) ADBKeyUp(code); -#else - ADBKeyUp(code); #endif if (code == 0x36) ctrl_down = false; -#ifdef __APPLE__ if (code == 0x3a) opt_down = false; if (code == 0x37) cmd_down = false; -#else - if (code == 0x37) - opt_down = false; - if (code == 0x3a) - cmd_down = false; -#endif } 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; + // 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; + case SDL_WINDOWEVENT_RESTORED: + force_complete_window_refresh(); + break; } break; } - // Window "close" widget clicked + // Window "close" widget clicked case SDL_QUIT: if (SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) break; ADBKeyDown(0x7f); // Power key @@ -2336,18 +2402,19 @@ static void update_display_static(driver_base *drv) 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)) { + 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; } @@ -2359,11 +2426,13 @@ static void update_display_static(driver_base *drv) 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 = VIDEO_MODE_X / src_bytes_per_row; + const int pixels_per_byte = 8/mac_depth_of_video_depth(VIDEO_MODE_DEPTH); - x1 = VIDEO_MODE_X / pixels_per_byte; + 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]; + p = &MacFrameBaseHost[j * bytes_per_row]; p2 = &the_buffer_copy[j * bytes_per_row]; for (uint32 i = 0; i < x1; i++) { if (*p != *p2) { @@ -2375,11 +2444,11 @@ 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; - for (uint32 i = (VIDEO_MODE_X / pixels_per_byte); i > x2; i--) { + for (uint32 i = line_len; i > x2; i--) { p--; p2--; if (*p != *p2) { x2 = i; @@ -2387,11 +2456,14 @@ static void update_display_static(driver_base *drv) } } } + x1 *= pixels_per_byte; x2 *= pixels_per_byte; - wide = (x2 - x1 + pixels_per_byte - 1) & -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 + // Update copy of frame buffer if (high && wide) { // Lock surface, if required @@ -2402,8 +2474,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; } @@ -2413,7 +2485,7 @@ static void update_display_static(driver_base *drv) SDL_UnlockSurface(drv->s); // Refresh display - update_sdl_video(drv->s, x1, y1, wide, high); + update_sdl_video(drv->s, x1, y1, wide_clipped, high); } } else { @@ -2422,7 +2494,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) { @@ -2434,7 +2506,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; @@ -2449,7 +2521,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 @@ -2460,8 +2532,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 @@ -2510,9 +2582,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; } } @@ -2752,4 +2824,4 @@ void video_set_dirty_area(int x, int y, int w, int h) } #endif -#endif //ifdef ENABLE_SDL2 +#endif // ends: SDL version check diff --git a/BasiliskII/src/SDL/xpram_sdl.cpp b/BasiliskII/src/SDL/xpram_sdl.cpp new file mode 100644 index 000000000..c6f558004 --- /dev/null +++ b/BasiliskII/src/SDL/xpram_sdl.cpp @@ -0,0 +1,98 @@ +/* + * xpram_sdl.cpp - XPRAM handling, SDL 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 "xpram.h" + + +// XPRAM file name and path +const char XPRAM_FILE_NAME[] = ".basilisk_ii_xpram"; + + +/* + * Load XPRAM from settings file + */ + +void LoadXPRAM(const char *dir) +{ + // Build a full-path to the file + char full_path[4096]; + if (!dir) { + dir = SDL_getenv("HOME"); + } + if (!dir) { + dir = "./"; + } + SDL_snprintf(full_path, sizeof(full_path), "%s/%s", dir, XPRAM_FILE_NAME); + + // Open the XPRAM file + FILE *f = fopen(full_path, "rb"); + if (f != NULL) { + fread(XPRAM, 256, 1, f); + fclose(f); + } +} + + +/* + * Save XPRAM to settings file + */ + +void SaveXPRAM(void) +{ + // Build a full-path to the file + char full_path[4096]; + const char *dir = SDL_getenv("HOME"); + if (!dir) { + dir = "./"; + } + SDL_snprintf(full_path, sizeof(full_path), "%s/%s", dir, XPRAM_FILE_NAME); + + // Save the XPRAM file + FILE *f = fopen(full_path, "wb"); + if (f != NULL) { + fwrite(XPRAM, 256, 1, f); + fclose(f); + } +} + + +/* + * Delete PRAM file + */ + +void ZapPRAM(void) +{ + // Build a full-path to the file + char full_path[4096]; + const char *dir = SDL_getenv("HOME"); + if (!dir) { + dir = "./"; + } + SDL_snprintf(full_path, sizeof(full_path), "%s/%s", dir, XPRAM_FILE_NAME); + + // Delete the XPRAM file + remove(full_path); +} 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/BasiliskII_128x128x32_icon.c b/BasiliskII/src/Unix/BasiliskII_128x128x32_icon.c deleted file mode 100644 index da13849aa..000000000 --- a/BasiliskII/src/Unix/BasiliskII_128x128x32_icon.c +++ /dev/null @@ -1,2672 +0,0 @@ -/* GIMP RGBA C-Source image dump (BasiliskII_128x128x32_icon.c) */ - -static const struct { - unsigned int width; - unsigned int height; - unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ - unsigned char pixel_data[128 * 128 * 4 + 1]; -} icon_128x128x32 = { - 128, 128, 4, - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\277\277\277\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\274\254P\377\223" - "}\200\377`>\277\377`>\277\377\274\254P\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\337\337\337\30PPP\377\312" - "\312\3121\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\337\327\40\377\207n\217\3778\16\357\377L\0\377\377[\0\377\377i\0\377" - "\377c\0\377\3778\16\357\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\342\342\342\11PPP\377PPP\377PPP\377\245\245\245X\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\307\273@\377`>\277\3779\0\377" - "\377f\0\377\377\215\0\377\377\220\0\377\377\210\0\377\377}\0\377\377g\0\377" - "\377E\36\337\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\1\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\1\\\\\\\242PPP\377PPP\377PPP\377PPP\377jjj\224\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\377\307\273@\377`>\277\377F\0\377\377z\0\377\377\224\0\377\377\223\0\377" - "\377\220\0\377\377\213\0\377\377}\0\377\377S\0\377\377S.\317\371\325\312" - "1\177\177\177\2\177\177\177\2\252\252\252\3\277\277\277\4\277\277\277\4\277" - "\277\277\4\252\252\252\3\177\177\177\2\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0jjj\224PPP\377PPP\377PPP\377PPP\377" - "PPP\377\312\312\3121\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\307\273@\377`>\277\377F\0\377\377z\0\377\377\223" - "\0\377\377\223\0\377\377\221\0\377\377\216\0\377\377}\0\377\377R\0\377\377" - "<\16\357\377\224~\201\252\252\252\3\277\277\277\4\324\324\324\6\337\337\337" - "\10\342\342\342\11\347\347\347\13\347\347\347\13\345\345\345\12\337\337\337" - "\10\314\314\314\5\252\252\252\3\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\245\245\245XPPP\377PPP\377PPP\377PPP\377PPP\377\245\245\245" - "X\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\337" - "\327\40\377mN\257\377F\0\377\377z\0\377\377\223\0\377\377\222\0\377\377\220" - "\0\377\377\215\0\377\377r\0\377\377N\0\377\377E\36\337\374\240\213q\361\344" - "\344\23\314\314\314\5\337\337\337\10\347\347\347\13\356\356\356\17\361\361" - "\361\23\350\350\350\27\353\353\353\32\353\353\353\32\361\344\335&\371\203" - "j\227\375R.\321\3778\16\357\375_>\300\377`>\277\377mN\257\377\223}\200\377" - "\223}\200\377\257\234`\342\257\244Z|G<\377|G<\377[NK\377PPP\377PPP\377jj" - "j\224\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\357\337\20\377\307\273@\377\257\234`\377\223}\200\377`>\277\377y^\237\377" - "\357\337\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377\357\337\20\377\207n\217\3779\0\377\377s\0\377\377" - "\223\0\377\377\222\0\377\377\220\0\377\377\215\0\377\377r\0\377\377B\0\377" - "\377`>\277\374\255\235a\252\252\252\3\324\324\324\6\342\342\342\11\353\353" - "\353\15\361\361\361\23\353\353\353\32\347\347\347!\346\346\346)\344\344\344" - "0\341\341\3414\341\341\3413\361\224\200\211\377T\0\377\377{\0\377\377\213" - "\0\377\377y\0\377\377x\0\377\377r\0\377\377_\0\377\377^\0\377\377Q\0\377" - "\377E\0\377\377E\0\377\377E\0\377\3772\0\377\377,\0\377\377,\0\377\377,\0" - "\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377" - ",\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377" - "\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0" - "\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377" - ",\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377" - "\377,\0\377\377,\0\377\3772\0\377\377A\0\377\377I\0\377\377P\0\377\377_\0" - "\377\377V\0\377\377`>\277\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\1\0\0\0\1" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\257\234`\377>\16\357\377f\0\377\377\223\0\377" - "\377\222\0\377\377\220\0\377\377\214\0\377\377|\0\377\377M\0\377\377`>\277" - "\373\310\274A\252\252\252\3\324\324\324\6\342\342\342\11\354\354\354\16\362" - "\362\362\25\355\355\355\35\345\345\345(\341\341\3413\336\336\336?\326\326" - "\326K\324\324\324T\320\320\320X\322\322\322U\365W6\322\377t\0\377\377\222" - "\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377\224\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377" - "\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377" - "\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223" - "\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0" - "\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377" - "\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377" - "\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223" - "\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0\377\377\223\0" - "\377\377\223\0\377\377\222\0\377\377\216\0\377\377\205\0\377\377|\0\377\377" - "u\0\377\377q\0\377\377p\0\377\377,\0\377\252\252\252\3\252\252\252\3\277" - "\277\277\4\277\277\277\4\277\277\277\4\252\252\252\3\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\324\311" - "0\377`>\277\377S\0\377\377\215\0\377\377\222\0\377\377\220\0\377\377\214" - "\0\377\377\210\0\377\377]\0\377\377I\35\337\374\255\235a\252\252\252\3\314" - "\314\314\5\342\342\342\11\354\354\354\16\362\362\362\25\356\356\356\37\346" - "\346\346*\337\337\3378\327\327\327G\320\320\320W\312\312\312f\303\303\303" - "s\300\300\300{\277\277\277}\302\302\302v\360S2\330\377w\0\377\377\224\0\377" - "\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377" - "\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224" - "\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377" - "\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377" - "\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\225\0\377\377\224" - "\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377\224\0\377\377\224\0\377\377\225\0\377\377\224\0\377\377\224\0\377" - "\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377" - "\224\0\377\377\224\0\377\377\221\0\377\377\211\0\377\377~\0\377\377v\0\377" - "\377r\0\377\377[\0\377\374kM\262\342\342\342\11\345\345\345\12\347\347\347" - "\13\347\347\347\13\347\347\347\13\342\342\342\11\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\223}\200\377@\0\377" - "\377z\0\377\377\223\0\377\377\220\0\377\377\215\0\377\377\211\0\377\377y" - "\0\377\377A\0\377\377\207n\217\361\344\344\23\314\314\314\5\337\337\337\10" - "\354\354\354\16\362\362\362\25\356\356\356\37\347\347\347+\340\340\340:\331" - "\331\331J\317\317\317\\\307\307\307n\276\276\276\177\266\266\266\215\261" - "\261\261\230\257\257\257\235\260\260\260\231\267\267\267\214\357Q0\334\377" - "x\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377\223\0\377\377\224\0\377\377\223\0\377\377\224\0\377\377\224\0\377" - "\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377" - "\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224" - "\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377" - "\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377" - "\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224" - "\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377\224\0\377\377\223\0\377\377\223\0\377\377\220\0\377\377\207\0\377" - "\377}\0\377\377u\0\377\377r\0\377\377F\0\377\365\246\226n\350\350\350\27" - "\352\352\352\31\353\353\353\32\354\354\354\33\352\352\352\31\363\363\363" - "\26\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\324\3110\377" - "S.\317\377`\0\377\377\223\0\377\377\221\0\377\377\216\0\377\377\211\0\377" - "\377\204\0\377\377e\0\377\377I\35\337\373\310\274A\277\277\277\4\337\337" - "\337\10\351\351\351\14\362\362\362\24\355\355\355\35\346\346\346*\337\337" - "\3379\326\326\326K\316\316\316^\304\304\304q\274\274\274\203\264\264\264" - "\224\254\254\254\241\251\251\251\252\247\247\247\256\247\247\247\254\254" - "\254\254\241\267\267\267\216\357Q0\334\377y\0\377\377\224\0\377\377\224\0" - "\377\377\223\0\377\377\222\0\377\377\221\0\377\377\220\0\377\377\220\0\377" - "\377\220\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377" - "\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221" - "\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0" - "\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377" - "\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377" - "\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221" - "\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0" - "\377\377\221\0\377\377\221\0\377\377\221\0\377\377\221\0\377\377\220\0\377" - "\377\217\0\377\377\212\0\377\377\202\0\377\377z\0\377\377t\0\377\377q\0\377" - "\3770\0\377\345\330\330<\344\344\3441\341\341\3414\342\342\3426\336\336\336" - "7\341\341\3414\347\347\347,\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\377\223}\200\377@\0\377\377\200\0\377\377\223\0\377\377\220\0\377\377" - "\214\0\377\377\206\0\377\377\201\0\377\377T\0\377\377lO\260\361\344\344\23" - "\324\324\324\6\347\347\347\13\360\360\360\22\354\354\354\33\345\345\345(" - "\336\336\3367\330\330\330I\315\315\315]\304\304\304q\273\273\273\204\262" - "\262\262\226\254\254\254\244\246\246\246\257\244\244\244\264\244\244\244" - "\264\246\246\246\257\254\254\254\244\264\264\264\223\277\277\277|\361T3\327" - "\377y\0\377\377\224\0\377\377\224\0\377\377\223\0\377\377\220\0\377\377\214" - "\0\377\377\211\0\377\377\210\0\377\377\210\0\377\377\211\0\377\377\211\0" - "\377\377\211\0\377\377\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377" - "\377\212\0\377\377\212\0\377\377\212\0\377\377\211\0\377\377\212\0\377\377" - "\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377\377\211" - "\0\377\377\212\0\377\377\211\0\377\377\212\0\377\377\212\0\377\377\212\0" - "\377\377\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377" - "\377\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377\377\212\0\377\377" - "\212\0\377\377\212\0\377\377\211\0\377\377\212\0\377\377\211\0\377\377\211" - "\0\377\377\211\0\377\377\210\0\377\377\206\0\377\377\201\0\377\377{\0\377" - "\377v\0\377\377r\0\377\377V\0\377\356jN\277\322\322\322V\321\321\321Y\317" - "\317\317\\\316\316\316_\316\316\316^\320\320\320X\326\326\326K\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\337\327\40\377`>\277\377`\0\377\377\224\0\377" - "\377\222\0\377\377\217\0\377\377\212\0\377\377\203\0\377\377x\0\377\377I" - "\0\377\375\222|\201\314\314\314\5\342\342\342\11\356\356\356\17\351\351\351" - "\30\351\351\351$\341\341\3413\332\332\332E\321\321\321Z\305\305\305o\273" - "\273\273\204\262\262\262\226\253\253\253\245\246\246\246\260\243\243\243" - "\265\243\243\243\266\245\245\245\261\251\251\251\247\260\260\260\231\271" - "\271\271\210\303\303\303t\315\315\315]\365W6\321\377y\0\377\377\224\0\377" - "\377\224\0\377\377\222\0\377\377\215\0\377\377\206\0\377\377\201\0\377\377" - "~\0\377\377~\0\377\377~\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377" - "\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177" - "\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0" - "\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377" - "\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377" - "\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177" - "\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0" - "\377\377\177\0\377\377\177\0\377\377\177\0\377\377\177\0\377\377~\0\377\377" - "|\0\377\377y\0\377\377u\0\377\377r\0\377\377p\0\377\377=\0\377\315\230\214" - "\241\273\273\273\204\273\273\273\207\267\267\267\213\266\266\266\215\270" - "\270\270\212\275\275\275\200\310\310\310l\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\274" - "\254P\377D\15\357\377z\0\377\377\224\0\377\377\222\0\377\377\216\0\377\377" - "\211\0\377\377\202\0\377\377v\0\377\377D\14\357\374\253\234b\332\332\332" - "\7\351\351\351\14\362\362\362\25\347\347\347\40\343\343\343.\333\333\333" - "@\322\322\322U\310\310\310k\275\275\275\201\263\263\263\225\253\253\253\245" - "\245\245\245\261\243\243\243\266\243\243\243\266\245\245\245\261\251\251" - "\251\247\260\260\260\231\271\271\271\210\302\302\302v\313\313\313c\325\325" - "\325P\335\335\335=\370Z8\312\377y\0\377\377\224\0\377\377\224\0\377\377\222" - "\0\377\377\213\0\377\377\202\0\377\377{\0\377\377v\0\377\377u\0\377\377v" - "\0\377\377v\0\377\377v\0\377\377v\0\377\377v\0\377\377w\0\377\377w\0\377" - "\377v\0\377\377v\0\377\377v\0\377\377w\0\377\377v\0\377\377w\0\377\377v\0" - "\377\377w\0\377\377v\0\377\377w\0\377\377v\0\377\377v\0\377\377v\0\377\377" - "v\0\377\377w\0\377\377v\0\377\377w\0\377\377w\0\377\377w\0\377\377v\0\377" - "\377v\0\377\377v\0\377\377v\0\377\377v\0\377\377v\0\377\377w\0\377\377w\0" - "\377\377w\0\377\377v\0\377\377v\0\377\377w\0\377\377v\0\377\377v\0\377\377" - "u\0\377\377u\0\377\377s\0\377\377r\0\377\377p\0\377\377g\0\377\363;\24\365" - "\246\246\246\257\245\245\245\261\244\244\244\264\241\241\241\267\241\241" - "\241\267\244\244\244\262\254\254\254\243\270\270\270\211\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316" - "\316\377\316\316\316\377\316\316\316\377\316\316\316\377\316\316\316\377" - "\316\316\316\377\316\316\316\377\316\316\316\377\316\316\316\377\316\316" - "\316\377\316\316\316\377\316\316\316\377\316\316\316\377\316\316\316\377" - "\316\316\316\377\316\316\316\377\316\316\316\377\316\316\316\377\316\316" - "\316\377\352s[\377\377M\0\377\377\215\0\377\377\224\0\377\377\222\0\377\377" - "\216\0\377\377\207\0\377\377\200\0\377\377u\0\377\375B\12\377\325\256\246" - "\377\312\312\312\377\307\307\307\377\304\304\304\377\276\276\276\377\267" - "\267\267\377\256\256\256\377\246\246\246\377\234\234\234\377\224\224\224" - "\377\214\214\214\377\206\206\206\377\203\203\203\377\203\203\203\377\206" - "\206\206\377\212\212\212\377\220\220\220\377\227\227\227\377\240\240\240" - "\377\246\246\246\377\256\256\256\377\265\265\265\377\273\273\273\377\300" - "\300\300\377\342xa\377\377`\0\377\377\224\0\377\377\224\0\377\377\221\0\377" - "\377\212\0\377\377\200\0\377\377x\0\377\377s\0\377\377r\0\377\377q\0\377" - "\377r\0\377\377r\0\377\377r\0\377\377q\0\377\377r\0\377\377r\0\377\377r\0" - "\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377" - "r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377" - "\377r\0\377\377r\0\377\377r\0\377\377q\0\377\377r\0\377\377r\0\377\377r\0" - "\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377q\0\377\377" - "r\0\377\377r\0\377\377r\0\377\377r\0\377\377r\0\377\377q\0\377\377q\0\377" - "\377q\0\377\377p\0\377\377p\0\377\377p\0\377\377N\0\377\311_I\351\223\223" - "\223\324\223\223\223\325\221\221\221\327\222\222\222\330\223\223\223\326" - "\227\227\227\315\241\241\241\272\261\261\261\232\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\247\232\227\377\347I(\377\377g\0" - "\377\377\224\0\377\377\224\0\377\377\222\0\377\377\215\0\377\377\207\0\377" - "\377\177\0\377\377k\0\377\372;\11\377\260\211\200\377\235\235\235\377\232" - "\232\232\377\226\226\226\377\221\221\221\377\213\213\213\377\204\204\204" - "\377|||\377uuu\377nnn\377iii\377fff\377eee\377fff\377jjj\377ooo\377uuu\377" - "|||\377\202\202\202\377\210\210\210\377\216\216\216\377\222\222\222\377\226" - "\226\226\377\231\231\231\377\234\234\234\377\317eO\377\377`\0\377\377\224" - "\0\377\377\224\0\377\377\221\0\377\377\212\0\377\377\200\0\377\377w\0\377" - "\377r\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0" - "\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377" - "p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377" - "\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0" - "\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377" - "p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377" - "\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0" - "\377\3770\0\377\217\202\177\354\210\210\210\353\210\210\210\354\207\207\207" - "\355\210\210\210\354\211\211\211\347\221\221\221\332\235\235\235\302\257" - "\257\257\236\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\263\213\203" - "\377\364A\23\377\377z\0\377\377\224\0\377\377\224\0\377\377\222\0\377\377" - "\215\0\377\377\206\0\377\377~\0\377\377j\0\377\356E\34\377\252\220\212\377" - "\234\234\234\377\230\230\230\377\224\224\224\377\216\216\216\377\207\207" - "\207\377\200\200\200\377www\377ppp\377jjj\377fff\377ddd\377ddd\377hhh\377" - "lll\377rrr\377zzz\377\201\201\201\377\210\210\210\377\215\215\215\377\222" - "\222\222\377\227\227\227\377\231\231\231\377\234\234\234\377\236\236\236" - "\377\236\236\236\377\312mZ\377\377Y\0\377\377\224\0\377\377\224\0\377\377" - "\221\0\377\377\211\0\377\377\177\0\377\377w\0\377\377r\0\377\377p\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377p\0\377\377" - "p\0\377\377o\0\377\377o\0\377\377o\0\377\377V\0\377\317K0\374\202\202\202" - "\367\202\202\202\367\202\202\202\367\202\202\202\367\204\204\204\364\207" - "\207\207\355\220\220\220\334\236\236\236\300\261\261\261\230\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316" - "\316\316\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\276|n\377\372E\10\377\377\207\0\377\377\224\0\377\377" - "\223\0\377\377\221\0\377\377\214\0\377\377\205\0\377\377~\0\377\377n\0\377" - "\364>\23\377\243\226\223\377\233\233\233\377\227\227\227\377\221\221\221" - "\377\213\213\213\377\203\203\203\377{{{\377sss\377lll\377fff\377ccc\377b" - "bb\377ddd\377hhh\377nnn\377vvv\377~~~\377\206\206\206\377\214\214\214\377" - "\222\222\222\377\226\226\226\377\231\231\231\377\234\234\234\377\236\236" - "\236\377\237\237\237\377\240\240\240\377\240\240\240\377\270\203x\377\377" - "F\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\211\0\377\377\177\0" - "\377\377v\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377p\0\377\377q\0\377\377r\0\377\377s\0" - "\377\377s\0\377\377r\0\377\377q\0\377\377p\0\377\377p\0\377\377o\0\377\377" - "o\0\377\377=\0\377\237j_\376~~~\375~~~\375\200\200\200\374\200\200\200\373" - "\203\203\203\366\210\210\210\353\221\221\221\327\243\243\243\266\267\267" - "\267\214\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\304ud\377\377M\0\377\377\215\0\377\377\223\0\377" - "\377\221\0\377\377\216\0\377\377\211\0\377\377\203\0\377\377|\0\377\377r" - "\0\377\372?\10\377\257\210\177\377\231\231\231\377\224\224\224\377\217\217" - "\217\377\210\210\210\377\200\200\200\377www\377ooo\377hhh\377ccc\377aaa\377" - "aaa\377ddd\377iii\377qqq\377yyy\377\201\201\201\377\211\211\211\377\220\220" - "\220\377\225\225\225\377\231\231\231\377\234\234\234\377\236\236\236\377" - "\237\237\237\377\240\240\240\377\240\240\240\377\240\240\240\377\240\240" - "\240\377\255\222\215\377\3779\0\377\377\224\0\377\377\224\0\377\377\221\0" - "\377\377\211\0\377\377~\0\377\377v\0\377\377q\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377g\0\377\3577\20\377\177\177\177\377\177\177\177" - "\377\177\177\177\376~~~\375\200\200\200\373\204\204\204\364\213\213\213\346" - "\227\227\227\315\252\252\252\250\277\277\277}\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\320fP\377\377S\0\377\377\224" - "\0\377\377\222\0\377\377\217\0\377\377\212\0\377\377\205\0\377\377\177\0" - "\377\377z\0\377\377p\0\377\372?\10\377\256\206~\377\230\230\230\377\222\222" - "\222\377\214\214\214\377\205\205\205\377|||\377sss\377kkk\377eee\377aaa\377" - "___\377aaa\377ddd\377kkk\377sss\377|||\377\205\205\205\377\214\214\214\377" - "\222\222\222\377\230\230\230\377\233\233\233\377\235\235\235\377\237\237" - "\237\377\240\240\240\377\240\240\240\377\240\240\240\377\240\240\240\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\365/\6\377\377\215\0\377" - "\377\223\0\377\377\217\0\377\377\207\0\377\377}\0\377\377u\0\377\377q\0\377" - "\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377I\0\377\267ZG\377\177\177" - "\177\377\177\177\177\377\177\177\177\377~~~\375\201\201\201\371\206\206\206" - "\360\217\217\217\336\236\236\236\300\261\261\261\230\310\310\310l\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\316\316\316\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\334X=\377\377`\0\377\377" - "\224\0\377\377\222\0\377\377\216\0\377\377\210\0\377\377\202\0\377\377|\0" - "\377\377w\0\377\377t\0\377\3779\0\377\256\206~\377\226\226\226\377\221\221" - "\221\377\212\212\212\377\201\201\201\377yyy\377ppp\377hhh\377bbb\377___\377" - "^^^\377```\377eee\377lll\377uuu\377~~~\377\207\207\207\377\217\217\217\377" - "\225\225\225\377\231\231\231\377\235\235\235\377\236\236\236\377\240\240" - "\240\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\206\206\206\377\3107\31" - "\377\377s\0\377\377\223\0\377\377|\0\377\377n\0\377\377T\0\377\377P\0\377" - "\377F\0\377\377=\0\377\377=\0\377\377=\0\377\3779\0\377\377,\0\377\377,\0" - "\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377" - ",\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377" - "\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0" - "\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377,\0\377\377" - ",\0\377\377,\0\377\377,\0\377\3770\0\377\377A\0\377\377k\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377k\0\377\3674\7\377\205xu" - "\377\177\177\177\377\177\177\177\377\177\177\177\376\200\200\200\374\203" - "\203\203\366\211\211\211\352\224\224\224\323\245\245\245\261\273\273\273" - "\207\317\317\317[\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\334X=\377\377m\0" - "\377\377\224\0\377\377\222\0\377\377\216\0\377\377\207\0\377\377\200\0\377" - "\377z\0\377\377v\0\377\377s\0\377\377F\0\377\300q`\377\225\225\225\377\217" - "\217\217\377\207\207\207\377~~~\377uuu\377mmm\377eee\377```\377]]]\377]]" - "]\377```\377eee\377mmm\377www\377\200\200\200\377\211\211\211\377\221\221" - "\221\377\226\226\226\377\233\233\233\377\235\235\235\377\237\237\237\377" - "\240\240\240\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\223\223\223\377" - "PPP\377\222B2\377\377?\0\377\377,\0\377\3352\16\377\3246\25\377\331oY\377" - "\325kU\377\276n^\377\244od\377\233f[\377\230cX\377\215e]\377rrr\377rrr\377" - "rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rr" - "r\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377" - "rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377{nk\377\236\\N\377" - "\371D\5\377\377k\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377V\0" - "\377\312F+\377}}}\377\177\177\177\377\177\177\177\377\177\177\177\376\201" - "\201\201\372\205\205\205\362\215\215\215\342\231\231\231\307\254\254\254" - "\241\301\301\301u\326\326\326K\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\334X=\377\377m\0\377" - "\377\224\0\377\377\222\0\377\377\216\0\377\377\207\0\377\377\177\0\377\377" - "y\0\377\377t\0\377\377q\0\377\377R\0\377\322\\C\377\224\224\224\377\215\215" - "\215\377\205\205\205\377|||\377rrr\377jjj\377ccc\377^^^\377\\\\\\\377\\\\" - "\\\377___\377fff\377nnn\377www\377\201\201\201\377\212\212\212\377\222\222" - "\222\377\230\230\230\377\233\233\233\377\236\236\236\377\237\237\237\377" - "\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "kkk\377PPP\377[NK\377qIA\377OOO\377MMM\377\240\240\240\377\301\301\301\377" - "\255\255\255\377\230\230\230\377\207\207\207\377|||\377vvv\377sss\377rrr" - "\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377" - "rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rr" - "r\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377rrr\377" - "rrr\377\334>\35\377\377^\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\3774\0\377\204id\377}}}\377\177\177\177\377\177\177\177\376~~~\375\202\202" - "\202\370\207\207\207\355\221\221\221\331\241\241\241\271\265\265\265\217" - "\313\313\313c\335\335\335<\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\326_G\377\377f\0\377\377\224\0\377\377\223" - "\0\377\377\217\0\377\377\210\0\377\377\200\0\377\377y\0\377\377t\0\377\377" - "q\0\377\377_\0\377\345G&\377\223\223\223\377\214\214\214\377\203\203\203" - "\377yyy\377ppp\377hhh\377aaa\377\\\\\\\377ZZZ\377[[[\377___\377eee\377nn" - "n\377xxx\377\202\202\202\377\214\214\214\377\223\223\223\377\230\230\230" - "\377\234\234\234\377\236\236\236\377\240\240\240\377\240\240\240\377\240" - "\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\223\223\223\377PPP\377" - "PPP\377PPP\377PPP\377OOO\377ggg\377\323\323\323\377\303\303\303\377\257\257" - "\257\377\234\234\234\377\212\212\212\377~~~\377xxx\377ttt\377ttt\377sss\377" - "ttt\377ttt\377ttt\377ttt\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uu" - "u\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377" - "uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377uuu\377\377" - ",\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377^\0\377\334>\35\377" - "sss\377~~~\377\177\177\177\376\177\177\177\376\200\200\200\373\204\204\204" - "\364\213\213\213\346\227\227\227\315\250\250\250\251\277\277\277}\323\323" - "\323R\343\343\343/\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\304ud\377\377S\0\377\377\224\0\377\377\223\0\377\377\220\0\377\377" - "\211\0\377\377\201\0\377\377y\0\377\377t\0\377\377q\0\377\377l\0\377\371" - "7\11\377\231\214\211\377\212\212\212\377\201\201\201\377www\377nnn\377ff" - "f\377___\377[[[\377YYY\377ZZZ\377^^^\377eee\377nnn\377yyy\377\203\203\203" - "\377\214\214\214\377\224\224\224\377\231\231\231\377\235\235\235\377\236" - "\236\236\377\240\240\240\377\240\240\240\377\240\240\240\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377kkk\377PPP\377PPP\377PPP\377" - "PPP\377OOO\377\266\266\266\377\325\325\325\377\306\306\306\377\263\263\263" - "\377\237\237\237\377\215\215\215\377\202\202\202\377zzz\377xxx\377www\377" - "xxx\377xxx\377yyy\377yyy\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zz" - "z\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377" - "zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377zzz\377\223" - "kc\377\3779\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377E\0\377" - "\252[J\377uuu\377\177\177\177\377\200\200\200\374\200\200\200\374\201\201" - "\201\371\206\206\206\360\217\217\217\335\236\236\236\277\261\261\261\230" - "\310\310\310k\334\334\334C\351\351\351$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\304ud\377\377S\0\377\377\224\0\377\377\223\0\377\377\221\0\377" - "\377\212\0\377\377\203\0\377\377z\0\377\377u\0\377\377r\0\377\377p\0\377" - "\377=\0\377\255xm\377\211\211\211\377\200\200\200\377vvv\377lll\377ddd\377" - "]]]\377ZZZ\377XXX\377YYY\377]]]\377ddd\377mmm\377xxx\377\203\203\203\377" - "\214\214\214\377\224\224\224\377\231\231\231\377\235\235\235\377\237\237" - "\237\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\223\223\223\377PPP\377PPP\377PP" - "P\377PPP\377PPP\377\205\205\205\377\337\337\337\377\327\327\327\377\312\312" - "\312\377\270\270\270\377\245\245\245\377\224\224\224\377\210\210\210\377" - "\202\202\202\377\177\177\177\377\177\177\177\377\177\177\177\377\200\200" - "\200\377\201\201\201\377\202\202\202\377\203\203\203\377\203\203\203\377" - "\204\204\204\377\205\205\205\377\205\205\205\377\205\205\205\377\205\205" - "\205\377\205\205\205\377\205\205\205\377\205\205\205\377\205\205\205\377" - "\205\205\205\377\205\205\205\377\205\205\205\377\205\205\205\377\205\205" - "\205\377\205\205\205\377\205\205\205\377\205\205\205\377\205\205\205\377" - "\205\205\205\377\205\205\205\377\205\205\205\377\205\205\205\377\205\205" - "\205\377\205\205\205\377\205\205\205\377\273^K\377\377I\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377g\0\377\3577\20\377}}}\377zzz\377\202\202\202\377" - "\201\201\201\371\201\201\201\372\203\203\203\365\211\211\211\351\225\225" - "\225\322\246\246\246\260\273\273\273\205\321\321\321Z\342\342\3425\354\354" - "\354\33\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\316\316\316\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\263\213\203\377\372E\10\377\377\215" - "\0\377\377\224\0\377\377\221\0\377\377\214\0\377\377\204\0\377\377|\0\377" - "\377u\0\377\377r\0\377\377p\0\377\377N\0\377\310^H\377\210\210\210\377~~" - "~\377ttt\377kkk\377bbb\377\\\\\\\377XXX\377WWW\377XXX\377\\\\\\\377ccc\377" - "mmm\377www\377\202\202\202\377\214\214\214\377\224\224\224\377\231\231\231" - "\377\235\235\235\377\237\237\237\377\240\240\240\377\240\240\240\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377kkk\377PPP\377PPP\377PPP\377PPP\377PPP\377\273\273\273\377\340" - "\340\340\377\331\331\331\377\316\316\316\377\276\276\276\377\255\255\255" - "\377\236\236\236\377\223\223\223\377\215\215\215\377\213\213\213\377\213" - "\213\213\377\215\215\215\377\216\216\216\377\220\220\220\377\221\221\221" - "\377\223\223\223\377\224\224\224\377\224\224\224\377\225\225\225\377\226" - "\226\226\377\226\226\226\377\226\226\226\377\226\226\226\377\226\226\226" - "\377\226\226\226\377\226\226\226\377\226\226\226\377\226\226\226\377\226" - "\226\226\377\226\226\226\377\226\226\226\377\226\226\226\377\226\226\226" - "\377\226\226\226\377\226\226\226\377\226\226\226\377\226\226\226\377\226" - "\226\226\377\226\226\226\377\226\226\226\377\226\226\226\377\226\226\226" - "\377\353@\34\377\377b\0\377\377o\0\377\377o\0\377\377o\0\377\377N\0\377\306" - "\\F\377\206\206\206\377\200\200\200\377\207\207\207\377\204\204\204\364\203" - "\203\203\366\206\206\206\360\215\215\215\341\233\233\233\305\256\256\256" - "\237\303\303\303s\331\331\331J\346\346\346)\361\361\361\23\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316" - "\316\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\247\232\227\377\3719\11\377\377\215\0\377\377\224\0\377\377\222\0\377\377" - "\215\0\377\377\206\0\377\377}\0\377\377w\0\377\377r\0\377\377p\0\377\377" - "b\0\377\352?\33\377\207\207\207\377~~~\377ttt\377iii\377aaa\377\\\\\\\377" - "XXX\377VVV\377:::\377<<<\377AAA\377GGG\377NNN\377VVV\377\214\214\214\377" - "\224\224\224\377\231\231\231\377\235\235\235\377\237\237\237\377\240\240" - "\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\223\223\223\377PPP\377PPP\377PP" - "P\377PPP\377PPP\377\205\205\205\377\343\343\343\377\340\340\340\377\334\334" - "\334\377\323\323\323\377\306\306\306\377\271\271\271\377\254\254\254\377" - "\243\243\243\377\236\236\236\377\235\235\235\377\237\237\237\377\240\240" - "\240\377\242\242\242\377\244\244\244\377\245\245\245\377\246\246\246\377" - ";;;\377;;;\377<<<\377<<<\377<<<\377<<<\377\253\253\253\377\253\253\253\377" - "\253\253\253\377\253\253\253\377\253\253\253\377\253\253\253\377\253\253" - "\253\377\253\253\253\377\253\253\253\377\253\253\253\377\253\253\253\377" - "\253\253\253\377\253\253\253\377\253\253\253\377\253\253\253\377\253\253" - "\253\377\253\253\253\377\253\253\253\377\253\253\253\377\273\223\213\377" - "\3779\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\3774\0\377\250\216" - "\210\377\223\223\223\377\210\210\210\377\214\214\214\377\207\207\207\356" - "\205\205\205\361\211\211\211\352\223\223\223\326\243\243\243\266\266\266" - "\266\215\315\315\315a\340\340\340;\356\356\356\36\354\354\354\16\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\316\316\316\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\347I(\377\377z\0\377\377\224\0\377\377\222\0\377\377\216\0\377\377" - "\210\0\377\377\177\0\377\377x\0\377\377s\0\377\377p\0\377\377o\0\377\377" - "9\0\377\236vn\377}}}\377rrr\377iii\377aaa\377[[[\377WWW\377UUU\377VVV\377" - "<<<\377@@@\377FFF\377NNN\377UUU\377\\\\\\\377\223\223\223\377\231\231\231" - "\377\235\235\235\377\237\237\237\377\240\240\240\377\240\240\240\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\206\206\206\377PPP\377PPP\377PPP\377PPP\377" - "PPP\377\274\274\274\377\343\343\343\377\341\341\341\377\337\337\337\377\330" - "\330\330\377\317\317\317\377\305\305\305\377\274\274\274\377\266\266\266" - "\377\263\263\263\377\263\263\263\377\264\264\264\377\266\266\266\377\267" - "\267\267\377\271\271\271\377\272\272\272\377\273\273\273\377BBB\377CCC\377" - "CCC\377CCC\377CCC\377CCC\377\277\277\277\377\277\277\277\377\277\277\277" - "\377\277\277\277\377\277\277\277\377\277\277\277\377\277\277\277\377\277" - "\277\277\377\277\277\277\377\277\277\277\377\277\277\277\377\277\277\277" - "\377\277\277\277\377\277\277\277\377\277\277\277\377\277\277\277\377\277" - "\277\277\377\277\277\277\377\277\277\277\377\343mT\377\377R\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377V\0\377\343`D\377\254\254\254\377\236\236\236" - "\377\220\220\220\377\220\220\220\377\211\211\211\347\210\210\210\353\215" - "\215\215\342\230\230\230\312\252\252\252\246\300\300\300z\325\325\325P\342" - "\342\342-\363\363\363\26\342\342\342\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\326_G\377\377f\0\377\377\224\0\377\377" - "\223\0\377\377\220\0\377\377\211\0\377\377\201\0\377\377y\0\377\377t\0\377" - "\377q\0\377\377p\0\377\377N\0\377\304ZD\377}}}\377rrr\377hhh\377```\377Z" - "ZZ\377VVV\377UUU\377VVV\377YYY\377???\377EEE\377LLL\377TTT\377[[[\377aaa" - "\377\231\231\231\377\235\235\235\377\237\237\237\377\240\240\240\377\240" - "\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\223\223\223\377]]]\377PPP\377" - "PPP\377PPP\377PPP\377kkk\377\344\344\344\377\343\343\343\377\342\342\342" - "\377\340\340\340\377\335\335\335\377\327\327\327\377\320\320\320\377\313" - "\313\313\377\306\306\306\377\306\306\306\377\306\306\306\377\307\307\307" - "\377\311\311\311\377\312\312\312\377\314\314\314\377\315\315\315\377\315" - "\315\315\377HHH\377HHH\377III\377III\377III\377III\377\320\320\320\377\320" - "\320\320\377\320\320\320\377\320\320\320\377\320\320\320\377\320\320\320" - "\377\320\320\320\377\320\320\320\377\320\320\320\377\320\320\320\377\320" - "\320\320\377\320\320\320\377\320\320\320\377\320\320\320\377\320\320\320" - "\377\320\320\320\377\320\320\320\377\320\320\320\377\320\320\320\377\371" - "A\32\377\377g\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377\322\235\222" - "\377\266\266\266\377\247\247\247\377\226\226\226\377\224\224\224\377\215" - "\215\215\342\213\213\213\345\222\222\222\330\240\240\240\273\264\264\264" - "\224\311\311\311h\333\333\333@\350\350\350\"\357\357\357\20\324\324\324\6" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\316\316\316\377\241\241\241\377\241\241\241\377\271\204y\377\377" - "F\0\377\377\224\0\377\377\223\0\377\377\221\0\377\377\213\0\377\377\203\0" - "\377\377{\0\377\377u\0\377\377r\0\377\377p\0\377\377g\0\377\3608\21\377~" - "~~\377sss\377hhh\377```\377ZZZ\377VVV\377TTT\377UUU\377XXX\377]]]\377DDD" - "\377KKK\377SSS\377ZZZ\377aaa\377eee\377\234\234\234\377\236\236\236\377\240" - "\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\206\206\206\377PPP\377PPP\377PPP\377PPP\377PPP\377\256\256\256\377\344" - "\344\344\377\344\344\344\377\343\343\343\377\342\342\342\377\340\340\340" - "\377\335\335\335\377\331\331\331\377\327\327\327\377\325\325\325\377\324" - "\324\324\377\325\325\325\377\326\326\326\377\327\327\327\377\327\327\327" - "\377\330\330\330\377\330\330\330\377\331\331\331\377LLL\377MMM\377MMM\377" - "MMM\377MMM\377MMM\377\333\333\333\377\333\333\333\377\333\333\333\377\333" - "\333\333\377\333\333\333\377\333\333\333\377\333\333\333\377\333\333\333" - "\377\333\333\333\377\333\333\333\377\333\333\333\377\333\333\333\377\333" - "\333\333\377\333\333\333\377\333\333\333\377\333\333\333\377\333\333\333" - "\377\333\333\333\377\344\257\244\377\377=\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377g\0\377\371A\32\377\313\313\313\377\275\275\275\377\253\253\253" - "\377\230\230\230\377\227\227\227\377\217\217\217\336\217\217\217\336\230" - "\230\230\314\250\250\250\253\275\275\275\201\322\322\322V\345\345\3452\352" - "\352\352\31\347\347\347\13\277\277\277\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\241\241" - "\241\377\247\232\227\377\3719\11\377\377\215\0\377\377\224\0\377\377\221" - "\0\377\377\215\0\377\377\205\0\377\377}\0\377\377v\0\377\377r\0\377\377p" - "\0\377\377o\0\377\377=\0\377\237j_\377ttt\377iii\377```\377ZZZ\377VVV\377" - "TTT\377TTT\377VVV\377\\\\\\\377ddd\377III\377QQQ\377YYY\377___\377ddd\377" - "ggg\377\236\236\236\377\240\240\240\377\240\240\240\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377]]]\377PPP\377PPP\377PPP\377" - "PPP\377kkk\377\344\344\344\377\344\344\344\377\344\344\344\377\343\343\343" - "\377\343\343\343\377\342\342\342\377\340\340\340\377\340\340\340\377\336" - "\336\336\377\335\335\335\377\335\335\335\377\335\335\335\377\336\336\336" - "\377\336\336\336\377\337\337\337\377\337\337\337\377\340\340\340\377\340" - "\340\340\377NNN\377NNN\377OOO\377OOO\377OOO\377OOO\377\340\340\340\377\340" - "\340\340\377\340\340\340\377\340\340\340\377\340\340\340\377\340\340\340" - "\377\340\340\340\377\340\340\340\377\340\340\340\377\340\340\340\377\340" - "\340\340\377\340\340\340\377\340\340\340\377\340\340\340\377\340\340\340" - "\377\340\340\340\377\340\340\340\377\340\340\340\377\363pT\377\377V\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377I\0\377\351\214y\377\315\315\315\377" - "\275\275\275\377\252\252\252\377\227\227\227\377\227\227\227\377\220\220" - "\220\333\223\223\223\326\236\236\236\277\261\261\261\232\305\305\305o\332" - "\332\332F\352\352\352&\360\360\360\22\332\332\332\7\177\177\177\2\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\316\316\316\377\241\241\241\377\342Q3\377\377s\0\377\377\224\0\377\377\223" - "\0\377\377\217\0\377\377\210\0\377\377\177\0\377\377x\0\377\377s\0\377\377" - "p\0\377\377o\0\377\377^\0\377\337A\40\377uuu\377jjj\377aaa\377ZZZ\377VVV" - "\377SSS\377SSS\377UUU\377ZZZ\377aaa\377kkk\377OOO\377WWW\377^^^\377ccc\377" - "ggg\377iii\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\223\223\223\377PPP\377PPP\377PPP\377" - "PPP\377PPP\377\256\256\256\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\343\343\343\377\343\343\343\377\342\342\342\377\342" - "\342\342\377\341\341\341\377\341\341\341\377\341\341\341\377\341\341\341" - "\377\341\341\341\377\342\342\342\377\342\342\342\377\342\342\342\377\342" - "\342\342\377\342\342\342\377OOO\377OOO\377OOO\377OOO\377OOO\377OOO\377\343" - "\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343" - "\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343" - "\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343" - "\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\375" - "7\16\377\377k\0\377\377o\0\377\377o\0\377\377k\0\377\375;\15\377\332\314" - "\312\377\313\313\313\377\272\272\272\377\246\246\246\377\224\224\224\377" - "\224\224\224\377\222\222\222\330\227\227\227\315\245\245\245\261\271\271" - "\271\210\315\315\315]\336\336\3367\354\354\354\34\351\351\351\14\314\314" - "\314\5\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\316\316\316\377\276|n\377\377M\0\377\377\224\0\377" - "\377\223\0\377\377\221\0\377\377\212\0\377\377\202\0\377\377z\0\377\377t" - "\0\377\377q\0\377\377p\0\377\377o\0\377\3774\0\377\207mg\377kkk\377bbb\377" - "ZZZ\377VVV\377SSS\377SSS\377TTT\377XXX\377___\377hhh\377ttt\377UUU\377\\" - "\\\\\377bbb\377fff\377hhh\377jjj\377\240\240\240\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377kkk\377PPP\377" - "PPP\377PPP\377PPP\377]]]\377\326\326\326\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\343" - "\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343" - "\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343" - "\343\343\377\343\343\343\377\343\343\343\377PPP\377PPP\377PPP\377PPP\377" - "PPP\377PPP\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343" - "\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343" - "\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343" - "\377\343\343\343\377\343\343\343\377\343\343\343\377\343\343\343\377\354" - "\252\234\377\377A\0\377\377o\0\377\377o\0\377\377o\0\377\377V\0\377\362o" - "S\377\324\324\324\377\306\306\306\377\265\265\265\377\241\241\241\377\220" - "\220\220\377\223\223\223\377\223\223\223\324\235\235\235\302\255\255\255" - "\240\302\302\302v\326\326\326L\347\347\347+\362\362\362\25\337\337\337\10" - "\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\321\304\302\377\364A\23\377\377\207\0\377" - "\377\224\0\377\377\222\0\377\377\216\0\377\377\205\0\377\377}\0\377\377v" - "\0\377\377r\0\377\377p\0\377\377o\0\377\377V\0\377\314I-\377mmm\377ccc\377" - "\\\\\\\377VVV\377SSS\377SSS\377SSS\377VVV\377\\\\\\\377eee\377ppp\377|||" - "\377ZZZ\377aaa\377fff\377hhh\377jjj\377kkk\377\240\240\240\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\223\223\223\377PPP\377" - "PPP\377PPP\377PPP\377PPP\377\223\223\223\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377PPP\377PPP\377" - "PPP\377PPP\377PPP\377PPP\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\367fH\377\377Z\0\377\377o\0\377\377o\0\377\377o\0\377\3779\0" - "\377\341\271\261\377\320\320\320\377\301\301\301\377\255\255\255\377\233" - "\233\233\377\214\214\214\377\223\223\223\377\227\227\227\316\243\243\243" - "\265\265\265\265\217\314\314\314d\335\335\335=\347\347\347\40\354\354\354" - "\16\314\314\314\5\177\177\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\347}g\377\377`\0\377\377\224" - "\0\377\377\223\0\377\377\220\0\377\377\211\0\377\377\200\0\377\377w\0\377" - "\377s\0\377\377p\0\377\377o\0\377\377k\0\377\3705\7\377wjg\377ddd\377\\\\" - "\\\377VVV\377SSS\377RRR\377SSS\377UUU\377ZZZ\377aaa\377lll\377yyy\377\205" - "\205\205\377___\377ddd\377hhh\377iii\377jjj\377kkk\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\206\206\206" - "\377PPP\377PPP\377PPP\377PPP\377PPP\377\311\311\311\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377PPP\377" - "PPP\377PPP\377PPP\377PPP\377PPP\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\346\330\326\377\3770\0\377\377o\0\377\377o\0\377\377o\0\377\377b\0\377\371" - "N*\377\327\327\327\377\314\314\314\377\272\272\272\377\247\247\247\377\225" - "\225\225\377\211\211\211\377\223\223\223\377\233\233\233\305\251\251\251" - "\247\277\277\277}\323\323\323S\344\344\3440\351\351\351\30\345\345\345\12" - "\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\337\327\40\3779\0\377\377\224\0\377\377" - "\224\0\377\377\222\0\377\377\214\0\377\377\204\0\377\377{\0\377\377t\0\377" - "\377q\0\377\377p\0\377\377o\0\377\377N\0\377\270N8\377fff\377]]]\377XXX\377" - "TTT\377RRR\377RRR\377TTT\377XXX\377^^^\377hhh\377ttt\377\201\201\201\377" - "\214\214\214\377ccc\377ggg\377iii\377jjj\377kkk\377kkk\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377kkk\377P" - "PP\377PPP\377PPP\377PPP\377\206\206\206\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\356\237\216\377\377E\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "E\0\377\352\232\212\377\324\324\324\377\306\306\306\377\264\264\264\377\240" - "\240\240\377\220\220\220\377\207\207\207\377\224\224\224\377\241\241\241" - "\272\262\262\262\226\310\310\310k\334\334\334C\351\351\351$\360\360\360\21" - "\332\332\332\7\177\177\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377`>\277\377z\0\377\377\224" - "\0\377\377\223\0\377\377\217\0\377\377\210\0\377\377\177\0\377\377w\0\377" - "\377r\0\377\377p\0\377\377o\0\377\377k\0\377\3675\7\377reb\377___\377XXX" - "\377UUU\377RRR\377RRR\377SSS\377VVV\377\\\\\\\377ddd\377ooo\377|||\377\210" - "\210\210\377\222\222\222\377fff\377hhh\377jjj\377kkk\377kkk\377kkk\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\223\223\223" - "\377PPP\377PPP\377PPP\377PPP\377PPP\377\256\256\256\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\372O+\377\377b\0\377\377o\0\377\377o\0\377\377k\0\377" - "\375;\15\377\334\317\314\377\317\317\317\377\277\277\277\377\255\255\255" - "\377\232\232\232\377\214\214\214\377\206\206\206\377\231\231\231\377\247" - "\247\247\254\273\273\273\205\321\321\321Z\342\342\3425\354\354\354\33\351" - "\351\351\14\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\307\273@\377F\0\377\377\224" - "\0\377\377\224\0\377\377\221\0\377\377\214\0\377\377\203\0\377\377z\0\377" - "\377s\0\377\377q\0\377\377o\0\377\377o\0\377\377N\0\377\265K5\377aaa\377" - "ZZZ\377UUU\377SSS\377QQQ\377RRR\377TTT\377XXX\377```\377kkk\377www\377\204" - "\204\204\377\217\217\217\377\227\227\227\377hhh\377jjj\377kkk\377kkk\377" - "kkk\377kkk\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\206\206\206\377PPP\377PPP\377PPP\377PPP\377]]]\377\326\326\326\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\347\315\307\377\3774\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377V\0\377\363oT\377\327\327\327\377\312\312\312\377\271\271\271" - "\377\245\245\245\377\224\224\224\377\211\211\211\377\207\207\207\377\235" - "\235\235\377\257\257\257\235\303\303\303s\331\331\331J\346\346\346)\361\361" - "\361\23\337\337\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377`>\277\377z\0\377" - "\377\224\0\377\377\223\0\377\377\217\0\377\377\207\0\377\377~\0\377\377v" - "\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\3774\0\377w]W\377\\\\" - "\\\377VVV\377SSS\377QQQ\377QQQ\377SSS\377VVV\377\\\\\\\377fff\377rrr\377" - "\177\177\177\377\213\213\213\377\224\224\224\377\233\233\233\377iii\377j" - "jj\377kkk\377kkk\377kkk\377kkk\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377]]]\377PPP\377PPP\377PPP\377PPP\377\206\206\206\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377PPP\377PPP\377PPP\377PPP" - "\377PPP\377PPP\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\360\223\200\377\377I\0\377\377o" - "\0\377\377o\0\377\377o\0\377\3779\0\377\343\273\263\377\323\323\323\377\305" - "\305\305\377\262\262\262\377\237\237\237\377\217\217\217\377\210\210\210" - "\377\212\212\212\377\243\243\243\377\267\267\267\214\315\315\315a\340\340" - "\340;\356\356\356\37\354\354\354\16\314\314\314\5\177\177\177\2\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "\307\273@\377F\0\377\377\224\0\377\377\223\0\377\377\221\0\377\377\213\0" - "\377\377\202\0\377\377y\0\377\377t\0\377\377q\0\377\377o\0\377\377o\0\377" - "\377V\0\377\306C'\377^^^\377XXX\377SSS\377RRR\377QQQ\377RRR\377UUU\377ZZ" - "Z\377aaa\377mmm\377yyy\377\206\206\206\377\221\221\221\377\230\230\230\377" - "\235\235\235\377\237\237\237\377\240\240\240\377\240\240\240\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\223\223\223\377PPP\377PPP\377PPP\377PPP\377PPP\377\256\256" - "\256\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\374C\35\377\377g\0\377\377o\0\377\377o\0" - "\377\377b\0\377\371N*\377\331\331\331\377\317\317\317\377\276\276\276\377" - "\254\254\254\377\231\231\231\377\213\213\213\377\210\210\210\377\215\215" - "\215\377\252\252\252\377\300\300\300{\322\322\322Q\343\343\343.\350\350\350" - "\27\342\342\342\11\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377`>\277\377z\0\377\377" - "\224\0\377\377\222\0\377\377\216\0\377\377\207\0\377\377}\0\377\377v\0\377" - "\377r\0\377\377p\0\377\377o\0\377\377o\0\377\3779\0\377\177WO\377YYY\377" - "UUU\377RRR\377QQQ\377QQQ\377SSS\377VVV\377]]]\377ggg\377ttt\377\201\201\201" - "\377\214\214\214\377\226\226\226\377\233\233\233\377\236\236\236\377\240" - "\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\206" - "\206\206\377PPP\377PPP\377PPP\377PPP\377]]]\377\326\326\326\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\351" - "\301\271\377\3779\0\377\377o\0\377\377o\0\377\377o\0\377\377E\0\377\352\233" - "\212\377\326\326\326\377\311\311\311\377\267\267\267\377\245\245\245\377" - "\224\224\224\377\212\212\212\377\211\211\211\377\222\222\222\377\262\262" - "\262\377\311\311\311i\333\333\333A\351\351\351#\357\357\357\20\324\324\324" - "\6\177\177\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\324\3110\377@\0\377\377\224\0\377\377\224\0" - "\377\377\221\0\377\377\212\0\377\377\201\0\377\377x\0\377\377s\0\377\377" - "q\0\377\377p\0\377\377o\0\377\377^\0\377\330:\31\377\\\\\\\377VVV\377SSS" - "\377QQQ\377QQQ\377RRR\377UUU\377ZZZ\377bbb\377nnn\377zzz\377\210\210\210" - "\377\222\222\222\377\231\231\231\377\235\235\235\377\240\240\240\377\240" - "\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377kkk\377" - "PPP\377PPP\377PPP\377PPP\377\206\206\206\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\363" - "}d\377\377R\0\377\377o\0\377\377o\0\377\377k\0\377\375;\15\377\335\320\315" - "\377\322\322\322\377\303\303\303\377\261\261\261\377\236\236\236\377\217" - "\217\217\377\211\211\211\377\213\213\213\377\230\230\230\377\272\272\272" - "\377\320\320\320X\341\341\3414\353\353\353\32\347\347\347\13\277\277\277" - "\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\377y^\237\377m\0\377\377\224\0\377\377\223\0\377\377\216" - "\0\377\377\206\0\377\377|\0\377\377u\0\377\377q\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377E\0\377\233K;\377XXX\377SSS\377QQQ\377QQQ\377QQQ\377SSS\377" - "WWW\377^^^\377hhh\377ttt\377\202\202\202\377\215\215\215\377\226\226\226" - "\377\234\234\234\377\237\237\237\377\240\240\240\377\240\240\240\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\223\223\223\377PPP\377PPP\377PPP\377" - "PPP\377PPP\377\256\256\256\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\374C\35\377\377g\0\377" - "\377o\0\377\377o\0\377\377V\0\377\363pT\377\330\330\330\377\316\316\316\377" - "\275\275\275\377\252\252\252\377\230\230\230\377\213\213\213\377\211\211" - "\211\377\220\220\220\377\236\236\236\377\303\303\303\377\330\330\330I\345" - "\345\345(\361\361\361\23\337\337\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\357\337" - "\20\3773\0\377\377\224\0\377\377\224\0\377\377\222\0\377\377\213\0\377\377" - "\202\0\377\377y\0\377\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377k\0" - "\377\365/\6\377ZZZ\377UUU\377RRR\377QQQ\377QQQ\377RRR\377UUU\377ZZZ\377b" - "bb\377nnn\377{{{\377\210\210\210\377\222\222\222\377\231\231\231\377\236" - "\236\236\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\206\206\206\377PPP\377PPP\377PPP\377PPP\377" - "PPP\377\311\311\311\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\354\252\234\377\377A\0\377\377o\0\377\377o\0" - "\377\377o\0\377\3779\0\377\344\274\264\377\325\325\325\377\310\310\310\377" - "\266\266\266\377\243\243\243\377\223\223\223\377\212\212\212\377\213\213" - "\213\377\225\225\225\377\245\245\245\377\314\314\314\377\340\340\340:\356" - "\356\356\36\353\353\353\15\314\314\314\5\177\177\177\2\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\223}\200" - "\377a\0\377\377\224\0\377\377\224\0\377\377\220\0\377\377\210\0\377\377~" - "\0\377\377u\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377\377V\0\377" - "\302>#\377VVV\377SSS\377QQQ\377QQQ\377QQQ\377SSS\377VVV\377]]]\377hhh\377" - "uuu\377\202\202\202\377\216\216\216\377\227\227\227\377\234\234\234\377\237" - "\237\237\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\206\206\206\377PPP\377PPP\377PPP\377PPP\377" - "kkk\377\326\326\326\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\365qV\377\377V\0\377\377o\0\377\377o\0\377\377" - "g\0\377\373C\34\377\333\333\333\377\321\321\321\377\302\302\302\377\257\257" - "\257\377\234\234\234\377\217\217\217\377\212\212\212\377\216\216\216\377" - "\234\234\234\377\255\255\255\377\324\324\324\377\343\343\343.\363\363\363" - "\26\342\342\342\11\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377E\36\337\377\210\0\377" - "\377\224\0\377\377\223\0\377\377\216\0\377\377\205\0\377\377z\0\377\377s" - "\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\3779\0\377xQH\377UUU\377" - "RRR\377QQQ\377QQQ\377RRR\377UUU\377ZZZ\377bbb\377mmm\377{{{\377\210\210\210" - "\377\222\222\222\377\232\232\232\377\236\236\236\377\240\240\240\377\240" - "\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377kkk\377PPP\377PPP\377PPP\377PPP\377\223\223\223\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\3758\16\377\377k\0\377\377o\0\377\377o\0\377\377I\0\377\355" - "\220}\377\330\330\330\377\314\314\314\377\274\274\274\377\250\250\250\377" - "\227\227\227\377\214\214\214\377\213\213\213\377\223\223\223\377\242\242" - "\242\377\265\265\265\377\333\333\333\377\351\351\351#\357\357\357\20\324" - "\324\324\6\177\177\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\324\3110\377@\0\377\377\224\0\377\377" - "\224\0\377\377\222\0\377\377\214\0\377\377\201\0\377\377x\0\377\377r\0\377" - "\377p\0\377\377o\0\377\377o\0\377\377g\0\377\3532\14\377VVV\377SSS\377QQ" - "Q\377QQQ\377QQQ\377SSS\377VVV\377]]]\377fff\377ttt\377\201\201\201\377\215" - "\215\215\377\226\226\226\377\234\234\234\377\245\230\225\377\276|n\377\320" - "fP\377\342Q3\377\347I(\377\347I(\377\347I(\377\342Q3\377\320fP\377\276|n" - "\377\247\232\227\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\223\223\223\377]]]\377PPP\377PPP\377PPP\377PPP\377\256" - "\256\256\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\356\237\216\377\377E\0\377\377o\0\377\377o\0\377\377" - "o\0\377\3770\0\377\337\322\317\377\325\325\325\377\306\306\306\377\265\265" - "\265\377\242\242\242\377\223\223\223\377\213\213\213\377\214\214\214\377" - "\230\230\230\377\252\252\252\377\275\275\275\377\341\341\341\377\353\353" - "\353\32\347\347\347\13\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377y^\237\377m\0\377" - "\377\224\0\377\377\224\0\377\377\220\0\377\377\210\0\377\377}\0\377\377u" - "\0\377\377q\0\377\377o\0\377\377o\0\377\377o\0\377\377R\0\377\266@'\377T" - "TT\377QQQ\377QQQ\377QQQ\377QQQ\377TTT\377XXX\377aaa\377lll\377zzz\377\207" - "\207\207\377\231\214\211\377\277p_\377\355A\36\377\3770\0\377\377A\0\377" - "\377N\0\377\377[\0\377\377_\0\377\377^\0\377\377^\0\377\377Z\0\377\377N\0" - "\377\377A\0\377\3770\0\377\355B\36\377\304ud\377\247\232\227\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\206\206\206\377PPP\377PPP\377PPP\377PPP\377PPP\377\311\311" - "\311\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\367fH\377\377Z\0\377\377o\0\377\377o\0\377\377Z\0\377\365" - "dF\377\332\332\332\377\320\320\320\377\301\301\301\377\256\256\256\377\234" - "\234\234\377\217\217\217\377\213\213\213\377\221\221\221\377\236\236\236" - "\377\261\261\261\377\304\304\304\377\347\347\347\377\361\361\361\23\337\337" - "\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3778\16\357\377\215\0\377\377\224\0" - "\377\377\222\0\377\377\215\0\377\377\204\0\377\377z\0\377\377s\0\377\377" - "p\0\377\377o\0\377\377o\0\377\377o\0\377\3779\0\377vNF\377SSS\377QQQ\377" - "QQQ\377QQQ\377RRR\377UUU\377\\\\\\\377eee\377rrr\377\200\200\200\377\306" - "\\F\377\3707\10\377\377E\0\377\377b\0\377\377p\0\377\377p\0\377\377q\0\377" - "\377q\0\377\377q\0\377\377q\0\377\377p\0\377\377p\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377b\0\377\377E\0\377\3717\11\377\320fP\377\240\240\240\377" - "\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377\206\206" - "\206\377PPP\377PPP\377PPP\377PPP\377kkk\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\346\330\326\377\3770\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377A\0\377\351\247\231\377\327\327\327" - "\377\313\313\313\377\272\272\272\377\247\247\247\377\226\226\226\377\214" - "\214\214\377\213\213\213\377\225\225\225\377\245\245\245\377\271\271\271" - "\377\312\312\312\377\354\354\354\377\353\353\353\15\314\314\314\5\177\177" - "\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\324\3110\377?\0\377\377\224\0\377\377\224\0\377\377\221" - "\0\377\377\212\0\377\377\200\0\377\377w\0\377\377r\0\377\377p\0\377\377o" - "\0\377\377o\0\377\377k\0\377\365/\6\377TTT\377RRR\377QQQ\377QQQ\377QQQ\377" - "SSS\377WWW\377___\377jjj\377\231dY\377\3607\21\377\377N\0\377\377k\0\377" - "\377p\0\377\377p\0\377\377q\0\377\377s\0\377\377t\0\377\377u\0\377\377u\0" - "\377\377t\0\377\377r\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377k\0\377\377N\0\377\363;\24\377\262\212\202\377\240" - "\240\240\377\240\240\240\377\240\240\240\377kkk\377PPP\377PPP\377PPP\377" - "PPP\377\206\206\206\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\360\223\200\377\377I\0\377\377o\0\377\377o\0" - "\377\377g\0\377\373C\34\377\335\335\335\377\324\324\324\377\306\306\306\377" - "\264\264\264\377\241\241\241\377\222\222\222\377\213\213\213\377\217\217" - "\217\377\234\234\234\377\255\255\255\377\300\300\300\377\317\317\317\377" - "\360\360\360\377\342\342\342\11\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\207n\217" - "\377f\0\377\377\224\0\377\377\223\0\377\377\217\0\377\377\207\0\377\377|" - "\0\377\377u\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377\377V\0\377" - "\277<\40\377SSS\377QQQ\377QQQ\377QQQ\377RRR\377UUU\377ZZZ\377bbb\377\267" - "M7\377\377=\0\377\377g\0\377\377o\0\377\377o\0\377\377p\0\377\377q\0\377" - "\377s\0\377\377v\0\377\377z\0\377\377|\0\377\377}\0\377\377z\0\377\377w\0" - "\377\377t\0\377\377r\0\377\377p\0\377\377p\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377g\0\377\3779\0\377\303sc\377\236\236\236\377\237\237" - "\237\377\\\\\\\377PPP\377PPP\377PPP\377PPP\377\241\241\241\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\372" - "O+\377\377b\0\377\377o\0\377\377o\0\377\377R\0\377\361{b\377\332\332\332" - "\377\317\317\317\377\277\277\277\377\255\255\255\377\233\233\233\377\216" - "\216\216\377\213\213\213\377\223\223\223\377\242\242\242\377\265\265\265" - "\377\306\306\306\377\324\324\324\377\363\363\363\377\324\324\324\6\177\177" - "\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377S.\317\377\200\0\377\377\224\0\377\377\223\0\377" - "\377\215\0\377\377\204\0\377\377z\0\377\377s\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377E\0\377\225F5\377RRR\377QQQ\377QQQ\377QQQ\377S" - "SS\377VVV\377]]]\377\306B'\377\377N\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377p\0\377\377g\0\377\377`\0\377\377c\0\377\377x\0\377\377\203\0\377\377" - "\207\0\377\377\207\0\377\377\204\0\377\377\177\0\377\377z\0\377\377u\0\377" - "\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377E\0\377\323]D\377\217\217\217\377NNN\377OOO\377OOO\377" - "PPP\377PPP\377\273\273\273\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\347\315\307\377\3774\0\377\377o\0\377\377o\0\377\377" - "o\0\377\3774\0\377\342\310\302\377\327\327\327\377\312\312\312\377\271\271" - "\271\377\246\246\246\377\225\225\225\377\214\214\214\377\215\215\215\377" - "\230\230\230\377\251\251\251\377\274\274\274\377\315\315\315\377\327\327" - "\327\377\365\365\365\377\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\337\327\40\377" - "9\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\213\0\377\377\201\0" - "\377\377x\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "4\0\377iNI\377QQQ\377QQQ\377QQQ\377QQQ\377SSS\377XXX\377\260F0\377\377N\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377V\0\377\3775\0\377\363;\24\377\347" - "I(\377\347I(\377\3713\12\377\377>\0\377\377j\0\377\377\217\0\377\377\215" - "\0\377\377\210\0\377\377\201\0\377\377{\0\377\377v\0\377\377r\0\377\377p" - "\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377N\0\377\305[E\377MMM\377MMM\377NNN\377OOO\377\\\\\\\377\310\310\310\377" - "\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\362\210" - "r\377\377N\0\377\377o\0\377\377o\0\377\377b\0\377\371N*\377\334\334\334\377" - "\323\323\323\377\305\305\305\377\262\262\262\377\237\237\237\377\222\222" - "\222\377\213\213\213\377\221\221\221\377\236\236\236\377\260\260\260\377" - "\303\303\303\377\321\321\321\377\333\333\333\377\367\367\367\377\252\252" - "\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\257\234`\377S\0\377\377\224\0\377\377\223\0\377" - "\377\220\0\377\377\210\0\377\377~\0\377\377v\0\377\377r\0\377\377p\0\377" - "\377o\0\377\377o\0\377\377g\0\377\3521\13\377RRR\377QQQ\377QQQ\377QQQ\377" - "RRR\377UUU\377dWT\377\3664\6\377\377k\0\377\377o\0\377\377k\0\377\377=\0" - "\377\331V:\377\252\220\212\377\237\237\237\377\237\237\237\377\236\236\236" - "\377\234\234\234\377\254\204|\377\327T8\377\377?\0\377\377\177\0\377\377" - "\217\0\377\377\211\0\377\377\202\0\377\377{\0\377\377v\0\377\377r\0\377\377" - "p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377E\0\377\216>.\377KKK\377LLL\377MMM\377iii\377\323\323\323\377\342\342" - "\342\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\374C\35\377\377" - "g\0\377\377o\0\377\377o\0\377\377E\0\377\354\234\214\377\331\331\331\377" - "\317\317\317\377\276\276\276\377\254\254\254\377\232\232\232\377\216\216" - "\216\377\214\214\214\377\225\225\225\377\245\245\245\377\267\267\267\377" - "\311\311\311\377\326\326\326\377\336\336\336\377\370\370\370\377\177\177" - "\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\207n\217\377f\0\377\377\224\0\377\377\223\0\377" - "\377\217\0\377\377\206\0\377\377|\0\377\377u\0\377\377q\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377Z\0\377\3119\32\377QQQ\377QQQ\377QQQ\377QQQ\377" - "SSS\377VVV\377\206QF\377\377=\0\377\377o\0\377\377^\0\377\3706\10\377\262" - "}r\377\235\235\235\377\236\236\236\377\236\236\236\377\235\235\235\377\232" - "\232\232\377\227\227\227\377\222\222\222\377\215\215\215\377\236wn\377\351" - "B\27\377\377l\0\377\377\217\0\377\377\212\0\377\377\203\0\377\377|\0\377" - "\377v\0\377\377s\0\377\377q\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377k\0\377\3659\3\377iA9\377III\377KKK\377\201\201\201\377" - "\337\337\337\377\341\341\341\377\342\342\342\377\343\343\343\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\351\301" - "\271\377\3779\0\377\377o\0\377\377o\0\377\377o\0\377\3770\0\377\340\323\320" - "\377\326\326\326\377\311\311\311\377\267\267\267\377\245\245\245\377\224" - "\224\224\377\214\214\214\377\217\217\217\377\233\233\233\377\254\254\254" - "\377\276\276\276\377\317\317\317\377\331\331\331\377\340\340\340\377\371" - "\371\371\377\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377S.\317\377\200\0\377\377\224\0\377" - "\377\223\0\377\377\216\0\377\377\204\0\377\377z\0\377\377t\0\377\377p\0\377" - "\377p\0\377\377o\0\377\377o\0\377\377N\0\377\251?)\377QQQ\377QQQ\377QQQ\377" - "QQQ\377SSS\377XXX\377j]Z\377\3674\7\377\377E\0\377\341C\"\377\231\214\211" - "\377\232\232\232\377\235\235\235\377\236\236\236\377\234\234\234\377\231" - "\231\231\377\224\224\224\377\217\217\217\377\210\210\210\377\201\201\201" - "\377{{{\377~pn\377\311F*\377\377l\0\377\377\220\0\377\377\212\0\377\377\204" - "\0\377\377|\0\377\377w\0\377\377s\0\377\377q\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377b\0\377\3330\14\377DDD\377GGG\377{{" - "{\377\330\330\330\377\336\336\336\377\340\340\340\377\342\342\342\377\343" - "\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\363" - "}d\377\377R\0\377\377o\0\377\377o\0\377\377V\0\377\363pT\377\333\333\333" - "\377\322\322\322\377\303\303\303\377\260\260\260\377\236\236\236\377\221" - "\221\221\377\214\214\214\377\223\223\223\377\241\241\241\377\263\263\263" - "\377\305\305\305\377\323\323\323\377\334\334\334\377\340\340\340\377\372" - "\372\372\377\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224\0\377" - "\377\222\0\377\377\215\0\377\377\202\0\377\377y\0\377\377s\0\377\377p\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377=\0\377}H=\377QQQ\377PPP\377QQQ\377" - "RRR\377UUU\377ZZZ\377ccc\377\213c[\377\257_O\377\214\214\214\377\225\225" - "\225\377\233\233\233\377\235\235\235\377\233\233\233\377\230\230\230\377" - "\222\222\222\377\214\214\214\377\204\204\204\377|||\377uuu\377ooo\377iii" - "\377fff\377\330:\31\377\377y\0\377\377\220\0\377\377\213\0\377\377\204\0" - "\377\377}\0\377\377v\0\377\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377N\0\377\2364\36\377BBB\377\214\214\214\377" - "\317\317\317\377\327\327\327\377\335\335\335\377\340\340\340\377\342\342" - "\342\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\3758\16" - "\377\377k\0\377\377o\0\377\377o\0\377\377A\0\377\351\247\231\377\330\330" - "\330\377\315\315\315\377\275\275\275\377\252\252\252\377\231\231\231\377" - "\216\216\216\377\216\216\216\377\227\227\227\377\247\247\247\377\272\272" - "\272\377\313\313\313\377\327\327\327\377\337\337\337\377\341\341\341\377" - "\372\372\372\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\324\3110\377?\0\377\377\224\0\377\377" - "\224\0\377\377\222\0\377\377\213\0\377\377\201\0\377\377x\0\377\377r\0\377" - "\377p\0\377\377o\0\377\377o\0\377\377o\0\377\3774\0\377gLG\377QQQ\377PPP" - "\377QQQ\377RRR\377VVV\377\\\\\\\377fff\377ttt\377\202\202\202\377\217\217" - "\217\377\227\227\227\377\233\233\233\377\233\233\233\377\230\230\230\377" - "\222\222\222\377\212\212\212\377\201\201\201\377yyy\377rrr\377kkk\377ggg" - "\377ccc\377aaa\377h[X\377\3548\13\377\377\206\0\377\377\221\0\377\377\213" - "\0\377\377\204\0\377\377|\0\377\377u\0\377\377r\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\3774\0\377T:4\377\213\213\213" - "\377\303\303\303\377\317\317\317\377\327\327\327\377\335\335\335\377\340" - "\340\340\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\354\252\234\377\377" - "A\0\377\377o\0\377\377o\0\377\377g\0\377\373C\34\377\335\335\335\377\325" - "\325\325\377\307\307\307\377\266\266\266\377\244\244\244\377\224\224\224" - "\377\215\215\215\377\220\220\220\377\234\234\234\377\256\256\256\377\301" - "\301\301\377\320\320\320\377\332\332\332\377\340\340\340\377\342\342\342" - "\377\372\372\372\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\257\234`\377S\0\377\377\224\0\377" - "\377\224\0\377\377\221\0\377\377\212\0\377\377\177\0\377\377w\0\377\377r" - "\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377,\0\377QQQ\377QQQ\377" - "QQQ\377QQQ\377SSS\377WWW\377___\377jjj\377xxx\377\206\206\206\377\222\222" - "\222\377\230\230\230\377\233\233\233\377\231\231\231\377\223\223\223\377" - "\213\213\213\377\201\201\201\377xxx\377ppp\377kkk\377ggg\377ddd\377ccc\377" - "bbb\377aaa\377\207RG\377\377F\0\377\377\223\0\377\377\220\0\377\377\212\0" - "\377\377\202\0\377\377{\0\377\377u\0\377\377q\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377V\0\377\2630\24\377\211\211\211\377" - "\252\252\252\377\266\266\266\377\301\301\301\377\311\311\311\377\317\317" - "\317\377\323\323\323\377\324\324\324\377\325\325\325\377\326\326\326\377" - "\326\326\326\377\326\326\326\377\326\326\326\377\326\326\326\377\326\326" - "\326\377\326\326\326\377\326\326\326\377\326\326\326\377\326\326\326\377" - "\326\326\326\377\326\326\326\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\365qV\377\377V\0\377\377" - "o\0\377\377o\0\377\377R\0\377\361{b\377\333\333\333\377\321\321\321\377\302" - "\302\302\377\257\257\257\377\235\235\235\377\221\221\221\377\215\215\215" - "\377\224\224\224\377\244\244\244\377\266\266\266\377\307\307\307\377\325" - "\325\325\377\335\335\335\377\341\341\341\377\343\343\343\377\373\373\373" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\377\223}\200\377`\0\377\377\224\0\377\377\223\0\377" - "\377\220\0\377\377\210\0\377\377~\0\377\377u\0\377\377q\0\377\377p\0\377" - "\377o\0\377\377o\0\377\377^\0\377\3246\25\377QQQ\377PPP\377QQQ\377QQQ\377" - "TTT\377XXX\377aaa\377mmm\377|||\377\212\212\212\377\224\224\224\377\231\231" - "\231\377\232\232\232\377\226\226\226\377\217\217\217\377\205\205\205\377" - "zzz\377qqq\377kkk\377iii\377iii\377iii\377kkk\377kkk\377kkk\377iii\377\305" - "B&\377\377m\0\377\377\223\0\377\377\220\0\377\377\211\0\377\377\201\0\377" - "\377y\0\377\377t\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\3774\0\377V<6\377CCC\377III\377PPP\377TTT\377XXX\377ZZZ\377" - "\\\\\\\377]]]\377]]]\377]]]\377]]]\377]]]\377]]]\377]]]\377]]]\377]]]\377" - "]]]\377]]]\377]]]\377\274\274\274\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\346\330\326\377\3770\0\377\377o\0\377" - "\377o\0\377\377o\0\377\3774\0\377\343\311\303\377\327\327\327\377\314\314" - "\314\377\274\274\274\377\251\251\251\377\230\230\230\377\216\216\216\377" - "\217\217\217\377\231\231\231\377\252\252\252\377\275\275\275\377\315\315" - "\315\377\330\330\330\377\337\337\337\377\342\342\342\377\343\343\343\377" - "\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377mN\257\377s\0\377\377\224\0\377\377\223" - "\0\377\377\217\0\377\377\206\0\377\377|\0\377\377u\0\377\377q\0\377\377p" - "\0\377\377o\0\377\377o\0\377\377^\0\377\3235\24\377QQQ\377PPP\377QQQ\377" - "RRR\377UUU\377ZZZ\377ddd\377qqq\377\200\200\200\377\214\214\214\377\226\226" - "\226\377\232\232\232\377\231\231\231\377\224\224\224\377\213\213\213\377" - "\200\200\200\377vvv\377ooo\377mmm\377nnn\377ppp\377ttt\377www\377yyy\377" - "xxx\377vvv\377\204id\377\3779\0\377\377\224\0\377\377\223\0\377\377\217\0" - "\377\377\210\0\377\377\177\0\377\377x\0\377\377s\0\377\377p\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377R\0\377\245.\26\377555\377:::\377" - "@@@\377EEE\377III\377MMM\377NNN\377OOO\377PPP\377PPP\377PPP\377PPP\377PP" - "P\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377\311\311\311\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\356\237\216" - "\377\377E\0\377\377o\0\377\377o\0\377\377b\0\377\371N*\377\335\335\335\377" - "\324\324\324\377\306\306\306\377\265\265\265\377\242\242\242\377\224\224" - "\224\377\215\215\215\377\222\222\222\377\237\237\237\377\261\261\261\377" - "\304\304\304\377\322\322\322\377\333\333\333\377\340\340\340\377\342\342" - "\342\377\343\343\343\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377`>\277\377z\0" - "\377\377\224\0\377\377\223\0\377\377\216\0\377\377\204\0\377\377z\0\377\377" - "t\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377N\0\377\250>(\377" - "QQQ\377PPP\377QQQ\377RRR\377UUU\377\\\\\\\377fff\377ttt\377\203\203\203\377" - "\217\217\217\377\230\230\230\377\233\233\233\377\231\231\231\377\223\223" - "\223\377\212\212\212\377\200\200\200\377www\377sss\377ttt\377www\377|||\377" - "\201\201\201\377\205\205\205\377\206\206\206\377\206\206\206\377\204\204" - "\204\377\200\200\200\377\315I.\377\377m\0\377\377\224\0\377\377\222\0\377" - "\377\216\0\377\377\206\0\377\377}\0\377\377v\0\377\377r\0\377\377p\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377k\0\377\362,\3\377111\377555\377;;;" - "\377AAA\377FFF\377JJJ\377MMM\377OOO\377OOO\377PPP\377PPP\377PPP\377PPP\377" - "PPP\377PPP\377PPP\377PPP\377PPP\377kkk\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\367fH\377\377Z\0" - "\377\377o\0\377\377o\0\377\377E\0\377\354\234\214\377\332\332\332\377\320" - "\320\320\377\300\300\300\377\256\256\256\377\234\234\234\377\220\220\220" - "\377\216\216\216\377\226\226\226\377\245\245\245\377\270\270\270\377\311" - "\311\311\377\327\327\327\377\336\336\336\377\341\341\341\377\343\343\343" - "\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3778\16\357\377\215" - "\0\377\377\224\0\377\377\222\0\377\377\215\0\377\377\203\0\377\377z\0\377" - "\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377N\0\377\250>(" - "\377PPP\377PPP\377QQQ\377SSS\377VVV\377]]]\377iii\377www\377\205\205\205" - "\377\221\221\221\377\231\231\231\377\233\233\233\377\231\231\231\377\224" - "\224\224\377\214\214\214\377\204\204\204\377~~~\377|||\377~~~\377\203\203" - "\203\377\210\210\210\377\215\215\215\377\220\220\220\377\222\222\222\377" - "\222\222\222\377\220\220\220\377\215\215\215\377\226|v\377\3779\0\377\377" - "\224\0\377\377\224\0\377\377\222\0\377\377\214\0\377\377\203\0\377\377z\0" - "\377\377t\0\377\377p\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "A\0\377o-\37\377111\377777\377===\377CCC\377HHH\377KKK\377NNN\377OOO\377" - "PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377\223\223\223" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\347\315\307\377\3774\0\377\377o\0\377\377o\0\377\377o\0\377\3770\0\377" - "\341\324\321\377\327\327\327\377\313\313\313\377\272\272\272\377\247\247" - "\247\377\227\227\227\377\216\216\216\377\220\220\220\377\234\234\234\377" - "\255\255\255\377\277\277\277\377\317\317\317\377\331\331\331\377\340\340" - "\340\377\342\342\342\377\343\343\343\377\344\344\344\377\373\373\373\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224\0\377\377\222\0\377\377" - "\214\0\377\377\202\0\377\377y\0\377\377s\0\377\377p\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377N\0\377\250>(\377PPP\377QQQ\377QQQ\377SSS\377XXX\377" - "___\377kkk\377zzz\377\210\210\210\377\223\223\223\377\232\232\232\377\235" - "\235\235\377\233\233\233\377\227\227\227\377\221\221\221\377\213\213\213" - "\377\206\206\206\377\206\206\206\377\211\211\211\377\215\215\215\377\222" - "\222\222\377\226\226\226\377\230\230\230\377\231\231\231\377\231\231\231" - "\377\231\231\231\377\226\226\226\377\222\222\222\377\342D#\377\377z\0\377" - "\377\224\0\377\377\223\0\377\377\220\0\377\377\210\0\377\377~\0\377\377v" - "\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377V\0\377" - "\257,\20\377...\377333\377888\377>>>\377DDD\377III\377MMM\377NNN\377OOO\377" - "PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377\274\274\274\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\360\223\200\377\377I\0\377\377o\0\377\377o\0\377\377V\0\377\364pU\377\334" - "\334\334\377\323\323\323\377\306\306\306\377\263\263\263\377\241\241\241" - "\377\223\223\223\377\216\216\216\377\224\224\224\377\241\241\241\377\264" - "\264\264\377\306\306\306\377\324\324\324\377\334\334\334\377\340\340\340" - "\377\343\343\343\377\344\344\344\377\344\344\344\377\373\373\373\377\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224\0\377\377\222\0\377\377\213" - "\0\377\377\201\0\377\377x\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377=\0\377}H=\377PPP\377QQQ\377QQQ\377TTT\377XXX\377aaa\377n" - "nn\377|||\377\212\212\212\377\225\225\225\377\233\233\233\377\235\235\235" - "\377\235\235\235\377\232\232\232\377\226\226\226\377\222\222\222\377\220" - "\220\220\377\221\221\221\377\222\222\222\377\226\226\226\377\231\231\231" - "\377\234\234\234\377\235\235\235\377\236\236\236\377\236\236\236\377\235" - "\235\235\377\233\233\233\377\231\231\231\377\274m\\\377\377S\0\377\377\224" - "\0\377\377\224\0\377\377\222\0\377\377\214\0\377\377\203\0\377\377y\0\377" - "\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377k\0\377\364.\5" - "\377QQQ\377WWW\377```\377kkk\377www\377\202\202\202\377\212\212\212\377\216" - "\216\216\377\221\221\221\377\222\222\222\377\223\223\223\377\206\206\206" - "\377PPP\377PPP\377PPP\377PPP\377]]]\377\311\311\311\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\372O+\377\377b\0\377" - "\377o\0\377\377o\0\377\377A\0\377\352\250\232\377\331\331\331\377\317\317" - "\317\377\277\277\277\377\255\255\255\377\234\234\234\377\220\220\220\377" - "\217\217\217\377\230\230\230\377\250\250\250\377\273\273\273\377\313\313" - "\313\377\327\327\327\377\337\337\337\377\342\342\342\377\343\343\343\377" - "\344\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377" - "\377\224\0\377\377\224\0\377\377\222\0\377\377\213\0\377\377\200\0\377\377" - "w\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377" - "}H=\377PPP\377QQQ\377QQQ\377TTT\377ZZZ\377ccc\377ppp\377\177\177\177\377" - "\215\215\215\377\226\226\226\377\234\234\234\377\236\236\236\377\236\236" - "\236\377\235\235\235\377\233\233\233\377\231\231\231\377\230\230\230\377" - "\230\230\230\377\231\231\231\377\234\234\234\377\235\235\235\377\236\236" - "\236\377\240\240\240\377\240\240\240\377\240\240\240\377\240\240\240\377" - "\236\236\236\377\235\235\235\377\237\222\217\377\3772\0\377\377\224\0\377" - "\377\224\0\377\377\223\0\377\377\217\0\377\377\206\0\377\377|\0\377\377u" - "\0\377\377q\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\3779\0\377" - "uME\377[[[\377ccc\377nnn\377|||\377\210\210\210\377\222\222\222\377\232\232" - "\232\377\236\236\236\377\240\240\240\377\240\240\240\377\206\206\206\377" - "PPP\377PPP\377PPP\377PPP\377kkk\377\326\326\326\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\347\315\307\377\3774\0\377\377o\0\377\377" - "o\0\377\377g\0\377\373C\34\377\336\336\336\377\327\327\327\377\312\312\312" - "\377\270\270\270\377\245\245\245\377\226\226\226\377\216\216\216\377\221" - "\221\221\377\235\235\235\377\257\257\257\377\301\301\301\377\320\320\320" - "\377\332\332\332\377\340\340\340\377\342\342\342\377\343\343\343\377\344" - "\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377" - "\224\0\377\377\224\0\377\377\221\0\377\377\212\0\377\377\200\0\377\377w\0" - "\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G" - "<\377PPP\377QQQ\377RRR\377UUU\377[[[\377eee\377rrr\377\201\201\201\377\217" - "\217\217\377\230\230\230\377\235\235\235\377\237\237\237\377\240\240\240" - "\377\237\237\237\377\236\236\236\377\235\235\235\377\235\235\235\377\235" - "\235\235\377\236\236\236\377\236\236\236\377\240\240\240\377\240\240\240" - "\377\240\240\240\377\240\240\240\377\240\240\240\377\240\240\240\377\240" - "\240\240\377\237\237\237\377\235\235\235\377\345G&\377\377y\0\377\377\224" - "\0\377\377\224\0\377\377\221\0\377\377\211\0\377\377\177\0\377\377w\0\377" - "\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377I\0\377\237B/" - "\377WWW\377^^^\377hhh\377uuu\377\202\202\202\377\216\216\216\377\227\227" - "\227\377\235\235\235\377\237\237\237\377\240\240\240\377kkk\377PPP\377PP" - "P\377PPP\377PPP\377\206\206\206\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\363}d\377\377R\0\377\377o\0\377\377o\0\377" - "\377R\0\377\361{b\377\334\334\334\377\322\322\322\377\304\304\304\377\262" - "\262\262\377\240\240\240\377\223\223\223\377\216\216\216\377\225\225\225" - "\377\244\244\244\377\266\266\266\377\307\307\307\377\325\325\325\377\335" - "\335\335\377\341\341\341\377\343\343\343\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0" - "\377\377\224\0\377\377\221\0\377\377\212\0\377\377\177\0\377\377w\0\377\377" - "r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377PPP" - "\377QQQ\377RRR\377UUU\377\\\\\\\377fff\377ttt\377\203\203\203\377\220\220" - "\220\377\231\231\231\377\235\235\235\377\240\240\240\377\240\240\240\377" - "\240\240\240\377\240\240\240\377\237\237\237\377\237\237\237\377\237\237" - "\237\377\240\240\240\377\240\240\240\377\240\240\240\377\240\240\240\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\240\240" - "\240\377\240\240\240\377\237\237\237\377\316dN\377\377_\0\377\377\224\0\377" - "\377\224\0\377\377\222\0\377\377\214\0\377\377\202\0\377\377x\0\377\377s" - "\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377V\0\377\276:\37\377" - "UUU\377ZZZ\377bbb\377nnn\377|||\377\211\211\211\377\224\224\224\377\233\233" - "\233\377\236\236\236\377\240\240\240\377kkk\377PPP\377PPP\377PPP\377PPP\377" - "\241\241\241\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\374C\35\377\377g\0\377\377o\0\377\377o\0\377\3774\0\377" - "\344\311\304\377\331\331\331\377\316\316\316\377\276\276\276\377\253\253" - "\253\377\233\233\233\377\220\220\220\377\220\220\220\377\232\232\232\377" - "\253\253\253\377\275\275\275\377\315\315\315\377\330\330\330\377\337\337" - "\337\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377" - "\377\224\0\377\377\221\0\377\377\212\0\377\377\177\0\377\377v\0\377\377r" - "\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377PPP\377" - "QQQ\377SSS\377VVV\377]]]\377hhh\377vvv\377\205\205\205\377\221\221\221\377" - "\231\231\231\377\236\236\236\377\240\240\240\377\240\240\240\377\240\240" - "\240\377\240\240\240\377\240\240\240\377\240\240\240\377\240\240\240\377" - "\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\240\240\240\377\240\240\240\377\266\201v\377\377E\0\377\377\224\0\377\377" - "\224\0\377\377\223\0\377\377\216\0\377\377\205\0\377\377{\0\377\377t\0\377" - "\377q\0\377\377o\0\377\377o\0\377\377o\0\377\377^\0\377\3235\24\377SSS\377" - "WWW\377^^^\377iii\377vvv\377\204\204\204\377\220\220\220\377\230\230\230" - "\377\235\235\235\377\222\222\222\377]]]\377PPP\377PPP\377PPP\377PPP\377\274" - "\274\274\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\351" - "\301\271\377\3779\0\377\377o\0\377\377o\0\377\377b\0\377\371N*\377\336\336" - "\336\377\326\326\326\377\310\310\310\377\267\267\267\377\245\245\245\377" - "\225\225\225\377\217\217\217\377\223\223\223\377\237\237\237\377\261\261" - "\261\377\304\304\304\377\322\322\322\377\333\333\333\377\340\340\340\377" - "\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224" - "\0\377\377\221\0\377\377\211\0\377\377\177\0\377\377v\0\377\377r\0\377\377" - "p\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377PPP\377QQQ\377" - "SSS\377VVV\377^^^\377iii\377www\377\206\206\206\377\222\222\222\377\232\232" - "\232\377\236\236\236\377\240\240\240\377\240\240\240\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\240\240\240\377\240\240\240\377\377,\0\377\377\223\0\377\377\224" - "\0\377\377\223\0\377\377\220\0\377\377\207\0\377\377}\0\377\377u\0\377\377" - "q\0\377\377p\0\377\377o\0\377\377o\0\377\377k\0\377\364.\5\377RRR\377UUU" - "\377[[[\377ddd\377ppp\377\177\177\177\377\214\214\214\377\226\226\226\377" - "\234\234\234\377\221\221\221\377PPP\377PPP\377PPP\377PPP\377PPP\377\311\311" - "\311\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\363}d\377" - "\377R\0\377\377o\0\377\377o\0\377\377E\0\377\354\234\214\377\333\333\333" - "\377\321\321\321\377\303\303\303\377\260\260\260\377\237\237\237\377\223" - "\223\223\377\217\217\217\377\226\226\226\377\246\246\246\377\270\270\270" - "\377\311\311\311\377\327\327\327\377\336\336\336\377\341\341\341\377\343" - "\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224\0\377" - "\377\221\0\377\377\211\0\377\377\177\0\377\377v\0\377\377q\0\377\377p\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377PPP\377QQQ\377SSS\377" - "WWW\377___\377kkk\377yyy\377\207\207\207\377\223\223\223\377\233\233\233" - "\377\236\236\236\377\240\240\240\377\240\240\240\377\206\206\206\377\223" - "\223\223\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\240\240\240\377\240\240\240\377\355A\36\377\377\200\0\377\377\224\0" - "\377\377\224\0\377\377\221\0\377\377\212\0\377\377\200\0\377\377w\0\377\377" - "r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377,\0\377QQQ\377SSS" - "\377XXX\377```\377lll\377zzz\377\210\210\210\377\223\223\223\377\232\232" - "\232\377\204\204\204\377PPP\377PPP\377PPP\377PPP\377]]]\377\326\326\326\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\3758\16\377\377" - "k\0\377\377o\0\377\377o\0\377\3770\0\377\324\307\304\377\231\231\231\377" - "\251\251\251\377\275\275\275\377\252\252\252\377\232\232\232\377\220\220" - "\220\377\221\221\221\377\234\234\234\377\255\255\255\377\277\277\277\377" - "\317\317\317\377\331\331\331\377\340\340\340\377\342\342\342\377\343\343" - "\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224\0\377\377" - "\221\0\377\377\211\0\377\377\177\0\377\377v\0\377\377r\0\377\377p\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377QQQ\377QQQ\377SSS\377WWW\377" - "___\377kkk\377zzz\377\210\210\210\377\224\224\224\377\233\233\233\377\236" - "\236\236\377\240\240\240\377\206\206\206\377kkk\377kkk\377kkk\377\206\206" - "\206\377\223\223\223\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\240\240\240\377" - "\341P2\377\377r\0\377\377\224\0\377\377\224\0\377\377\222\0\377\377\214\0" - "\377\377\202\0\377\377x\0\377\377s\0\377\377p\0\377\377o\0\377\377o\0\377" - "\377o\0\377\3770\0\377\\OL\377SSS\377VVV\377]]]\377hhh\377uuu\377\204\204" - "\204\377\220\220\220\377\231\231\231\377\203\203\203\377OOO\377PPP\377PP" - "P\377PPP\377kkk\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\354\252\234\377\377A\0\377\377o\0\377\377o\0\377\377V\0\377\326R7\377ZZ" - "Z\377KKK\377QQQ\377\240\240\240\377\244\244\244\377\225\225\225\377\217\217" - "\217\377\224\224\224\377\242\242\242\377\264\264\264\377\306\306\306\377" - "\324\324\324\377\334\334\334\377\340\340\340\377\343\343\343\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\224\0\377\377" - "\221\0\377\377\211\0\377\377\177\0\377\377w\0\377\377r\0\377\377p\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377E\0\377\222B2\377QQQ\377QQQ\377SSS\377X" - "XX\377```\377mmm\377{{{\377\211\211\211\377\224\224\224\377\233\233\233\377" - "\236\236\236\377\222\222\222\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377" - "\206\206\206\377\223\223\223\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\240\240\240\377\320fP\377\377_\0\377\377" - "\224\0\377\377\224\0\377\377\223\0\377\377\215\0\377\377\204\0\377\377y\0" - "\377\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377}H" - "=\377RRR\377UUU\377ZZZ\377ddd\377rrr\377\200\200\200\377\215\215\215\377" - "\227\227\227\377\202\202\202\377OOO\377PPP\377PPP\377PPP\377\206\206\206" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\365qV\377\377" - "V\0\377\377o\0\377\377o\0\377\377A\0\377\206D6\377MMM\377III\377DDD\377R" - "RR\377\224\224\224\377\222\222\222\377\220\220\220\377\230\230\230\377\250" - "\250\250\377\273\273\273\377\313\313\313\377\327\327\327\377\337\337\337" - "\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\377,\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\212\0\377\377" - "\177\0\377\377v\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377N\0\377\250>(\377QQQ\377QQQ\377SSS\377XXX\377aaa\377mmm\377|||\377" - "\212\212\212\377\225\225\225\377\233\233\233\377\221\221\221\377kkk\377k" - "kk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377\206\206\206" - "\377\223\223\223\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\312mZ\377\377" - "X\0\377\377\224\0\377\377\224\0\377\377\223\0\377\377\216\0\377\377\204\0" - "\377\377z\0\377\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377" - "=\0\377}H=\377QQQ\377TTT\377XXX\377aaa\377nnn\377|||\377\212\212\212\377" - "\225\225\225\377ggg\377OOO\377PPP\377PPP\377PPP\377\206\206\206\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\326\326\326\377\274\274\274\377\3702\11\377\377k\0\377\377" - "o\0\377\377k\0\377\364.\5\377NNN\377LLL\377HHH\377BBB\377;;;\377ccc\377\220" - "\220\220\377\222\222\222\377\235\235\235\377\257\257\257\377\301\301\301" - "\377\320\320\320\377\332\332\332\377\340\340\340\377\342\342\342\377\343" - "\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377\224\0" - "\377\377\224\0\377\377\221\0\377\377\212\0\377\377\200\0\377\377w\0\377\377" - "r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377N\0\377\250>(\377" - "QQQ\377QQQ\377SSS\377XXX\377aaa\377mmm\377|||\377\212\212\212\377\225\225" - "\225\377\234\234\234\377\221\221\221\377kkk\377kkk\377kkk\377kkk\377kkk\377" - "kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377\206\206\206\377" - "\223\223\223\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\270\203x\377\377E\0\377\377\224\0\377\377\224\0\377\377\223\0\377" - "\377\216\0\377\377\205\0\377\377{\0\377\377s\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377=\0\377}H=\377QQQ\377SSS\377WWW\377___\377kkk\377" - "yyy\377\207\207\207\377\223\223\223\377ggg\377OOO\377PPP\377PPP\377PPP\377" - "\223\223\223\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\326\326\326\377\311\311" - "\311\377\256\256\256\377\206\206\206\377]]]\377\222B2\377\377E\0\377\377" - "o\0\377\377o\0\377\377R\0\377\262;#\377MMM\377JJJ\377FFF\377???\377999\377" - "```\377\220\220\220\377\225\225\225\377\244\244\244\377\266\266\266\377\307" - "\307\307\377\325\325\325\377\335\335\335\377\341\341\341\377\343\343\343" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377,\0\377\377" - "\224\0\377\377\224\0\377\377\221\0\377\377\212\0\377\377\200\0\377\377w\0" - "\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377N\0\377\250" - ">(\377QQQ\377QQQ\377SSS\377XXX\377aaa\377mmm\377|||\377\212\212\212\377\225" - "\225\225\377\234\234\234\377\237\237\237\377\240\240\240\377\206\206\206" - "\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377" - "kkk\377kkk\377kkk\377kkk\377\206\206\206\377\206\206\206\377\223\223\223" - "\377\255xm\377\377E\0\377\377\224\0\377\377\224\0\377\377\223\0\377\377\217" - "\0\377\377\206\0\377\377{\0\377\377t\0\377\377q\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377=\0\377|G<\377QQQ\377SSS\377VVV\377]]]\377hhh\377www\377\205" - "\205\205\377\221\221\221\377fff\377NNN\377OOO\377PPP\377PPP\377\223\223\223" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\326\326\326\377\311\311\311\377\274\274\274" - "\377\241\241\241\377\206\206\206\377kkk\377]]]\377PPP\377PPP\377PPP\377\310" - "7\31\377\377Z\0\377\377o\0\377\377o\0\377\3779\0\377oH?\377MMM\377III\377" - "CCC\377fff\377\202\202\202\377\222\222\222\377\221\221\221\377\232\232\232" - "\377\253\253\253\377\275\275\275\377\315\315\315\377\330\330\330\377\337" - "\337\337\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\373" - "\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3778\16\357\377\215\0\377\377\224\0\377\377" - "\221\0\377\377\212\0\377\377\200\0\377\377w\0\377\377r\0\377\377p\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377^\0\377\3235\24\377QQQ\377QQQ\377SSS\377" - "XXX\377aaa\377mmm\377|||\377\212\212\212\377\225\225\225\377\234\234\234" - "\377\237\237\237\377\240\240\240\377\241\241\241\377\241\241\241\377\206" - "\206\206\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377" - "kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377\207_W\377\377?\0\377\377\223\0" - "\377\377\224\0\377\377\223\0\377\377\217\0\377\377\207\0\377\377|\0\377\377" - "t\0\377\377q\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377QQQ" - "\377RRR\377UUU\377\\\\\\\377fff\377ttt\377\203\203\203\377\220\220\220\377" - "fff\377NNN\377OOO\377PPP\377PPP\377\241\241\241\377\326\326\326\377\311\311" - "\311\377\274\274\274\377\241\241\241\377\223\223\223\377\206\206\206\377" - "kkk\377]]]\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377[NK\377\377" - "0\0\377\377o\0\377\377o\0\377\377b\0\377\3363\17\377NNN\377XXX\377\203\203" - "\203\377\244\244\244\377\250\250\250\377\230\230\230\377\221\221\221\377" - "\224\224\224\377\240\240\240\377\261\261\261\377\304\304\304\377\322\322" - "\322\377\333\333\333\377\340\340\340\377\342\342\342\377\343\343\343\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377`>\277\377z\0" - "\377\377\224\0\377\377\221\0\377\377\213\0\377\377\201\0\377\377w\0\377\377" - "r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377^\0\377\3235\24\377" - "QQQ\377QQQ\377SSS\377XXX\377aaa\377mmm\377|||\377\212\212\212\377\225\225" - "\225\377\234\234\234\377\237\237\237\377\240\240\240\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\223\223\223\377\206\206" - "\206\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377kkk\377k" - "kk\377kkk\377kkk\377kkk\377\377,\0\377\377\223\0\377\377\224\0\377\377\223" - "\0\377\377\220\0\377\377\207\0\377\377}\0\377\377u\0\377\377q\0\377\377o" - "\0\377\377o\0\377\377o\0\377\377=\0\377r=2\377CCC\377DDD\377FFF\377KKK\377" - "TTT\377___\377lll\377www\377XXX\377NNN\377OOO\377PPP\377PPP\377]]]\377]]" - "]\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377" - "PPP\377PPP\377PPP\377PPP\377\222B2\377\377E\0\377\377o\0\377\377o\0\377\377" - "I\0\377\272]J\377\250\250\250\377\307\307\307\377\306\306\306\377\264\264" - "\264\377\242\242\242\377\224\224\224\377\221\221\221\377\227\227\227\377" - "\246\246\246\377\270\270\270\377\311\311\311\377\327\327\327\377\336\336" - "\336\377\341\341\341\377\343\343\343\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377mN\257\377s\0\377\377\224\0\377" - "\377\222\0\377\377\213\0\377\377\201\0\377\377x\0\377\377s\0\377\377p\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377,\0\377QQQ\377QQQ\377SSS" - "\377XXX\377```\377mmm\377{{{\377\212\212\212\377\224\224\224\377\233\233" - "\233\377\237\237\237\377\240\240\240\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\223\223" - "\223\377\223\223\223\377\206\206\206\377kkk\377kkk\377kkk\377kkk\377kkk\377" - "kkk\377kkk\377kkk\377kkk\377kkk\377\377,\0\377\377\223\0\377\377\224\0\377" - "\377\224\0\377\377\221\0\377\377\210\0\377\377~\0\377\377u\0\377\377q\0\377" - "\377p\0\377\377o\0\377\377o\0\377\3779\0\377[3+\377666\377666\377888\377" - "<<<\377BBB\377KKK\377UUU\377^^^\377KKK\377NNN\377OOO\377PPP\377PPP\377PP" - "P\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377" - "PPP\377PPP\377PPP\377PPP\377PPP\377\3235\24\377\377^\0\377\377o\0\377\377" - "o\0\377\3770\0\377\342\325\322\377\332\332\332\377\317\317\317\377\277\277" - "\277\377\255\255\255\377\234\234\234\377\222\222\222\377\222\222\222\377" - "\234\234\234\377\255\255\255\377\277\277\277\377\317\317\317\377\331\331" - "\331\377\340\340\340\377\342\342\342\377\343\343\343\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\223}\200\377" - "`\0\377\377\224\0\377\377\222\0\377\377\214\0\377\377\202\0\377\377x\0\377" - "\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\3770\0" - "\377\\OL\377QQQ\377SSS\377XXX\377```\377lll\377zzz\377\211\211\211\377\224" - "\224\224\377\233\233\233\377\236\236\236\377\240\240\240\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\223\223\223\377\206\206\206\377xxx\377kkk\377kkk\377kkk\377kkk\377k" - "kk\377kkk\377\377,\0\377\377\223\0\377\377\224\0\377\377\224\0\377\377\221" - "\0\377\377\211\0\377\377~\0\377\377v\0\377\377q\0\377\377p\0\377\377o\0\377" - "\377o\0\377\377,\0\377555\377666\377666\377888\377;;;\377AAA\377JJJ\377T" - "TT\377]]]\377KKK\377NNN\377OOO\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP" - "\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377]]]\377" - "kkk\377\241\206\201\377\3774\0\377\377o\0\377\377o\0\377\377Z\0\377\366e" - "G\377\336\336\336\377\327\327\327\377\312\312\312\377\271\271\271\377\247" - "\247\247\377\230\230\230\377\221\221\221\377\225\225\225\377\242\242\242" - "\377\264\264\264\377\306\306\306\377\323\323\323\377\334\334\334\377\340" - "\340\340\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\274\254P\377M\0\377\377" - "\224\0\377\377\222\0\377\377\214\0\377\377\202\0\377\377y\0\377\377s\0\377" - "\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377=\0\377|G<\377" - "QQQ\377SSS\377WWW\377___\377kkk\377zzz\377\210\210\210\377\224\224\224\377" - "\233\233\233\377\236\236\236\377\240\240\240\377\240\240\240\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\223\223\223\377\223\223\223\377" - "\206\206\206\377\206\206\206\377xxx\377xxx\377\377,\0\377\377\223\0\377\377" - "\224\0\377\377\224\0\377\377\221\0\377\377\211\0\377\377\177\0\377\377v\0" - "\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377\377,\0\377555\377666\377" - "666\377888\377;;;\377AAA\377III\377TTT\377]]]\377JJJ\377MMM\377OOO\377PP" - "P\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377PPP\377" - "kkk\377\206\206\206\377\241\241\241\377\274\274\274\377\311\311\311\377\344" - "\344\344\377\360\223\200\377\377I\0\377\377o\0\377\377o\0\377\377A\0\377" - "\352\250\232\377\334\334\334\377\323\323\323\377\305\305\305\377\263\263" - "\263\377\241\241\241\377\224\224\224\377\222\222\222\377\231\231\231\377" - "\250\250\250\377\272\272\272\377\313\313\313\377\327\327\327\377\337\337" - "\337\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\324\3110\377" - "@\0\377\377\224\0\377\377\222\0\377\377\215\0\377\377\204\0\377\377z\0\377" - "\377s\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377I\0" - "\377\235@-\377QQQ\377SSS\377VVV\377^^^\377jjj\377yyy\377\207\207\207\377" - "\223\223\223\377\233\233\233\377\236\236\236\377\240\240\240\377\240\240" - "\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\223\223" - "\223\377\377,\0\377\377\223\0\377\377\224\0\377\377\224\0\377\377\221\0\377" - "\377\211\0\377\377~\0\377\377v\0\377\377q\0\377\377p\0\377\377o\0\377\377" - "b\0\377\331.\12\377555\377666\377666\377777\377;;;\377AAA\377III\377SSS\377" - "\\\\\\\377JJJ\377MMM\377OOO\377PPP\377PPP\377PPP\377kkk\377kkk\377\206\206" - "\206\377\223\223\223\377\241\241\241\377\256\256\256\377\274\274\274\377" - "\311\311\311\377\326\326\326\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\374C\35\377\377g\0\377\377o\0\377" - "\377k\0\377\3757\16\377\340\340\340\377\331\331\331\377\317\317\317\377\276" - "\276\276\377\255\255\255\377\234\234\234\377\223\223\223\377\224\224\224" - "\377\236\236\236\377\257\257\257\377\301\301\301\377\320\320\320\377\332" - "\332\332\377\340\340\340\377\342\342\342\377\343\343\343\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377,\0\377\377\224\0\377\377\223\0\377\377\216\0\377\377\206" - "\0\377\377|\0\377\377t\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377R\0\377\262<#\377QQQ\377SSS\377VVV\377]]]\377iii\377www\377" - "\206\206\206\377\222\222\222\377\232\232\232\377\236\236\236\377\240\240" - "\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\377,\0\377\377\223\0\377\377\224\0\377\377\224\0" - "\377\377\221\0\377\377\211\0\377\377~\0\377\377v\0\377\377q\0\377\377p\0" - "\377\377o\0\377\377^\0\377\3202\21\377CCC\377CCC\377DDD\377EEE\377JJJ\377" - "QQQ\377[[[\377hhh\377ttt\377VVV\377MMM\377OOO\377PPP\377PPP\377\223\223\223" - "\377\326\326\326\377\326\326\326\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\351" - "\301\271\377\3779\0\377\377o\0\377\377o\0\377\377R\0\377\362{c\377\336\336" - "\336\377\327\327\327\377\311\311\311\377\270\270\270\377\246\246\246\377" - "\230\230\230\377\222\222\222\377\226\226\226\377\244\244\244\377\266\266" - "\266\377\307\307\307\377\325\325\325\377\335\335\335\377\341\341\341\377" - "\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377`>\277\377z\0" - "\377\377\223\0\377\377\220\0\377\377\210\0\377\377\177\0\377\377v\0\377\377" - "r\0\377\377p\0\377\377o\0\377\377o\0\377\377o\0\377\377b\0\377\3363\17\377" - "QQQ\377SSS\377VVV\377]]]\377hhh\377vvv\377\205\205\205\377\221\221\221\377" - "\231\231\231\377\236\236\236\377\240\240\240\377\240\240\240\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\377,\0\377" - "\377\224\0\377\377\224\0\377\377\224\0\377\377\220\0\377\377\210\0\377\377" - "}\0\377\377u\0\377\377q\0\377\377o\0\377\377o\0\377\377N\0\377\250>(\377" - "PPP\377QQQ\377QQQ\377SSS\377XXX\377aaa\377nnn\377}}}\377\213\213\213\377" - "ccc\377MMM\377OOO\377PPP\377PPP\377\223\223\223\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\363}d\377\377R\0\377\377o\0\377" - "\377o\0\377\3779\0\377\346\276\266\377\334\334\334\377\322\322\322\377\304" - "\304\304\377\262\262\262\377\240\240\240\377\224\224\224\377\223\223\223" - "\377\233\233\233\377\253\253\253\377\275\275\275\377\315\315\315\377\330" - "\330\330\377\337\337\337\377\342\342\342\377\343\343\343\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\373\373\373" - "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\223}\200\377`\0\377\377\224\0\377\377\222" - "\0\377\377\214\0\377\377\202\0\377\377y\0\377\377s\0\377\377p\0\377\377p" - "\0\377\377o\0\377\377o\0\377\377o\0\377\377,\0\377QQQ\377RRR\377UUU\377\\" - "\\\\\377fff\377uuu\377\203\203\203\377\220\220\220\377\231\231\231\377\236" - "\236\236\377\240\240\240\377\240\240\240\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\377,\0\377\377\223\0\377\377" - "\224\0\377\377\223\0\377\377\220\0\377\377\207\0\377\377|\0\377\377u\0\377" - "\377q\0\377\377o\0\377\377o\0\377\377E\0\377\223C3\377PPP\377QQQ\377QQQ\377" - "SSS\377XXX\377aaa\377nnn\377}}}\377\213\213\213\377ccc\377MMM\377OOO\377" - "PPP\377PPP\377\223\223\223\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\3758\16\377\377k\0\377\377o\0\377\377b\0\377\372N+\377" - "\340\340\340\377\331\331\331\377\316\316\316\377\276\276\276\377\254\254" - "\254\377\234\234\234\377\223\223\223\377\224\224\224\377\240\240\240\377" - "\261\261\261\377\303\303\303\377\321\321\321\377\333\333\333\377\340\340" - "\340\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\377\324\3110\377@\0\377\377\224\0\377\377\223\0\377\377\217\0\377" - "\377\207\0\377\377}\0\377\377u\0\377\377q\0\377\377p\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377=\0\377}H=\377RRR\377UUU\377[[[\377eee\377sss\377\201" - "\201\201\377\217\217\217\377\230\230\230\377\235\235\235\377\240\240\240" - "\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\255\222\215\377\3779\0\377\377\224\0\377\377\224\0\377\377\223\0\377" - "\377\217\0\377\377\206\0\377\377|\0\377\377t\0\377\377p\0\377\377o\0\377" - "\377o\0\377\3779\0\377rJB\377PPP\377QQQ\377QQQ\377TTT\377YYY\377bbb\377o" - "oo\377~~~\377\214\214\214\377ddd\377NNN\377OOO\377PPP\377PPP\377\206\206" - "\206\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\354\252\234\377" - "\377A\0\377\377o\0\377\377o\0\377\377I\0\377\356\222~\377\336\336\336\377" - "\326\326\326\377\310\310\310\377\267\267\267\377\245\245\245\377\227\227" - "\227\377\223\223\223\377\230\230\230\377\246\246\246\377\270\270\270\377" - "\311\311\311\377\326\326\326\377\336\336\336\377\341\341\341\377\343\343" - "\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\3778\16\357\377\215\0\377\377\224\0\377\377\221\0\377\377\213\0\377\377" - "\202\0\377\377x\0\377\377s\0\377\377p\0\377\377p\0\377\377o\0\377\377o\0" - "\377\377R\0\377\263<$\377QQQ\377TTT\377ZZZ\377ccc\377ppp\377\200\200\200" - "\377\215\215\215\377\227\227\227\377\235\235\235\377\237\237\237\377\240" - "\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\271" - "\204y\377\377E\0\377\377\224\0\377\377\224\0\377\377\223\0\377\377\216\0" - "\377\377\205\0\377\377z\0\377\377s\0\377\377p\0\377\377o\0\377\377k\0\377" - "\364.\5\377QQQ\377PPP\377QQQ\377QQQ\377TTT\377ZZZ\377bbb\377ppp\377\177\177" - "\177\377\215\215\215\377~~~\377NNN\377OOO\377PPP\377PPP\377kkk\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\367fH\377\377Z\0\377\377o\0\377" - "\377o\0\377\3770\0\377\342\325\322\377\333\333\333\377\321\321\321\377\302" - "\302\302\377\260\260\260\377\237\237\237\377\224\224\224\377\224\224\224" - "\377\234\234\234\377\255\255\255\377\276\276\276\377\317\317\317\377\331" - "\331\331\377\340\340\340\377\342\342\342\377\343\343\343\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377y^\237\377m\0\377" - "\377\224\0\377\377\223\0\377\377\216\0\377\377\206\0\377\377}\0\377\377u" - "\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377\377b\0\377\3363\17\377" - "QQQ\377TTT\377YYY\377bbb\377nnn\377}}}\377\213\213\213\377\226\226\226\377" - "\234\234\234\377\237\237\237\377\240\240\240\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\271\204y\377\377F\0\377\377\224\0\377\377" - "\224\0\377\377\223\0\377\377\215\0\377\377\203\0\377\377y\0\377\377s\0\377" - "\377p\0\377\377o\0\377\377Z\0\377\3108\31\377QQQ\377PPP\377QQQ\377QQQ\377" - "UUU\377ZZZ\377ddd\377rrr\377\200\200\200\377\216\216\216\377~~~\377NNN\377" - "OOO\377PPP\377PPP\377kkk\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\346\330\326" - "\377\3770\0\377\377o\0\377\377o\0\377\377Z\0\377\366eG\377\337\337\337\377" - "\330\330\330\377\315\315\315\377\274\274\274\377\252\252\252\377\233\233" - "\233\377\223\223\223\377\225\225\225\377\242\242\242\377\264\264\264\377" - "\305\305\305\377\323\323\323\377\334\334\334\377\340\340\340\377\343\343" - "\343\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\377\274\254P\377M\0\377\377\224\0\377\377\224\0\377\377" - "\221\0\377\377\213\0\377\377\201\0\377\377y\0\377\377s\0\377\377p\0\377\377" - "p\0\377\377o\0\377\377o\0\377\3774\0\377gLG\377SSS\377XXX\377```\377lll\377" - "zzz\377\211\211\211\377\224\224\224\377\233\233\233\377\236\236\236\377\240" - "\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\312" - "nZ\377\377Y\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\213\0\377" - "\377\200\0\377\377x\0\377\377r\0\377\377p\0\377\377o\0\377\377E\0\377\223" - "C3\377QQQ\377PPP\377QQQ\377RRR\377UUU\377[[[\377eee\377ttt\377\202\202\202" - "\377\217\217\217\377\177\177\177\377NNN\377OOO\377PPP\377PPP\377]]]\377\326" - "\326\326\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\360\223\200\377\377I\0\377\377o\0\377\377o\0" - "\377\377A\0\377\352\250\232\377\335\335\335\377\324\324\324\377\306\306\306" - "\377\266\266\266\377\244\244\244\377\227\227\227\377\223\223\223\377\232" - "\232\232\377\250\250\250\377\272\272\272\377\313\313\313\377\327\327\327" - "\377\337\337\337\377\341\341\341\377\343\343\343\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "8\16\357\377\215\0\377\377\224\0\377\377\223\0\377\377\216\0\377\377\206" - "\0\377\377}\0\377\377u\0\377\377q\0\377\377p\0\377\377o\0\377\377o\0\377" - "\377I\0\377\235A-\377SSS\377VVV\377^^^\377jjj\377xxx\377\206\206\206\377" - "\222\222\222\377\232\232\232\377\236\236\236\377\240\240\240\377\240\240" - "\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\320fP\377\377`\0\377\377" - "\224\0\377\377\223\0\377\377\217\0\377\377\207\0\377\377}\0\377\377v\0\377" - "\377q\0\377\377p\0\377\377o\0\377\3770\0\377\\OL\377QQQ\377PPP\377QQQ\377" - "RRR\377VVV\377\\\\\\\377ggg\377uuu\377\204\204\204\377\221\221\221\377\214" - "\214\214\377NNN\377OOO\377PPP\377PPP\377PPP\377\311\311\311\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\372O+\377\377b\0\377\377o\0\377\377k\0\377\3757\16\377\340\340\340\377" - "\332\332\332\377\320\320\320\377\301\301\301\377\256\256\256\377\236\236" - "\236\377\224\224\224\377\224\224\224\377\236\236\236\377\257\257\257\377" - "\301\301\301\377\320\320\320\377\332\332\332\377\340\340\340\377\342\342" - "\342\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\373\373\373\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\223}\200\377`\0\377\377\224" - "\0\377\377\224\0\377\377\221\0\377\377\212\0\377\377\201\0\377\377x\0\377" - "\377s\0\377\377p\0\377\377p\0\377\377o\0\377\377b\0\377\3363\17\377RRR\377" - "VVV\377\\\\\\\377hhh\377uuu\377\203\203\203\377\220\220\220\377\231\231\231" - "\377\236\236\236\377\240\240\240\377\240\240\240\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\342Q3\377\377s\0\377\377\224\0\377\377\221\0\377\377" - "\214\0\377\377\203\0\377\377y\0\377\377t\0\377\377p\0\377\377o\0\377\377" - "Z\0\377\3119\32\377QQQ\377QQQ\377PPP\377QQQ\377SSS\377VVV\377]]]\377iii\377" - "www\377\206\206\206\377\222\222\222\377\232\232\232\377[[[\377OOO\377PPP" - "\377PPP\377PPP\377\274\274\274\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\351\301\271\377\3779\0\377\377o\0\377\377" - "o\0\377\377R\0\377\362{c\377\337\337\337\377\327\327\327\377\313\313\313" - "\377\272\272\272\377\250\250\250\377\232\232\232\377\223\223\223\377\227" - "\227\227\377\245\245\245\377\266\266\266\377\307\307\307\377\325\325\325" - "\377\335\335\335\377\341\341\341\377\343\343\343\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\377\337\327\40\3779\0\377\377\224\0\377\377\224\0\377\377\223" - "\0\377\377\216\0\377\377\206\0\377\377}\0\377\377u\0\377\377q\0\377\377p" - "\0\377\377o\0\377\377o\0\377\3779\0\377sKC\377UUU\377[[[\377ddd\377rrr\377" - "\201\201\201\377\216\216\216\377\227\227\227\377\235\235\235\377\237\237" - "\237\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\355B\36" - "\377\377\200\0\377\377\223\0\377\377\217\0\377\377\207\0\377\377~\0\377\377" - "w\0\377\377r\0\377\377p\0\377\377o\0\377\377A\0\377\212G:\377QQQ\377QQQ\377" - "QQQ\377QQQ\377SSS\377WWW\377___\377kkk\377zzz\377\210\210\210\377\224\224" - "\224\377\233\233\233\377iii\377PPP\377PPP\377PPP\377PPP\377\241\241\241\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\363}d\377\377R\0\377\377o\0\377\377o\0\377\3779\0\377\346\276\266\377\334" - "\334\334\377\323\323\323\377\305\305\305\377\264\264\264\377\242\242\242" - "\377\226\226\226\377\224\224\224\377\234\234\234\377\253\253\253\377\275" - "\275\275\377\315\315\315\377\330\330\330\377\337\337\337\377\342\342\342" - "\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\373" - "\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\373w\\\242\377" - "m\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\213\0\377\377\201\0" - "\377\377y\0\377\377s\0\377\377p\0\377\377p\0\377\377o\0\377\377V\0\377\275" - ":\36\377TTT\377YYY\377bbb\377nnn\377}}}\377\213\213\213\377\225\225\225\377" - "\234\234\234\377\237\237\237\377\240\240\240\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\377,\0\377\377\224\0\377\377\222\0\377\377\214\0\377\377" - "\203\0\377\377z\0\377\377t\0\377\377q\0\377\377o\0\377\377g\0\377\3522\13" - "\377TTT\377QQQ\377QQQ\377QQQ\377QQQ\377TTT\377YYY\377aaa\377nnn\377|||\377" - "\212\212\212\377\225\225\225\377\234\234\234\377jjj\377PPP\377PPP\377PPP" - "\377PPP\377\206\206\206\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\3758\16\377\377k\0\377\377o\0\377\377b\0\377\372" - "N+\377\340\340\340\377\331\331\331\377\317\317\317\377\276\276\276\377\255" - "\255\255\377\234\234\234\377\224\224\224\377\225\225\225\377\240\240\240" - "\377\261\261\261\377\303\303\303\377\321\321\321\377\333\333\333\377\340" - "\340\340\377\342\342\342\377\343\343\343\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\367\333\333$\3779\0\377\377\224\0\377\377\224\0\377\377\223" - "\0\377\377\216\0\377\377\206\0\377\377}\0\377\377u\0\377\377q\0\377\377p" - "\0\377\377o\0\377\377k\0\377\3652\5\377^QN\377XXX\377___\377kkk\377yyy\377" - "\210\210\210\377\223\223\223\377\232\232\232\377\236\236\236\377\240\240" - "\240\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241" - "\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377" - "\241\241\241\377\241\241\241\377\271\204y\377\377F\0\377\377\223\0\377\377" - "\220\0\377\377\210\0\377\377\177\0\377\377w\0\377\377r\0\377\377p\0\377\377" - "o\0\377\377N\0\377\254B,\377SSS\377QQQ\377QQQ\377QQQ\377RRR\377UUU\377ZZ" - "Z\377ddd\377rrr\377\200\200\200\377\215\215\215\377\227\227\227\377\235\235" - "\235\377\204\204\204\377PPP\377PPP\377PPP\377PPP\377kkk\377\326\326\326\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\354\252\234\377\377A\0\377\377o" - "\0\377\377o\0\377\377I\0\377\356\222~\377\336\336\336\377\326\326\326\377" - "\311\311\311\377\270\270\270\377\246\246\246\377\230\230\230\377\224\224" - "\224\377\230\230\230\377\246\246\246\377\270\270\270\377\311\311\311\377" - "\326\326\326\377\336\336\336\377\341\341\341\377\343\343\343\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\373\373\373\377" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\277\277\4\373x]\243" - "\377m\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\213\0\377\377\202" - "\0\377\377y\0\377\377t\0\377\377p\0\377\377p\0\377\377o\0\377\377N\0\377" - "\251?)\377VVV\377]]]\377hhh\377uuu\377\204\204\204\377\220\220\220\377\231" - "\231\231\377\235\235\235\377\240\240\240\377\240\240\240\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\320" - "fP\377\377`\0\377\377\222\0\377\377\215\0\377\377\204\0\377\377{\0\377\377" - "t\0\377\377q\0\377\377o\0\377\377k\0\377\3663\6\377bUR\377SSS\377QQQ\377" - "QQQ\377QQQ\377SSS\377VVV\377]]]\377ggg\377uuu\377\203\203\203\377\220\220" - "\220\377\231\231\231\377\235\235\235\377\222\222\222\377PPP\377PPP\377PP" - "P\377PPP\377PPP\377\311\311\311\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\367fH\377\377Z\0\377\377o\0\377\377o\0\377\3770\0\377\342\325\322\377\333" - "\333\333\377\322\322\322\377\303\303\303\377\261\261\261\377\240\240\240" - "\377\225\225\225\377\224\224\224\377\234\234\234\377\255\255\255\377\276" - "\276\276\377\317\317\317\377\331\331\331\377\340\340\340\377\342\342\342" - "\377\343\343\343\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\252\252\252\3\370\336\327'\3779\0\377\377\224\0\377\377\224\0\377\377" - "\223\0\377\377\217\0\377\377\207\0\377\377~\0\377\377w\0\377\377r\0\377\377" - "p\0\377\377o\0\377\377k\0\377\3652\5\377`RP\377[[[\377ddd\377qqq\377\200" - "\200\200\377\215\215\215\377\226\226\226\377\234\234\234\377\237\237\237" - "\377\240\240\240\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\347I(\377\377z\0\377\377\221\0\377\377\212\0" - "\377\377\200\0\377\377x\0\377\377s\0\377\377p\0\377\377o\0\377\377N\0\377" - "\257E/\377WWW\377SSS\377QQQ\377QQQ\377QQQ\377SSS\377XXX\377___\377kkk\377" - "yyy\377\207\207\207\377\222\222\222\377\232\232\232\377\236\236\236\377\222" - "\222\222\377]]]\377PPP\377PPP\377PPP\377PPP\377\274\274\274\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\347\315\307\377\3774\0\377\377o\0\377\377o\0\377\377Z\0\377" - "\366eG\377\337\337\337\377\330\330\330\377\315\315\315\377\275\275\275\377" - "\253\253\253\377\234\234\234\377\224\224\224\377\226\226\226\377\242\242" - "\242\377\264\264\264\377\305\305\305\377\323\323\323\377\334\334\334\377" - "\340\340\340\377\343\343\343\377\343\343\343\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377" - "\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\373\373\373\377\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\177\177\2\324\324\324\6\371\220y\210" - "\377`\0\377\377\224\0\377\377\224\0\377\377\222\0\377\377\214\0\377\377\204" - "\0\377\377{\0\377\377u\0\377\377r\0\377\377p\0\377\377o\0\377\377N\0\377" - "\252@*\377XXX\377aaa\377mmm\377{{{\377\210\210\210\377\224\224\224\377\233" - "\233\233\377\236\236\236\377\240\240\240\377\240\240\240\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241" - "\241\241\377\241\241\241\377\241\241\241\377\241\241\241\377\241\241\241" - "\377\241\241\241\377\241\241\241\377\247\232\227\377\3773\0\377\377\223\0" - "\377\377\217\0\377\377\207\0\377\377}\0\377\377u\0\377\377q\0\377\377p\0" - "\377\377g\0\377\3544\15\377^^^\377VVV\377SSS\377QQQ\377QQQ\377RRR\377UUU" - "\377ZZZ\377bbb\377ooo\377~~~\377\213\213\213\377\225\225\225\377\233\233" - "\233\377\237\237\237\377\240\240\240\377kkk\377PPP\377PPP\377PPP\377PPP\377" - "\223\223\223\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344" - "\344\377\344\344\344\377\344\344\344\377\360\223\200\377\377I\0\377\377o" - "\0\377\377o\0\377\377A\0\377\352\250\232\377\335\335\335\377\325\325\325" - "\377\307\307\307\377\266\266\266\377\245\245\245\377\227\227\227\377\224" - "\224\224\377\232\232\232\377\250\250\250\377\273\273\273\377\313\313\313" - "\377\327\327\327\377\337\337\337\377\341\341\341\377\343\343\343\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344" - "\344\344\377\344\344\344\377\344\344\344\377\344\344\344\377\344\344\344" - "\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\1\277\277\277\4\365\342\342\33\374H\33\342\377\207\0\377\377\224\0\377" - "\377\223\0\377\377\220\0\377\377\212\0\377\377\201\0\377\377z\0\377\377t" - "\0\377\377q\0\377\377p\0\377\377k\0\377\3674\7\377xkh\377xxx\377\206\206" - "\206\377\227\227\227\377\251\251\251\377\270\270\270\377\303\303\303\377" - "\312\312\312\377\314\314\314\377\316\316\316\377\316\316\316\377\316\316" - "\316\377\316\316\316\377\316\316\316\377\316\316\316\377\316\316\316\377" - "\316\316\316\377\316\316\316\377\316\316\316\377\316\316\316\377\316\316" - "\316\377\316\316\316\377\341\221\201\377\377S\0\377\377\222\0\377\377\214" - "\0\377\377\202\0\377\377y\0\377\377s\0\377\377p\0\377\377o\0\377\377A\0\377" - "\254i\\\377www\377nnn\377jjj\377hhh\377hhh\377jjj\377nnn\377www\377\204\204" - "\204\377\225\225\225\377\246\246\246\377\267\267\267\377\302\302\302\377" - "\311\311\311\377\314\314\314\377\316\316\316\377\247\247\247\377PPP\377P" - "PP\377PPP\377PPP\377kkk\377\373\373\373\377\373\373\373\377\373\373\373\377" - "\373\373\373\377\373\373\373\377\373\373\373\377\376F\37\377\377g\0\377\377" - "o\0\377\377k\0\377\3779\20\377\366\366\366\377\360\360\360\377\345\345\345" - "\377\325\325\325\377\301\301\301\377\256\256\256\377\243\243\243\377\243" - "\243\243\377\256\256\256\377\301\301\301\377\325\325\325\377\345\345\345" - "\377\360\360\360\377\366\366\366\377\371\371\371\377\372\372\372\377\373" - "\373\373\377\373\373\373\377\373\373\373\377\373\373\373\377\373\373\373" - "\377\373\373\373\377\373\373\373\377\373\373\373\377\373\373\373\377\373" - "\373\373\377\373\373\373\377\373\373\373\377\373\373\373\377\373\373\373" - "\377\373\373\373\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\1\252\252\252\3\337\337\337\10\365\301\267O\377F\0\377\377\224\0\377\377" - "\224\0\377\377\223\0\377\377\216\0\377\377\210\0\377\377\177\0\377\377x\0" - "\377\377s\0\377\377q\0\377\377p\0\377\377Z\0\377\330G)\372\217\217\217\336" - "\236\236\236\300\261\261\261\230\310\310\310k\334\334\334C\351\351\351$\360" - "\360\360\21\332\332\332\7\177\177\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377S.\317" - "\377\200\0\377\377\220\0\377\377\210\0\377\377~\0\377\377v\0\377\377r\0\377" - "\377p\0\377\377Z\0\377\350W9\333\241\241\241\271\220\220\220\333\206\206" - "\206\357\201\201\201\371\200\200\200\374\200\200\200\373\204\204\204\364" - "\213\213\213\346\227\227\227\315\250\250\250\251\276\276\276~\323\323\323" - "R\343\343\343.\363\363\363\26\342\342\342\11\252\252\252\3\0\0\0\1\277\277" - "\277\4PPP\377PPP\377PPP\377PPP\377PPP\377\277\277\277\4\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\377\307\273@\377=\0\377\377o\0\377\377o\0\377\377V\0\377\375" - "y]\241\351\351\351\14\355\355\355\35\337\337\3378\317\317\317\\\273\273\273" - "\205\252\252\252\246\244\244\244\264\250\250\250\253\267\267\267\216\310" - "\310\310g\333\333\333@\350\350\350\"\357\357\357\20\324\324\324\6\177\177" - "\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\177\177\2\314\314\314" - "\5\354\354\354\16\366\201g\235\377f\0\377\377\224\0\377\377\224\0\377\377" - "\222\0\377\377\215\0\377\377\206\0\377\377~\0\377\377w\0\377\377s\0\377\377" - "q\0\377\377p\0\377\377=\0\377\250sh\354\227\227\227\315\252\252\252\250\277" - "\277\277}\323\323\323R\343\343\343/\350\350\350\27\345\345\345\12\277\277" - "\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\307\273@\377F\0\377\377\222\0\377\377\215\0\377" - "\377\203\0\377\377z\0\377\377t\0\377\377q\0\377\377l\0\377\3739\13\366\267" - "\252\250\235\236\236\236\300\216\216\216\337\205\205\205\361\201\201\201" - "\372\200\200\200\374\201\201\201\371\206\206\206\357\217\217\217\335\236" - "\236\236\300\261\261\261\230\310\310\310l\334\334\334C\351\351\351$\360\360" - "\360\21\332\332\332\7\177\177\177\2\0\0\0\1\0\0\0\0jjj\224PPP\377PPP\377" - "PPP\377PPP\377\337\337\337\30\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377y^\237\377" - "V\0\377\377o\0\377\377o\0\377\3779\0\377\372\317\3136\360\360\360\21\352" - "\352\352%\332\332\332E\310\310\310l\264\264\264\223\247\247\247\256\244\244" - "\244\264\255\255\255\242\275\275\275\200\320\320\320W\341\341\3413\353\353" - "\353\32\347\347\347\13\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\1\252\252\252\3\345\345\345\12\350\350\350\27\372O+\330" - "\377\200\0\377\377\224\0\377\377\224\0\377\377\221\0\377\377\214\0\377\377" - "\205\0\377\377}\0\377\377w\0\377\377s\0\377\377p\0\377\377l\0\377\3675\7" - "\376\231\214\210\332\242\242\242\270\265\265\265\217\314\314\314d\335\335" - "\335=\347\347\347!\356\356\356\17\324\324\324\6\177\177\177\2\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" - "`>\277\377y\0\377\377\217\0\377\377\210\0\377\377~\0\377\377w\0\377\377s" - "\0\377\377p\0\377\377=\0\377\322\235\223\225\256\256\256\237\231\231\231" - "\307\214\214\214\344\204\204\204\363\201\201\201\372\201\201\201\372\203" - "\203\203\365\212\212\212\350\224\224\224\321\246\246\246\257\273\273\273" - "\205\321\321\321Z\342\342\3425\354\354\354\33\351\351\351\14\277\277\277" - "\4\0\0\0\1\0\0\0\0\0\0\0\0\312\312\3121PPP\377PPP\377PPP\377PPP\377\245\245" - "\245X\0\0\0\0\0\0\0\0\0\0\0\0\377\357\337\20\3770\0\377\377o\0\377\377o\0" - "\377\377g\0\377\377E\36\337\345\345\345\12\351\351\351\30\344\344\3440\323" - "\323\323S\300\300\300{\256\256\256\237\243\243\243\263\246\246\246\260\261" - "\261\261\227\304\304\304q\330\330\330I\345\345\345(\361\361\361\23\337\337" - "\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\177\177\177\2\324\324\324\6\356\356\356\17\356\336\336/\374<\14\363" - "\377\215\0\377\377\224\0\377\377\223\0\377\377\221\0\377\377\214\0\377\377" - "\204\0\377\377}\0\377\377w\0\377\377s\0\377\377p\0\377\377_\0\377\342D#\370" - "\231\231\231\307\255\255\255\242\303\303\303w\327\327\327N\342\342\342-\363" - "\363\363\26\345\345\345\12\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\257\234`\377S\0\377\377\220" - "\0\377\377\212\0\377\377\202\0\377\377y\0\377\377t\0\377\377p\0\377\377J" - "\0\377\350\212x\234\277\277\277|\250\250\250\251\226\226\226\317\212\212" - "\212\350\203\203\203\365\201\201\201\372\202\202\202\370\206\206\206\357" - "\217\217\217\336\235\235\235\302\260\260\260\234\304\304\304q\330\330\330" - "I\346\346\346)\361\361\361\23\337\337\337\10\252\252\252\3\0\0\0\1\0\0\0" - "\0\0\0\0\0\277\277\277\4PPP\377PPP\377PPP\377PPP\377PPP\377\0\0\0\1\0\0\0" - "\0\0\0\0\0\377\241\215p\377I\0\377\377o\0\377\377o\0\377\377I\0\377\374\237" - "\213s\354\354\354\16\347\347\347\40\335\335\335<\313\313\313c\270\270\270" - "\212\250\250\250\251\243\243\243\265\250\250\250\251\270\270\270\212\315" - "\315\315b\335\335\335<\356\356\356\37\354\354\354\16\314\314\314\5\177\177" - "\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\277" - "\277\277\4\345\345\345\12\350\350\350\27\352\303\272U\374F\12\364\377\215" - "\0\377\377\224\0\377\377\223\0\377\377\221\0\377\377\213\0\377\377\204\0" - "\377\377}\0\377\377v\0\377\377s\0\377\377p\0\377\377V\0\377\326R7\357\244" - "\244\244\264\267\267\267\214\315\315\315a\335\335\335<\347\347\347\40\356" - "\356\356\17\324\324\324\6\177\177\177\2\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\377\357\337\20\377>\16\357\377\212\0\377\377\213\0" - "\377\377\203\0\377\377|\0\377\377u\0\377\377r\0\377\377V\0\377\363pU\263" - "\321\321\321Z\271\271\271\210\244\244\244\264\223\223\223\326\210\210\210" - "\354\203\203\203\366\202\202\202\370\204\204\204\364\211\211\211\347\226" - "\226\226\320\246\246\246\257\273\273\273\207\315\315\315]\337\337\3378\356" - "\356\356\36\353\353\353\15\314\314\314\5\177\177\177\2\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0jjj\224PPP\377PPP\377PPP\377PPP\377\332\332\332#\0\0\0\0\0" - "\0\0\0\377E\36\337\377g\0\377\377o\0\377\377o\0\377\3774\0\377\370\336\327" - "'\362\362\362\24\346\346\346*\331\331\331J\304\304\304r\261\261\261\230\245" - "\245\245\261\244\244\244\264\256\256\256\237\300\300\300{\323\323\323S\344" - "\344\3440\350\350\350\27\345\345\345\12\252\252\252\3\0\0\0\1\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\177\177\2\324\324" - "\324\6\356\356\356\17\347\347\347!\344\275\265a\374F\12\365\377\215\0\377" - "\377\224\0\377\377\223\0\377\377\221\0\377\377\213\0\377\377\204\0\377\377" - "|\0\377\377v\0\377\377r\0\377\377p\0\377\377V\0\377\331V:\351\254\254\254" - "\241\303\303\303w\325\325\325O\343\343\343.\351\351\351\30\347\347\347\13" - "\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\357\337" - "\20\377V,\317\377z\0\377\377\210\0\377\377\203\0\377\377|\0\377\377v\0\377" - "\377s\0\377\377V\0\377\367tY\253\336\336\336?\311\311\311h\263\263\263\225" - "\237\237\237\276\217\217\217\335\206\206\206\357\203\203\203\366\203\203" - "\203\365\207\207\207\355\220\220\220\333\236\236\236\277\261\261\261\232" - "\306\306\306p\330\330\330I\346\346\346*\362\362\362\24\342\342\342\11\252" - "\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\332\332\332#PPP\377PP" - "P\377PPP\377PPP\377jjj\224\0\0\0\0\377\274\254P\377A\0\377\377o\0\377\377" - "o\0\377\377Z\0\377\375lN\260\351\351\351\14\354\354\354\33\342\342\3425\321" - "\321\321Z\274\274\274\202\254\254\254\244\243\243\243\265\246\246\246\257" - "\264\264\264\224\310\310\310l\332\332\332E\352\352\352%\360\360\360\21\332" - "\332\332\7\177\177\177\2\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\277\277\277\4\345\345\345\12\363\363\363" - "\26\347\347\347,\336\266\257m\373F\11\366\377\215\0\377\377\224\0\377\377" - "\223\0\377\377\220\0\377\377\212\0\377\377\203\0\377\377{\0\377\377u\0\377" - "\377r\0\377\377p\0\377\377V\0\377\347I'\354\300\246\237\233\314\314\314d" - "\336\336\336?\351\351\351#\360\360\360\21\337\337\337\10\252\252\252\3\0" - "\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\377\357\337\20\377U,\317\377q\0\377\377\201" - "\0\377\377\177\0\377\377z\0\377\377v\0\377\377s\0\377\377V\0\377\372u[\247" - "\346\346\346*\326\326\326L\303\303\303w\254\254\254\243\231\231\231\311\214" - "\214\214\344\205\205\205\362\203\203\203\365\206\206\206\360\215\215\215" - "\342\230\230\230\312\250\250\250\251\274\274\274\202\321\321\321Y\342\342" - "\3426\355\355\355\35\353\353\353\15\314\314\314\5\177\177\177\2\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\277\277\4PPP\377PPP\377PPP\377PPP\377" - "PPP\377\342\342\342\11\377`>\277\377^\0\377\377o\0\377\377o\0\377\377E\0" - "\377\374\255\233d\360\360\360\21\351\351\351$\334\334\334B\307\307\307j\265" - "\265\265\221\246\246\246\255\243\243\243\266\251\251\251\247\272\272\272" - "\206\315\315\315]\337\337\3378\355\355\355\35\351\351\351\14\314\314\314" - "\5\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\1\177\177\177\2\324\324\324\6\354\354\354\16\356\356\356" - "\36\336\336\3367\330\260\252x\372:\12\367\377z\0\377\377\224\0\377\377\223" - "\0\377\377\220\0\377\377\211\0\377\377\202\0\377\377z\0\377\377u\0\377\377" - "r\0\377\377p\0\377\377^\0\377\372;\11\371\336t_\276\324\311\304`\341\341" - "\3414\354\354\354\34\354\354\354\16\324\324\324\6\177\177\177\2\0\0\0\1\0" - "\0\0\0\377\257\234`\377<\16\357\377h\0\377\377x\0\377\377x\0\377\377w\0\377" - "\377t\0\377\377r\0\377\377F\0\377\373w[\244\355\355\355\35\336\336\3367\317" - "\317\317\\\271\271\271\210\244\244\244\262\223\223\223\324\211\211\211\351" - "\205\205\205\362\205\205\205\361\211\211\211\347\223\223\223\324\243\243" - "\243\266\265\265\265\221\311\311\311i\331\331\331D\352\352\352&\361\361\361" - "\23\337\337\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0jjj\224PPP\377PPP\377PPP\377PPP\377\253\236\231b\3770\0\377" - "\377o\0\377\377o\0\377\377k\0\377\3778\16\357\345\345\345\12\350\350\350" - "\27\343\343\343/\322\322\322Q\300\300\300z\257\257\257\236\244\244\244\264" - "\244\244\244\264\257\257\257\235\303\303\303w\325\325\325O\342\342\342-\363" - "\363\363\26\342\342\342\11\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\252\252" - "\252\3\337\337\337\10\361\361\361\23\352\352\352&\334\334\334B\314\301\274" - "p\354N-\342\377Z\0\377\377\215\0\377\377\222\0\377\377\217\0\377\377\211" - "\0\377\377\200\0\377\377x\0\377\377s\0\377\377p\0\377\377p\0\377\377k\0\377" - "\377N\0\377\3739\13\366\357lP\272\361\226\201\210\365\300\263Q\367\302\270" - "H\373\270\254S\377\210o\220\377E\36\337\377F\0\377\377m\0\377\377r\0\377" - "\377s\0\377\377s\0\377\377r\0\377\377d\0\377\3779\0\377\372\254\233f\362" - "\362\362\24\345\345\345(\327\327\327G\305\305\305o\261\261\261\232\235\235" - "\235\301\217\217\217\335\210\210\210\354\206\206\206\360\211\211\211\352" - "\221\221\221\331\236\236\236\300\257\257\257\235\302\302\302v\325\325\325" - "P\344\344\3441\353\353\353\32\351\351\351\14\314\314\314\5\0\0\0\1\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\337\337\337\30PPP\377" - "PPP\377PPP\377PPP\377|G<\377\377=\0\377\377o\0\377\377o\0\377\377V\0\377" - "\375y]\241\354\354\354\16\356\356\356\37\335\335\335<\315\315\315a\270\270" - "\270\212\251\251\251\252\241\241\241\267\247\247\247\256\266\266\266\220" - "\311\311\311h\333\333\333A\351\351\351#\357\357\357\20\324\324\324\6\177" - "\177\177\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\177\177\2\314\314\314\5\347\347\347" - "\13\352\352\352\31\343\343\343.\326\326\326L\304\304\304q\322uc\305\371>" - "\10\373\377m\0\377\377\222\0\377\377\216\0\377\377\206\0\377\377}\0\377\377" - "u\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377\377k\0\377\377V\0\377" - "\377I\0\377\377=\0\377\377=\0\377\377A\0\377\377R\0\377\377g\0\377\377o\0" - "\377\377p\0\377\377p\0\377\377p\0\377\377l\0\377\377N\0\377\377S/\320\372" - "\317\3136\356\356\356\17\356\356\356\37\337\337\3378\317\317\317[\273\273" - "\273\205\246\246\246\255\227\227\227\316\214\214\214\343\207\207\207\355" - "\211\211\211\352\217\217\217\335\233\233\233\306\251\251\251\247\275\275" - "\275\201\317\317\317\\\340\340\340:\347\347\347!\357\357\357\20\332\332\332" - "\7\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\\\\\\\242PPP\377PPP\377PPP\377qIA\377\3735\14\362\377,\0" - "\377\377,\0\377\375lN\260\363\350\350\27\362\362\362\24\346\346\346)\331" - "\331\331J\304\304\304r\261\261\261\230\244\244\244\262\241\241\241\267\253" - "\253\253\245\274\274\274\202\321\321\321Y\341\341\3414\354\354\354\33\347" - "\347\347\13\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177" - "\177\2\324\324\324\6\356\356\356\17\356\356\356\36\342\342\3426\322\322\322" - "U\301\301\301y\272\237\231\252\332W;\347\3779\0\377\377k\0\377\377\212\0" - "\377\377\200\0\377\377x\0\377\377r\0\377\377p\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0" - "\377\377o\0\377\377o\0\377\377o\0\377\377g\0\377\377N\0\377\377;\16\357\375" - "\222|\201\332\332\332\7\353\353\353\15\353\353\353\32\343\343\343/\327\327" - "\327M\303\303\303s\260\260\260\233\236\236\236\277\221\221\221\331\211\211" - "\211\347\212\212\212\350\217\217\217\336\230\230\230\312\246\246\246\255" - "\270\270\270\212\311\311\311e\334\334\334C\344\344\344'\362\362\362\25\342" - "\342\342\11\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\312\312\3121PPP\377PPP\377PPP\377PPP\377" - "PPP\377\0\0\0\1\0\0\0\1\277\277\277\4\351\351\351\14\354\354\354\33\342\342" - "\3425\321\321\321Y\274\274\274\202\253\253\253\245\241\241\241\267\243\243" - "\243\263\260\260\260\231\304\304\304r\331\331\331J\346\346\346)\362\362\362" - "\24\337\337\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\1\252\252\252\3\337\337\337\10\360\360\360\22\351\351\351#\335\335" - "\335<\317\317\317[\276\276\276\177\255\255\255\242\252\216\212\310\325Q6" - "\360\3772\0\377\377L\0\377\377[\0\377\377j\0\377\377p\0\377\377o\0\377\377" - "o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377\377o\0\377" - "\377o\0\377\377g\0\377\377R\0\377\377A\0\377\377E\37\340\375\223}\202\363" - "\347\347\26\342\342\342\11\356\356\356\17\352\352\352\31\347\347\347+\332" - "\332\332E\310\310\310g\266\266\266\215\245\245\245\261\227\227\227\316\216" - "\216\216\340\214\214\214\344\217\217\217\336\230\230\230\314\245\245\245" - "\261\266\266\266\220\310\310\310l\330\330\330I\342\342\342-\352\352\352\31" - "\351\351\351\14\314\314\314\5\177\177\177\2\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1PPP\377PPP\377" - "PPP\377PPP\377PPP\377\272\272\272C\177\177\177\2\324\324\324\6\357\357\357" - "\20\351\351\351#\333\333\333A\311\311\311h\266\266\266\220\246\246\246\255" - "\242\242\242\270\250\250\250\253\267\267\267\213\313\313\313c\335\335\335" - "=\347\347\347\40\354\354\354\16\314\314\314\5\177\177\177\2\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\177\177\177\2\277\277\277\4\345\345\345" - "\12\362\362\362\25\344\344\344'\333\333\333@\316\316\316_\274\274\274\202" - "\254\254\254\243\235\235\235\301\231\214\210\332\265fV\361\320L1\372\356" - "5\17\376\3775\0\377\377=\0\377\377E\0\377\377N\0\377\377N\0\377\377N\0\377" - "\377N\0\377\377A\0\377\377=\0\377\3770\0\377\374D\35\343\371\202i\230\371" - "\266\250[\354\354\354\16\353\353\353\15\356\356\356\17\362\362\362\25\356" - "\356\356\36\342\342\342-\331\331\331D\315\315\315a\273\273\273\204\252\252" - "\252\246\234\234\234\304\221\221\221\327\216\216\216\337\220\220\220\333" - "\227\227\227\313\244\244\244\262\265\265\265\222\306\306\306p\327\327\327" - "N\344\344\3441\354\354\354\34\354\354\354\16\324\324\324\6\177\177\177\2" - "\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\271\271\271BPPP\377PPP\377PPP\377PPP\377\272\272" - "\272C\177\177\177\2\337\337\337\10\362\362\362\24\346\346\346*\326\326\326" - "K\303\303\303s\260\260\260\231\246\246\246\260\244\244\244\262\257\257\257" - "\236\300\300\300{\323\323\323S\344\344\3440\351\351\351\30\345\345\345\12" - "\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\1\177\177\177\2\314\314\314\5\351\351\351\14\350\350\350\27\346\346" - "\346)\334\334\334B\315\315\315a\274\274\274\202\254\254\254\243\236\236\236" - "\277\223\223\223\325\213\213\213\345\206\206\206\357\223xs\365\243nc\367" - "\263dS\365\305[E\362\312`J\350\320fO\334\327lW\316\323\221\202\246\331\243" - "\230\211\330\314\311V\337\337\3378\347\347\347+\351\351\351#\356\356\356" - "\37\356\356\356\37\350\350\350\"\346\346\346*\336\336\3367\331\331\331J\314" - "\314\314d\274\274\274\202\254\254\254\241\237\237\237\275\226\226\226\320" - "\221\221\221\331\223\223\223\326\232\232\232\310\245\245\245\261\264\264" - "\264\223\304\304\304q\322\322\322Q\341\341\3414\356\356\356\37\357\357\357" - "\20\332\332\332\7\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\277\277" - "\4PPP\377PPP\377\271\271\271B\277\277\277\4\0\0\0\1\252\252\252\3\342\342" - "\342\11\350\350\350\27\343\343\343/\322\322\322Q\301\301\301x\260\260\260" - "\231\251\251\251\252\253\253\253\245\266\266\266\215\311\311\311i\334\334" - "\334C\352\352\352%\360\360\360\21\332\332\332\7\177\177\177\2\0\0\0\1\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177\177" - "\2\324\324\324\6\353\353\353\15\351\351\351\30\346\346\346*\334\334\334B" - "\314\314\314`\275\275\275\200\256\256\256\237\241\241\241\272\226\226\226" - "\320\216\216\216\340\210\210\210\353\205\205\205\361\205\205\205\361\207" - "\207\207\355\215\215\215\342\225\225\225\322\240\240\240\274\254\254\254" - "\243\270\270\270\212\304\304\304r\316\316\316^\327\327\327N\331\331\331D" - "\336\336\336>\335\335\335=\333\333\333A\326\326\326K\321\321\321Z\305\305" - "\305o\273\273\273\207\254\254\254\241\241\241\241\271\230\230\230\312\225" - "\225\225\322\226\226\226\320\234\234\234\303\246\246\246\255\266\266\266" - "\220\306\306\306p\322\322\322Q\342\342\3425\347\347\347\40\360\360\360\21" - "\337\337\337\10\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\356\356\356\17\277\277\277\4\0\0\0\0\0\0\0\0\0\0\0\1\252\252\252\3\345" - "\345\345\12\350\350\350\27\343\343\343/\325\325\325O\304\304\304r\267\267" - "\267\216\260\260\260\231\265\265\265\217\301\301\301u\324\324\324T\341\341" - "\3413\354\354\354\33\351\351\351\14\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\252\252" - "\252\3\324\324\324\6\353\353\353\15\351\351\351\30\346\346\346)\333\333\333" - "A\315\315\315]\300\300\300{\261\261\261\230\244\244\244\262\232\232\232\310" - "\221\221\221\331\214\214\214\344\210\210\210\353\207\207\207\355\211\211" - "\211\352\215\215\215\341\223\223\223\324\234\234\234\303\246\246\246\257" - "\261\261\261\232\271\271\271\210\301\301\301x\307\307\307n\310\310\310g\312" - "\312\312f\310\310\310k\303\303\303t\274\274\274\202\264\264\264\224\251\251" - "\251\247\241\241\241\271\233\233\233\306\230\230\230\314\231\231\231\307" - "\241\241\241\272\253\253\253\245\270\270\270\212\310\310\310l\325\325\325" - "O\342\342\3425\347\347\347\40\360\360\360\22\342\342\342\11\277\277\277\4" - "\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\1\252\252\252\3\342\342\342\11\362\362\362\25\346" - "\346\346)\332\332\332E\315\315\315a\302\302\302v\277\277\277|\304\304\304" - "q\321\321\321Z\336\336\336>\351\351\351$\360\360\360\22\337\337\337\10\252" - "\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\252\252\252\3\324\324\324\6\353\353\353" - "\15\350\350\350\27\344\344\344'\335\335\335=\322\322\322V\304\304\304r\266" - "\266\266\215\252\252\252\246\240\240\240\274\227\227\227\315\221\221\221" - "\332\215\215\215\342\213\213\213\346\213\213\213\345\216\216\216\340\221" - "\221\221\327\227\227\227\313\240\240\240\274\247\247\247\256\255\255\255" - "\242\261\261\261\230\265\265\265\222\265\265\265\221\264\264\264\224\260" - "\260\260\233\253\253\253\245\245\245\245\261\240\240\240\273\235\235\235" - "\302\234\234\234\303\237\237\237\275\246\246\246\257\261\261\261\232\275" - "\275\275\201\311\311\311e\331\331\331J\345\345\3452\356\356\356\37\360\360" - "\360\22\342\342\342\11\277\277\277\4\177\177\177\2\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\1\177\177\177\2\332\332\332\7\357\357\357\20\356\356\356\37\341\341\341" - "4\330\330\330H\320\320\320W\321\321\321Y\325\325\325P\336\336\336>\346\346" - "\346)\350\350\350\27\347\347\347\13\277\277\277\4\0\0\0\1\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\1\177\177\177\2\324\324\324\6\351\351\351\14\362\362\362\25" - "\351\351\351$\342\342\3426\327\327\327M\311\311\311e\276\276\276~\262\262" - "\262\226\250\250\250\253\237\237\237\275\227\227\227\313\223\223\223\325" - "\220\220\220\333\217\217\217\335\220\220\220\333\223\223\223\326\226\226" - "\226\317\231\231\231\307\236\236\236\277\242\242\242\270\244\244\244\264" - "\245\245\245\261\244\244\244\262\243\243\243\265\241\241\241\271\240\240" - "\240\274\240\240\240\274\242\242\242\270\246\246\246\257\255\255\255\240" - "\267\267\267\214\303\303\303t\317\317\317[\334\334\334C\343\343\343.\355" - "\355\355\35\360\360\360\21\342\342\342\11\277\277\277\4\177\177\177\2\0\0" - "\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177\177\2\314\314\314\5\347\347\347\13\362" - "\362\362\24\350\350\350\"\343\343\343.\336\336\3367\337\337\3378\344\344" - "\3441\352\352\352%\351\351\351\30\353\353\353\15\324\324\324\6\177\177\177" - "\2\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177\177\2\314\314" - "\314\5\345\345\345\12\361\361\361\23\356\356\356\36\343\343\343.\333\333" - "\333A\322\322\322V\310\310\310l\274\274\274\202\262\262\262\226\251\251\251" - "\247\243\243\243\265\236\236\236\300\232\232\232\310\230\230\230\314\227" - "\227\227\316\227\227\227\315\227\227\227\313\231\231\231\307\234\234\234" - "\303\236\236\236\277\240\240\240\274\241\241\241\272\241\241\241\267\244" - "\244\244\264\246\246\246\260\251\251\251\247\260\260\260\234\267\267\267" - "\214\301\301\301y\314\314\314d\327\327\327N\337\337\3379\344\344\344'\352" - "\352\352\31\356\356\356\17\337\337\337\10\277\277\277\4\177\177\177\2\0\0" - "\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\252\252\252\3\324\324\324\6" - "\347\347\347\13\360\360\360\22\352\352\352\31\355\355\355\35\355\355\355" - "\35\352\352\352\31\361\361\361\23\351\351\351\14\324\324\324\6\252\252\252" - "\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177" - "\177\2\277\277\277\4\342\342\342\11\356\356\356\17\351\351\351\30\351\351" - "\351$\341\341\3414\332\332\332E\320\320\320X\307\307\307j\277\277\277|\267" - "\267\267\213\261\261\261\230\254\254\254\243\250\250\250\253\245\245\245" - "\261\243\243\243\265\243\243\243\266\243\243\243\266\244\244\244\264\246" - "\246\246\260\247\247\247\254\251\251\251\247\254\254\254\241\260\260\260" - "\231\266\266\266\220\274\274\274\203\303\303\303t\313\313\313c\322\322\322" - "Q\336\336\336?\343\343\343.\347\347\347\40\362\362\362\24\351\351\351\14" - "\324\324\324\6\252\252\252\3\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\1\252\252\252\3\314\314\314\5\337\337\337\10\347" - "\347\347\13\353\353\353\15\353\353\353\15\347\347\347\13\337\337\337\10\314" - "\314\314\5\252\252\252\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177\177\2\252\252\252\3\324\324\324" - "\6\347\347\347\13\360\360\360\22\354\354\354\33\352\352\352&\341\341\341" - "4\334\334\334B\325\325\325P\316\316\316^\310\310\310k\302\302\302v\275\275" - "\275\200\273\273\273\207\267\267\267\214\265\265\265\217\266\266\266\220" - "\265\265\265\217\267\267\267\214\271\271\271\210\274\274\274\202\300\300" - "\300z\304\304\304q\312\312\312f\321\321\321Y\326\326\326L\335\335\335=\343" - "\343\343/\351\351\351#\351\351\351\30\356\356\356\17\342\342\342\11\314\314" - "\314\5\177\177\177\2\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\177\177\177\2\252\252\252\3\277\277" - "\277\4\314\314\314\5\314\314\314\5\277\277\277\4\252\252\252\3\177\177\177" - "\2\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0", -}; - diff --git a/BasiliskII/src/Unix/BasiliskII_32x32x32_icon.c b/BasiliskII/src/Unix/BasiliskII_32x32x32_icon.c deleted file mode 100644 index 632f4673a..000000000 --- a/BasiliskII/src/Unix/BasiliskII_32x32x32_icon.c +++ /dev/null @@ -1,166 +0,0 @@ -/* GIMP RGBA C-Source image dump (BasiliskII_32x32x32_icon.c) */ - -static const struct { - unsigned int width; - unsigned int height; - unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ - unsigned char pixel_data[32 * 32 * 4 + 1]; -} icon_32x32x32 = { - 32, 32, 4, - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q'\17s\377s\0\377q\37\6s\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0JJJ\377\7\7\7!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0h(\16k\377\214\0\377" - "\356b\16\357\36\27\27!\12\12\12\30%%%)\356b\16\357\315Y\40\316\263I\40\326" - "\245B)\377\203\27\0\204z\16\0{z\16\0{\203\27\0\204z\16\0{\203\27\0\204z\16" - "\0{z\16\0{\203\27\0\204\264I\27\265,\26\15""9\0\0\0\10\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\377{\0\377\377\204" - "\0\377%\22\22)\27\27\27!AAARbbb\224jjj\224\377\224\0\377\377\214\0\377\377" - "\224\0\377\377\224\0\377\377\214\0\377\377\224\0\377\377\224\0\377\377\224" - "\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0" - "\377\377s\0\377,((9\37\37\37)\0\0\0\0\0\0\0\0,,,9jjj\204jjj\204aaa{jjj\204" - "\2138\40\224\377\224\0\377\377k\0\377bbb\204jjj\234zzz\306zzz\326\203\203" - "\203\316zzz\245\377\224\0\377\377\204\0\377\377s\0\377\377s\0\377\377{\0" - "\377\377s\0\377\377s\0\377\377s\0\377\377{\0\377\377s\0\377\377s\0\377\377" - "s\0\377\377s\0\377\377c\0\377zzz\306rrr\265\0\0\0\0\0\0\0\0jjj\204\234\234" - "\234\377\234\234\234\377\245\245\245\377\357c\30\377\377\224\0\377\367c\0" - "\377\224\224\224\377{{{\377ccc\377sss\377\214\214\214\377\234\234\234\377" - "\234\234\234\377\377\224\0\377\377{\0\377\377s\0\377\377k\0\377\377k\0\377" - "\377s\0\377\377k\0\377\377s\0\377\377k\0\377\377s\0\377\377s\0\377\377s\0" - "\377\377s\0\377\306Z9\377{{{\377rrr\275\0\0\0\0\0\0\0\0bbb\204\234\234\234" - "\377\245\245\245\377\367s\20\377\377\204\0\377\377k\0\377\214\214\214\377" - "kkk\377ZZZ\377{{{\377\224\224\224\377\234\234\234\377\245\245\245\377\224" - "\224\224\377\2559!\377\306\224\204\377\214kk\377kkk\377sss\377sss\377sss" - "\377sss\377sss\377sss\377sss\377\367R\10\377\377k\0\377{{{\377\203\203\203" - "\367XXX\204\0\0\0\0\0\0\0\0jjj\204\245\245\245\377\357c\30\377\377\204\0" - "\377\377s\0\377\224\204\204\377ccc\377ZZZ\377{{{\377\234\234\234\377\245" - "\245\245\377\245\245\245\377\234\234\234\377RRR\377sss\377\306\306\306\377" - "\214\214\214\377\214\214\214\377\214\214\214\377\214\214\214\377\214\214" - "\214\377\224\224\224\377\214\214\214\377\214\214\214\377\224\224\224\377" - "\377c\0\377\357R\30\377\204\204\204\377zzz\326666B\0\0\0\0\0\0\0\0aaa{\306" - "sR\377\377\224\0\377\377{\0\377\316R1\377ccc\377RRR\377JJJ\377{{{\377\234" - "\234\234\377\245\245\245\377\234\234\234\377\224\224\224\377RRR\377\336\336" - "\336\377\336\336\336\377\316\316\316\377\316\316\316\377\224\224\224\377" - "RRR\377\326\326\326\377\326\326\326\377\326\326\326\377\326\326\326\377\326" - "\306\306\377\377k\0\377\306\275\265\377\203\203\203\357jjj\234\25\25\25\30" - "\0\0\0\0\0\0\0\0jbb\204\377\224\0\377\377{\0\377\377k\0\377ccc\377RRR\377" - "kkk\377ccc\377\204\204\204\377\245\245\245\377\245\245\245\377\234\234\234" - "\377ZZZ\377ccc\377\347\347\347\377\347\347\347\377\347\347\347\377\347\347" - "\347\377\224\224\224\377RRR\377\347\347\347\377\336\336\336\377\347\347\347" - "\377\347\347\347\377\367k9\377\377c\0\377\275\275\275\377\203\203\203\347" - "IIIZ\0\0\0\0\0\0\0\0\0\0\0\0\356j\16\357\377\204\0\377\377s\0\377\234R9\377" - "RRR\377ZZZ\377\214\214\214\377ccc\377\204\204\204\377\234\234\234\377\234" - "\234\234\377\245\245\245\377RRR\377\326\326\326\377\347\347\347\377\336\336" - "\336\377\347\347\347\377\336\336\336\377\234\234\234\377JJJ\377\347\347\347" - "\377\347\347\347\377\347\347\347\377\336\336\336\377\377k\0\377\347\224\204" - "\377\234\234\234\377\203\203\203\326\36\36\36!\0\0\0\0\0\0\0\0\0\0\0\10\377" - "\224\0\377\377{\0\377\377k\0\377RRR\377RRR\377sss\377\224\224\224\377\234" - "\234\234\377\245\245\245\377\245\245\245\377\234\234\234\377\214\214\214" - "\377JJJ\377\347\347\347\377\347\347\347\377\347\347\347\377\336\336\336\377" - "\347\347\347\377\347\347\347\377\347\347\347\377\347\347\347\377\347\347" - "\347\377\336\336\336\377\347\275\265\377\377s\0\377\316\316\316\377\214\214" - "\214\377\203\203\203\265\0\0\0\10\0\0\0\0\0\0\0\0\335Y\26\336\377\214\0\377" - "\377s\0\377\316B\30\377JJJ\377ZZZ\377\204\204\204\377\234\234\234\377\245" - "\245\245\377\245\245\245\377\234\234\234\377\245\245\245\377ccc\377kkk\377" - "\347\347\347\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347" - "\347\377\336\336\336\377\336\336\336\377\347\347\347\377\336\336\336\377" - "\347\347\347\377\377c!\377\367c)\377\265\265\265\377\214\214\214\377zzz\224" - "\0\0\0\0\0\0\0\0\0\0\0\0\377\224\0\377\377{\0\377\377k\0\377ZRR\377RRR\377" - "{kk\377\377Z\10\377\377s\0\377\377s\0\377\377s\0\377\357R\30\377\245\245" - "\245\377RRR\377\255\255\255\377\347\347\347\377\336\336\336\377\347\347\347" - "\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347\347\377\347" - "\347\347\377\347\347\347\377\347\347\347\377\377k\0\377\336\316\316\377\234" - "\234\234\377\245\245\245\377yyy\204\0\0\0\0\0\0\0\0\36\27\27!\377\224\0\377" - "\377s\0\377\377k\0\377RRR\377ZRR\377\377k\0\377\316cJ\377\316cJ\377\377\214" - "\0\377\377s\0\377\377s\0\377\377c\0\377RRR\377\326\326\326\377\336\336\336" - "\377\347\347\347\377\347\347\347\377\347\347\347\377\336\336\336\377\347" - "\347\347\377\336\336\336\377\347\347\347\377\336\336\336\377\357\245\224" - "\377\377c\0\377\306\306\306\377\214\214\214\377\275\275\275\377yyy\204\0" - "\0\0\0\0\0\0\0\212(\16\214\377\224\0\377\377k\0\377\377R\0\377RRR\377ccc" - "\377\224\224\224\377\234\234\234\377{{{\377ccc\377\377\214\0\377\377s\0\377" - "\377s\0\377\347B\10\377\316\316\316\377\347\347\347\377\347\347\347\377\347" - "\347\347\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347\347" - "\377\347\347\347\377\347\347\347\377\377R\0\377\357\204c\377\255\255\255" - "\377\224\224\224\377\326\326\326\377zzz{\0\0\0\0\0\0\0\0\335b\26\336\377" - "\214\0\377\377s\0\377\336J\20\377RRR\377kkk\377\224\224\224\377\204\204\204" - "\377kkk\377{{{\377\265ZJ\377\377\214\0\377\377s\0\377\377s\0\377111\377J" - "JJ\377RRR\377JJJ\377RRR\377\347\347\347\377\347\347\347\377\347\347\347\377" - "\336\336\336\377\347\347\347\377\377k\0\377\326\326\326\377\234\234\234\377" - "\255\255\255\377\336\336\336\377yyy\204\0\0\0\0\0\0\0\0\377Z\0\377\377\204" - "\0\377\377k\0\377\275B\30\377JJJ\377{{{\377\234\234\234\377\234\234\234\377" - "\234\234\234\377\234\234\234\377\234\234\234\377\377\224\0\377\377{\0\377" - "\377s\0\377\265B)\377sss\377\224\224\224\377kkk\377ZZZ\377\336\336\336\377" - "\336\336\336\377\347\347\347\377\347\347\347\377\367\224{\377\377Z\10\377" - "\306\306\306\377\214\214\214\377\306\306\306\377\336\336\336\377\203\203" - "\203\204\0\0\0\0\0\0\0\0\377c\0\377\377\204\0\377\377s\0\377\275B!\377RR" - "R\377{{{\377\234\234\234\377\245\245\245\377\234\234\234\377\245\245\245" - "\377\234\234\234\377\377c\0\377\377\214\0\377\377k\0\377\357J\10\377ccc\377" - "\224\224\224\377RRR\377\214\214\214\377\347\347\347\377\347\347\347\377\347" - "\347\347\377\336\336\336\377\377Z\0\377\347\245\234\377\255\255\255\377\234" - "\234\234\377\326\326\326\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0\377c\0\377" - "\377\204\0\377\377s\0\377\316J\30\377RRR\377\204\204\204\377\224\224\224" - "\377kkk\377{{{\377\234\234\234\377\245\245\245\377\347c)\377\377\224\0\377" - "\377s\0\377\377R\0\377RRR\377\204\204\204\377JJJ\377\265\265\265\377\347" - "\347\347\377\336\336\336\377\347\347\347\377\336\336\336\377\377k\0\377J" - "JJ\377\214\214\214\377\265\265\265\377\336\336\336\377\347\347\347\377zz" - "z{\0\0\0\0\0\0\0\0\346b\17\347\377\214\0\377\377k\0\377\347J\10\377ZZZ\377" - "\204\204\204\377\245\245\245\377\214\214\214\377kkk\377kkk\377kkk\377\275" - "J1\377\377\224\0\377\377s\0\377\377Z\0\377JJJ\377sss\377RRR\377\214\214\214" - "\377sss\377ZZZ\377JJJ\377\275B!\377\336J\20\377\255\255\255\377\224\224\224" - "\377\316\316\316\377\336\336\336\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0" - "\2437\27\245\377\214\0\377\377s\0\377\377Z\0\377RRR\377\204\204\204\377\234" - "\234\234\377\245\245\245\377\234\234\234\377\245\245\245\377\234\234\234" - "\377\306ZB\377\377\224\0\377\377s\0\377\367J\0\377111\377RRR\377RRR\377Z" - "ZZ\377sss\377\224\224\224\377\326\326\326\377\377c\0\377\336\326\316\377" - "\245\245\245\377\245\245\245\377\336\336\336\377\347\347\347\377\347\347" - "\347\377zzz{\0\0\0\0\0\0\0\0%\22\22)\377\214\0\377\377s\0\377\377k\0\377" - "RRR\377{{{\377\234\234\234\377\245\245\245\377\234\234\234\377\245\245\245" - "\377\234\234\234\377\326kJ\377\377\214\0\377\377s\0\377\306J!\377RRR\377" - "sss\377JJJ\377\265\265\265\377\336\336\336\377\347\347\347\377\347\326\326" - "\377\377c\0\377\316\316\316\377\224\224\224\377\275\275\275\377\336\336\336" - "\377\347\347\347\377\336\336\336\377zzz{\0\0\0\0\0\0\0\0\0\0\0\0\377\224" - "\0\377\377\204\0\377\377s\0\377kJJ\377kkk\377\234\234\234\377\245\245\245" - "\377\234\234\234\377\245\245\245\377\245\245\245\377\347c)\377\377\214\0" - "\377\377s\0\377cJB\377ZZZ\377{{{\377RRR\377\224\224\224\377\347\347\347\377" - "\347\347\347\377\367c)\377\367\204c\377\275\275\275\377\224\224\224\377\316" - "\316\316\377\347\347\347\377\347\347\347\377\347\347\347\377yyy\204\0\0\0" - "\0\0\0\0\0\0\0\0\0\264@\27\265\377\214\0\377\377s\0\377\357J\10\377kkk\377" - "\224\224\224\377\245\245\245\377\234\234\234\377\245\245\245\377\234\234" - "\234\377\377c\0\377\377\204\0\377\377c\0\377RRR\377ZZZ\377\204\204\204\377" - "ccc\377ccc\377\336\336\336\377\347\347\347\377\377s\0\377\326\326\326\377" - "\245\245\245\377\245\245\245\377\336\336\336\377\336\336\336\377\336\336" - "\336\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\377\224\0\377" - "\377\204\0\377\377k\0\377kkc\377\245\245\245\377\265\265\265\377\275\275" - "\275\377\265\265\265\377\265\265\265\377\377\224\0\377\377s\0\377\234ZR\377" - "ccc\377kkk\377\245\245\245\377\245\245\245\377RRR\377\357\357\357\377\357" - "\255\234\377\377R\0\377\326\326\326\377\234\234\234\377\326\326\326\377\357" - "\357\357\377\357\357\357\377\367\367\367\377\357\357\357\377zzz{\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0H%\37J\377\214\0\377\377{\0\377\367Z\0\377XXX\204" - "\17\17\17\20\0\0\0\0\0\0\0\0\2128\27\214\377{\0\377\335Q\16\336zzz\326zz" - "z\367bbb\224\17\17\17\20\0\0\0\0RRR\377\0\0\0\0\377Z\0\377W\37\26ZQQQkjj" - "j\234\27\27\27!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0yA0\204\377\224\0\377\377{\0\377\367Z\10\3776..B\0" - "\0\0\0P\37\17R\377{\0\377\346Y\16\357QQQk\203\203\203\357zzz\316666B\0\0" - "\0\10\0\0\0\0III\336777\234\377s\0\377\27\27\27!rrr\245QQQk\0\0\0\10\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\17\17\17\20YYY{\356Y\7\367\377k\0\377\377k\0\377\377s\0\377\377c\0\377" - "a&\27c%%%)rrr\265zzz\326QQQk\0\0\0\10\0\0\0\0\0\0\0\0\0\0\0\20RRR\377\0\0" - "\0\0""777Jrrr\265$$$1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\25\25\25\30YYY{zzz\336\203\203" - "\203\357rrr\255IIIZIIIZjjj\245zzz\316QQQk\17\17\17\20\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\10IIIZXXXs\17\17\17\20\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\10\17\17\17\20AAAJbbb\224rrr\275zzz\275jjj\255bbb\214666B\17\17\17" - "\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\0\0\0\20\17" - "\17\17\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0", -}; - diff --git a/BasiliskII/src/Unix/Darwin/lowmem.c b/BasiliskII/src/Unix/Darwin/lowmem.c old mode 100644 new mode 100755 diff --git a/BasiliskII/src/Unix/Darwin/testlmem.sh b/BasiliskII/src/Unix/Darwin/testlmem.sh index 4e08425fa..b252c83ed 100755 --- a/BasiliskII/src/Unix/Darwin/testlmem.sh +++ b/BasiliskII/src/Unix/Darwin/testlmem.sh @@ -20,7 +20,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -PAGEZERO_SIZE=${1:-0x2000} +sw_vers > /dev/null && exit 0 + +PAGEZERO_SIZE=0x2000 +[[ -n "$1" ]] && PAGEZERO_SIZE=$1 # You want all the output to go to stderr so that configure is quiet but # config.log is verbose. { echo 'building lowmem utility' && \ 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 ebd8eb69e..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, using same algorithm as audio_amiga.cpp. - // 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/Linux/NetDriver/config.h b/BasiliskII/src/Unix/Linux/NetDriver/config.h deleted file mode 120000 index fc383f113..000000000 --- a/BasiliskII/src/Unix/Linux/NetDriver/config.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../SheepShaver/src/Unix/config.h \ No newline at end of file diff --git a/BasiliskII/src/Unix/Linux/etherhelpertool.c b/BasiliskII/src/Unix/Linux/etherhelpertool.c new file mode 100644 index 000000000..5d6117bc7 --- /dev/null +++ b/BasiliskII/src/Unix/Linux/etherhelpertool.c @@ -0,0 +1,506 @@ +/* + * etherhelpertool.c - Reads and writes raw ethernet packets usng bpf + * interface. + * + * Copyright (C) 2010, Daniel Sumorok + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include + +#define STR_MAX 256 +#define MAX_ARGV 10 + +static int remove_bridge = 0; +static char bridge_name[STR_MAX]; +static const char *exec_name = "etherhelpertool"; + +static int main_loop(int sd, int use_bpf); +static int open_tap(char *ifname); +static int run_cmd(const char *cmd); +static void handler(int signum); +static int install_signal_handlers(void); +static void do_exit(void); +static int open_bpf(char *ifname); + +int main(int argc, char **argv) +{ + char *if_name; + int ret = 255; + int sd = -1; + int tapNum; + int use_bpf; + + if (argc != 2) { + return 255; + } + + if_name = argv[1]; + + do { + if (strncmp(if_name, "tap", 3) == 0) { + sd = open_tap(if_name); + use_bpf = 0; + } else { + sd = open_bpf(if_name); + use_bpf = 1; + } + + if (sd < 0) { + fprintf(stderr, "%s: open device failed.\n", + exec_name); + ret = 253; + break; + } + + if (install_signal_handlers() != 0) { + fprintf(stderr, + "%s: failed to install signal handers.\n", + exec_name); + ret = 252; + break; + } + + ret = main_loop(sd, use_bpf); + close(sd); + } while (0); + + do_exit(); + + return ret; +} + +static int main_loop(int sd, int use_bpf) +{ + fd_set readSet; + char *outgoing, *incoming; + unsigned short *out_len; + unsigned short *in_len; + int in_index, out_index; + u_int blen = 0; + int ret; + int fret = 0; + int pkt_len; + int frame_len; + int pad; + char c = 0; + + blen = 4096; + + incoming = malloc(blen); + if (incoming == NULL) { + fprintf(stderr, + "%s: malloc() failed.\n", + exec_name); + return -2; + } + + outgoing = malloc(blen); + if (outgoing == NULL) { + free(outgoing); + fprintf(stderr, + "%s: malloc() failed.\n", + exec_name); + return -3; + } + + in_index = 0; + out_index = 0; + + out_len = (unsigned short *)outgoing; + + /* Let our parent know we are ready for business. */ + if(write(0, &c, 1) != 1) { + fprintf(stderr, "%s: Failed to notify main application: %s\n", + __func__, strerror(errno)); + } + + while (1) { + int i; + FD_ZERO(&readSet); + FD_SET(0, &readSet); + FD_SET(sd, &readSet); + + ret = select(sd + 1, &readSet, NULL, NULL, NULL); + if (ret < 0) { + fprintf(stderr, + "%s: select() failed.\n", + exec_name); + fret = -4; + break; + } + + if (FD_ISSET(0, &readSet)) { + if (out_index < 2) { + ret = read(0, outgoing + out_index, 2-out_index); + } else { + ret = read(0, outgoing + out_index, *out_len - out_index + 2); + } + + if (ret < 1) { + if(ret < 0) { + fprintf(stderr, + "%s: read() failed.\n", + exec_name); + } + fret = -5; + break; + } + + out_index += ret; + + if (out_index > 1) { + if ((*out_len + 2) > blen) { + fret = -6; + break; + } + + if (out_index == (*out_len + 2)) { + if(use_bpf) { + ret = write(sd, out_len + 1, *out_len); + if (ret != *out_len) { + fprintf(stderr, + "%s: write() failed.\n", + exec_name); + fret = -7; + break; + } + } else { + ret = write(sd, out_len + 1, *out_len); + if (ret != *out_len) { + fprintf(stderr, + "%s: write() failed.\n", + exec_name); + fret = -7; + break; + } + } + + out_index = 0; + } + } + + } + + if (FD_ISSET(sd, &readSet)) { + in_len = (unsigned short *)incoming; + + pkt_len = read(sd, in_len + 1, blen-2); + if (pkt_len < 14) { + fprintf(stderr, + "%s: read() returned %d.\n", + exec_name, pkt_len); + fret = -8; + break; + } + *in_len = pkt_len; + + if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + fprintf(stderr, + "%s: write() failed\n", + exec_name); + fret = -10; + break; + } + } + } + + free(incoming); + free(outgoing); + + return fret; +} + + +static int open_tap(char *ifname) +{ + char str[STR_MAX] = {0}; + char ifstr[STR_MAX] = {0}; + char *interface; + char *address = NULL; + char *netmask = NULL; + char *bridge = NULL; + char *bridged_if = NULL; + int sd; + struct ifreq ifr = {0}; + + snprintf(ifstr, STR_MAX, "%s", ifname); + interface = strtok(ifstr, "/"); + bridge = strtok(NULL, "/"); + if (bridge != NULL) { + bridged_if = strtok(NULL, "/"); + } + interface = strtok(ifstr, ":"); + + address = strtok(NULL, ":"); + + if (address != NULL) { + netmask = strtok(NULL, ":"); + } + + sd = open("/dev/net/tun", O_RDWR); + if (sd < 0) { + fprintf(stderr, "%s: Failed to open %s\n", + exec_name, interface); + return -1; + } + + snprintf(str, STR_MAX, "/dev/%s", interface); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, interface, IFNAMSIZ); + + if(ioctl(sd, TUNSETIFF, (void *)&ifr) != 0) { + fprintf(stderr, "%s: ioctl(TUNSETIFF): %s\n", + __func__, strerror(errno)); + close(sd); + return -1; + } + + if (address == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface); + } else if (netmask == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s", + interface, address); + } else { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s", + interface, address, netmask); + } + + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to configure %s\n", + exec_name, interface); + close(sd); + return -1; + } + + if (bridge != NULL) { + /* Check to see if bridge is alread up */ + snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge); + if (run_cmd(str) == 0) { + /* bridge is already up */ + if (bridged_if != NULL) { + fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n", + exec_name, bridge, bridged_if); + } + } else { + snprintf(str, STR_MAX, "/sbin/brctl addbr %s", bridge); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to create %s\n", + exec_name, bridge); + close(sd); + return -1; + } + remove_bridge = 1; + + strncpy(bridge_name, bridge, STR_MAX); + + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to open %s\n", + exec_name, bridge); + close(sd); + return -1; + } + + if (bridged_if != NULL) { + snprintf(str, STR_MAX, "/sbin/brctl addif %s %s", + bridge, bridged_if); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to add %s to %s\n", + exec_name, bridged_if, bridge); + close(sd); + return -1; + } + } + + snprintf(str, STR_MAX, "/sbin/brctl addif %s %s", + bridge, interface); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to add %s to %s\n", + exec_name, interface, bridge); + close(sd); + return -1; + } + } + } + + return sd; +} + +static int run_cmd(const char *cmd) { + char cmd_buffer[STR_MAX] = {0}; + char *argv[MAX_ARGV + 1] = {0}; + int i; + pid_t pid, waitpid; + int status = 0; + + /* Collect arguments */ + strncpy(cmd_buffer, cmd, STR_MAX-1); + + argv[0] = strtok(cmd_buffer, " "); + for (i=1; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STR_MAX 1024 +#define MAX_ARGV 10 + +FILE * run_tool(const char *if_name, const char *tool_name) { + char cmd_buffer[STR_MAX] = {0}; + char * const argv[3] = {NULL, NULL, NULL}; + int i; + pid_t pid, waitpid; + int status = 0; + int fds[2]; + char c; + + if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) { + fprintf(stderr, "%s: socketpair() failed: %s\n", + __func__, strerror(errno)); + return NULL; + } + + ((const char**)argv)[0] = tool_name; + ((const char**)argv)[1] = if_name; + + /* Run sub process */ + pid = fork(); + if (pid == 0) { + /* Child process */ + fclose(stdout); + fclose(stdin); + dup2(fds[0], 0); + close(fds[1]); + close(fds[0]); + + if (execve(tool_name, argv, NULL) < 0) { + perror("execve"); + exit(1); + } + } + + + close(fds[0]); + + if(read(fds[1], &c, 1) < 1) { + close(fds[1]); + return NULL; + } + + return fdopen(fds[1], "rw"); +} diff --git a/BasiliskII/src/Unix/Linux/scsi_linux.cpp b/BasiliskII/src/Unix/Linux/scsi_linux.cpp index b2cef0116..d63652779 100644 --- a/BasiliskII/src/Unix/Linux/scsi_linux.cpp +++ b/BasiliskII/src/Unix/Linux/scsi_linux.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include // workaround for broken RedHat 6.0 /usr/include/scsi #include #include diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 42f1b049f..bc92f1c65 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -100,7 +100,7 @@ define GUI_SRCS_LIST_TO_OBJS endef GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS) ifeq ($(USE_BINCUE),yes) -GUI_OBJS += bincue_unix.o +GUI_OBJS += bincue.o endif GUI_SRCS := $(GUI_SRCS:%=@top_srcdir@/%) @@ -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/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/config.guess b/BasiliskII/src/Unix/config.guess index 78f6b92cd..dc0a6b299 100755 --- a/BasiliskII/src/Unix/config.guess +++ b/BasiliskII/src/Unix/config.guess @@ -1,13 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2003-01-10' +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 -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -16,33 +15,31 @@ timestamp='2003-01-10' # 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. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. +# Please send patches to . + -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -53,8 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -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." @@ -66,11 +62,11 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. @@ -88,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -100,47 +94,92 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ;' +tmp= +# shellcheck disable=SC2172 +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" ; } || + { 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 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +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 +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #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')" + + # 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 tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -149,23 +188,34 @@ 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=`(/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 ;; - *) machine=${UNAME_MACHINE_ARCH}-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') + 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. - case "${UNAME_MACHINE_ARCH}" in + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -175,7 +225,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release @@ -183,210 +240,226 @@ 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/[-_].*/\./'` + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; + echo "$machine-${os}${release}${abi-}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:MicroBSD:*:*) - echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE} - exit 0 ;; + 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\.//') + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *: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 ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *: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 ;; alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi + # 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}') + ;; + *5.*) + 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 + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. # A Vn.n version is a released version. # 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. - eval $set_cc_for_build - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null - if test "$?" = 0 ; then - case `$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - 3-1307) - UNAME_MACHINE="alphaev7" - ;; - esac - fi - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; + 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 0;; + exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; *:OS/390:*:*) echo i370-ibm-openedition - exit 0 ;; + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp - exit 0;; + 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 fi - exit 0 ;; + exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 - exit 0 ;; - DRS?6000:UNIX_SV:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7 && exit 0 ;; + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + 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/[^.]*//')" + exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + 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/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # 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 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 + then + SUN_ARCH=x86_64 + fi + fi + 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/[^.]*//'` - exit 0 ;; + 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/-/_/'` - exit 0 ;; + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" + exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; + 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` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in + 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 sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac - exit 0 ;; + exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -396,41 +469,44 @@ EOF # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 - exit 0 ;; + exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -439,94 +515,95 @@ EOF #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c \ - && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && exit 0 - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + 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 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax - exit 0 ;; + exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax - exit 0 ;; + exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax - exit 0 ;; + exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix - exit 0 ;; + exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 - exit 0 ;; + exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 - exit 0 ;; + exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 - exit 0 ;; + exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + # DG/UX returns AViiON for all architectures + 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} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi - exit 0 ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 - exit 0 ;; + exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 - exit 0 ;; + exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 - exit 0 ;; + exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd - exit 0 ;; + exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; + 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 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix - exit 0 ;; + 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} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -537,128 +614,143 @@ EOF exit(0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 - echo rs6000-ibm-aix3.2.5 + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi - exit 0 ;; - *:AIX:*:[45]) - 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 + exit ;; + *:AIX:*:[4567]) + 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/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + 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} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; *:AIX:*:*) echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 - exit 0 ;; + exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx - exit 0 ;; + exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 - exit 0 ;; + exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd - exit 0 ;; + exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 - exit 0 ;; + exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + 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 - 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 - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + 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 + 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 - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + 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 - # avoid double evaluation of $set_cc_for_build - test -n "$CC_FOR_BUILD" || eval $set_cc_for_build - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + echo ia64-hp-hpux"$HPUX_REV" + exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -683,334 +775,414 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && + { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd - exit 0 ;; + exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd - exit 0 ;; + exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf - exit 0 ;; + exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf - exit 0 ;; + exit ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + if test -x /usr/sbin/sysversion ; then + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi - exit 0 ;; + exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites - exit 0 ;; + exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit 0 ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit 0 ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit 0 ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit 0 ;; + exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; *:UNICOS/mp:*:*) - echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + 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/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; + 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/ /_/') + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + 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 + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf + fi + exit ;; *:FreeBSD:*:*) - # Determine whether the default compiler uses glibc. - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #if __GLIBC__ >= 2 - LIBC=gnu - #else - LIBC= - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} - exit 0 ;; + 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/[-(].*//')" + exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:3*) - echo i586-pc-interix3 - exit 0 ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit 0 ;; + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-pc-cygwin + exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" + exit ;; *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; + # the GNU system + 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" + exit ;; + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + 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 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:* | arc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + 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 ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 #else - CPU= + LIBCABI=${LIBC} #endif #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + 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; } ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + 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" ;; esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; + 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" + exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 - exit 0 ;; + exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-stop + exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + 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} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" + 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 @@ -1018,208 +1190,328 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi - exit 0 ;; + exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 - exit 0 ;; + exit ;; paragon:*:*:*) echo i860-intel-osf1 - exit 0 ;; + exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi - exit 0 ;; + exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv - exit 0 ;; + exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv - exit 0 ;; + exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*: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) + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 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 0 + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + 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) + /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 \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 - exit 0 ;; + exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 - exit 0 ;; + exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 - exit 0 ;; + exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 - exit 0 ;; + exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 - exit 0 ;; + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos - exit 0 ;; + exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 - exit 0 ;; + exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + if test -d /usr/nec; then + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi - exit 0 ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos - exit 0 ;; + exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos - exit 0 ;; + exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos - exit 0 ;; + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit 0 ;; + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; *:Darwin:*:*) - case `uname -p` in - *86) UNAME_PROCESSOR=i686 ;; - powerpc) UNAME_PROCESSOR=powerpc ;; + UNAME_PROCESSOR=$(uname -p) + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit 0 ;; + 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 "$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 + # 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` - if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=$(uname -p) + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; *:QNX:*:4*) echo i386-pc-qnx - exit 0 ;; - NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux - exit 0 ;; + exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv - exit 0 ;; + exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - 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 - exit 0 ;; + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 - exit 0 ;; + exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex - exit 0 ;; + exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 - exit 0 ;; + exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 - exit 0 ;; + exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 - exit 0 ;; + exit ;; *:ITS:*:*) echo pdp10-unknown-its - exit 0 ;; + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" + exit ;; + *:*VMS:*:*) + 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 ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + *:AROS:*:*) + echo "$UNAME_MACHINE"-unknown-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < "$dummy.c" < -# include +#include +#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 () { @@ -1232,20 +1524,12 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" -#endif - ); exit (0); + "" #endif + ); exit (0); #endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) @@ -1253,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 @@ -1287,39 +1571,54 @@ main () #endif #if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); + struct utsname un; + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#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__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif #endif #if defined (alliant) && defined (i860) @@ -1330,79 +1629,73 @@ main () } EOF -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 +$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. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } +echo "$0: unable to guess system type" >&2 -# Convex versions that predate uname can use getsysinfo(1) +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +year=$(echo $timestamp | sed 's,-.*,,') +# shellcheck disable=SC2003 +if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then + cat >&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} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/BasiliskII/src/Unix/config.sub b/BasiliskII/src/Unix/config.sub index d6d67c3fd..7384e9198 100755 --- a/BasiliskII/src/Unix/config.sub +++ b/BasiliskII/src/Unix/config.sub @@ -1,42 +1,40 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2003-01-03' +timestamp='2021-04-30' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# 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 -# the Free Software Foundation; either version 2 of the License, or +# 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 +# the Free Software Foundation; either version 3 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. +# 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. - +# along with this program; if not, see . +# # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. + +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # 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/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 # that are meaningful with *any* GNU software. @@ -52,15 +50,14 @@ timestamp='2003-01-03' # 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 - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -70,8 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -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." @@ -83,23 +79,23 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 - exit 0;; + echo "$1" + exit ;; * ) break ;; @@ -114,955 +110,1173 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + 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 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -clix*) - basic_machine=clipper-intergraph + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - -lynx*) - os=-lynxos + op50n) + cpu=hppa1.1 + vendor=oki ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + op60c) + cpu=hppa1.1 + vendor=oki ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + ibm*) + cpu=i370 + vendor=ibm ;; - -psos*) - os=-psos + orion105) + cpu=clipper + vendor=highlevel ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | msp430 \ - | ns16k | ns32k \ - | openrisc | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | s390 | s390x \ - | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* \ - | m32r-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | msp430-* \ - | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | s390-* | s390x-* \ - | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 + cpu=we32k + vendor=att ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + basic_os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 + cpu=m68k + vendor=motorola ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=solaris2 ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) + cpu=mips + vendor=sgi + case $basic_os in + irix*) ;; *) - os=-irix4 + basic_os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos + cpu=m68000 + vendor=convergent ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + basic_os=nextstep2 ;; *) - os=-nextstep3 + basic_os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - nv1) - basic_machine=nv1-cray - os=-unicosmp - ;; - nsr-tandem) - basic_machine=nsr-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + basic_os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc + cpu=m68k + vendor=tti ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould + cpu=pn + vendor=gould ;; - power) basic_machine=power-ibm + power) + cpu=power + vendor=ibm ;; - ppc) basic_machine=powerpc-unknown + ps2) + cpu=i386 + vendor=ibm ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + rm[46]00) + cpu=mips + vendor=siemens ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown + rtpc | rtpc-*) + cpu=romp + vendor=ibm ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} ;; - ppc64) basic_machine=powerpc64-unknown + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + tower | tower-32) + cpu=m68k + vendor=ncr ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + w65) + cpu=w65 + vendor=wdc ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + none) + cpu=none + vendor=none ;; - rm[46]00) - basic_machine=mips-siemens + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine ;; - rtpc | rtpc-*) - basic_machine=romp-ibm + leon-*|leon[3-9]-*) + cpu=sparc + vendor=$(echo "$basic_machine" | sed 's/-.*//') ;; - sa29200) - basic_machine=a29k-amd - os=-udi + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | 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 \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | 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 \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | 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 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1070,168 +1284,213 @@ 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. @@ -1244,225 +1503,361 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in + score-*) + os=elf + ;; + spu-*) + os=elf + ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout + ;; + c4x-* | tic4x-*) + os=coff + ;; + c8051-*) + os=elf + ;; + clipper-intergraph) + os=clix + ;; + hexagon-*) + os=elf + ;; + tic54x-*) + os=coff + ;; + tic55x-*) + os=coff + ;; + tic6x-*) + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout + ;; + mep-*) + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 + ;; + pru-*) + os=elf ;; *-be) - os=-beos + os=beos ;; *-ibm) - os=-aix + os=aix + ;; + *-knuth) + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; - *-next ) - os=-nextstep + *-next) + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + 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. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -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 ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) vendor=ibm ;; - -ptx*) + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) vendor=sequent ;; - -vxsim* | -vxworks* | -windiss*) + *-tpf*) + vendor=ibm + ;; + *-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 - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os -exit 0 +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac old mode 100644 new mode 100755 index b405b2ce6..77219b5b7 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -1,17 +1,10 @@ -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 @@ -25,21 +18,17 @@ 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. AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no]) -AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphics [default=no]], [WANT_SDL_VIDEO=$enableval], [WANT_SDL_VIDEO=no]) -AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [default=no]], [WANT_SDL_AUDIO=$enableval], [WANT_SDL_AUDIO=no]) +AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphics [default=no]], [WANT_SDL_VIDEO=$enableval], [WANT_SDL_VIDEO=yes]) +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(sdl2, [ --with-sdl2 use SDL 2.x, rather than SDL 1.x [default=no]], [WANT_SDL_VERSION_MAJOR=2], [WANT_SDL_VERSION_MAJOR=1]) dnl JIT compiler options. -AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=no]], [WANT_JIT=$enableval], [WANT_JIT=no]) +AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes]) AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no]) dnl FPU emulation core. @@ -61,27 +50,18 @@ 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" ]) 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";; - gtk|gtk2) WANT_GTK="$withval";; - yes) WANT_GTK="gtk2 gtk";; - *) WANT_GTK="no";; - esac], - [WANT_GTK="gtk2 gtk"]) -AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes]) +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, AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode])) @@ -127,11 +107,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 +164,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;; @@ -288,9 +261,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 @@ -299,82 +269,28 @@ 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 - if [[ "x$WANT_SDL_VERSION_MAJOR" = "x1" ]]; then - AC_DEFINE(ENABLE_SDL1, 1, [Define if using SDL1.]) - 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" - else - WANT_SDL=no - WANT_SDL_VIDEO=no - WANT_SDL_AUDIO=no - SDL_SUPPORT="none" - fi - fi - - if [[ "x$WANT_SDL_VERSION_MAJOR" = "x2" ]]; then - AC_DEFINE(ENABLE_SDL2, 1, [Define if using SDL2.]) - AC_PATH_PROG(sdl_config, "sdl2-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" - else - WANT_SDL=no - WANT_SDL_VIDEO=no - WANT_SDL_AUDIO=no - SDL_SUPPORT="none" - fi - 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 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 @@ -382,6 +298,7 @@ AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no]) AS_IF([test "x$have_bincue" = "xyes" ], [ if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then DEFINES="$DEFINES -DBINCUE" + CPPFLAGS="$CPPFLAGS -DBINCUE" AC_SUBST(USE_BINCUE, yes) else AC_MSG_ERROR([You need SDL Audio to use BINCUE support.]) @@ -428,72 +345,16 @@ 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 -xgtk2*) - AM_PATH_GTK_2_0(1.3.15, [ - 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" - 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" - GUI_LIBS="$GTK_LIBS" - dnl somehow, would redefine gettext() to nothing if - dnl ENABLE_NLS is not set, thusly conflicting with C++ which - dnl includes - AM_GNU_GETTEXT([external]) - 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.]) + AC_MSG_WARN([Could not find GTK+ 2.x, disabling user interface.]) WANT_GTK=no ]) fi @@ -513,24 +374,10 @@ 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 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) @@ -625,7 +472,6 @@ mips-sony-bsd|mips-sony-newsos4) ;; *-*-darwin*) no_dev_ptmx=1 - LIBS="$LIBS -lstdc++" ;; *-*-freebsd*) no_dev_ptmx=1 @@ -739,6 +585,7 @@ AC_CHECK_FRAMEWORK(AppKit, []) AC_CHECK_FRAMEWORK(Carbon, [#include ]) AC_CHECK_FRAMEWORK(IOKit, [#include ]) AC_CHECK_FRAMEWORK(CoreFoundation, [#include ]) +AC_CHECK_FRAMEWORK(Metal, []) dnl Select system-dependant source files. SERIALSRC=serial_unix.cpp @@ -747,16 +594,13 @@ 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 - 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 @@ -778,19 +622,12 @@ freebsd*) fi ;; netbsd*) - CAN_NATIVE_M68K=yes 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" @@ -876,7 +713,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]) @@ -907,7 +744,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 @@ -919,7 +755,7 @@ fi dnl BINCUE overrides if [[ "x$have_bincue" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS bincue_unix.cpp" + EXTRASYSSRCS="$EXTRASYSSRCS bincue.cpp" fi dnl libvhd overrides @@ -928,14 +764,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.]) @@ -1128,42 +956,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, [ @@ -1399,7 +1191,6 @@ AC_PATH_PROG([BLESS], "true") dnl Check for linker script support case $target_os:$target_cpu in linux*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";; -linux*:x86_64) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-x86_64.ld";; linux*:powerpc) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-ppc.ld";; netbsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";; freebsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/freebsd-i386.ld";; @@ -1429,38 +1220,11 @@ fi 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 override the addressing mode test order for Darwin -if [[ "x$OS_TYPE" = "xdarwin" ]]; then - ADDRESSING_TEST_ORDER="banks" -fi - 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 @@ -1484,13 +1248,17 @@ 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 AC_MSG_ERROR([Sorry, the JIT Compiler requires Direct Addressing, at least]) fi +if [[ "x$OS_TYPE" = "xdarwin" ]]; then + WANT_VOSF=no + LDFLAGS="$LDFLAGS -Wl,-no_pie -pagezero_size 0x1000" +fi + dnl Enable VOSF screen updates with this feature is requested and feasible if [[ "x$WANT_VOSF" = "xyes" -a "x$CAN_VOSF" = "xyes" ]]; then AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.]) @@ -1658,14 +1426,10 @@ 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. -if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then +if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" = "xyes" ]]; then JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o" DEFINES="$DEFINES -DUSE_JIT -DUSE_JIT_FPU" @@ -1879,11 +1643,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 @@ -1910,18 +1672,12 @@ 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 -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 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/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 87a9f2c55..db2a143bb 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -41,6 +41,21 @@ #endif #include #include + +#ifdef ENABLE_MACOSX_ETHERHELPER + +#ifdef __APPLE__ +#include +#endif + +#ifdef __linux__ +#include +#endif + +#include +#include +#endif + #include #include #include @@ -49,6 +64,7 @@ #include #include #include +#include #if defined(__FreeBSD__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__)) #include @@ -100,9 +116,17 @@ enum { NET_IF_ETHERTAP, NET_IF_TUNTAP, NET_IF_SLIRP, - NET_IF_VDE + NET_IF_VDE, + NET_IF_ETHERHELPER }; + +#ifdef ENABLE_MACOSX_ETHERHELPER +extern "C" { + extern FILE * run_tool(const char *if_name, const char *tool_name); +} +#endif + // Constants #if ENABLE_TUNTAP static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig"; @@ -132,6 +156,11 @@ static uint8 ether_addr[6]; // Our Ethernet address const bool ether_driver_opened = true; // Flag: is the MacOS driver opened? #endif + +#ifdef ENABLE_MACOSX_ETHERHELPER +static uint8 packet_buffer[2048]; +#endif + // Attached network protocols, maps protocol type to MacOS handler address static map net_protocols; @@ -145,6 +174,11 @@ static void ether_do_interrupt(void); static void slirp_add_redirs(); static int slirp_add_redir(const char *redir_str); +#ifdef ENABLE_MACOSX_ETHERHELPER +static int get_mac_address(const char* dev, unsigned char *addr); +static bool open_ether_helper(const std::string &if_name); +static int read_packet(void); +#endif /* * Start packet reception thread @@ -245,6 +279,9 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); +#ifdef ENABLE_MACOSX_ETHERHELPER + std::string slave_dev; +#endif if (name == NULL) return false; @@ -271,6 +308,10 @@ bool ether_init(void) net_if_type = NET_IF_VDE; printf("selected Ethernet device type VDE\n"); } +#endif +#ifdef ENABLE_MACOSX_ETHERHELPER + else if (strncmp(name, "etherhelper", 10) == 0) + net_if_type = NET_IF_ETHERHELPER; #endif else { net_if_type = NET_IF_SHEEPNET; @@ -324,6 +365,25 @@ bool ether_init(void) case NET_IF_SHEEPNET: strcpy(dev_name, "/dev/sheep_net"); break; +#ifdef ENABLE_MACOSX_ETHERHELPER + case NET_IF_ETHERHELPER: { + std::string device(name); + size_t pos; + + pos = device.find('/'); + if(pos != device.npos) { + slave_dev = device.substr(pos + 1); + } + + if(slave_dev.size() == 0) { + WarningAlert("No network device specified."); + return false; + } + + return open_ether_helper(slave_dev); + } + +#endif } #ifdef HAVE_LIBVDEPLUG @@ -836,6 +896,21 @@ static int16 ether_do_write(uint32 arg) return noErr; } else #endif +#ifdef ENABLE_MACOSX_ETHERHELPER + if (net_if_type == NET_IF_ETHERHELPER) { + unsigned short pkt_len; + + pkt_len = len; + if (write(fd, &pkt_len, 2) < 2) { + return excessCollsns; + } + + if (write(fd, packet, len) < len) { + return excessCollsns; + } + return noErr; + } else +#endif if (write(fd, packet, len) < 0) { D(bug("WARNING: Couldn't transmit packet\n")); return excessCollsns; @@ -969,6 +1044,13 @@ static void *receive_func(void *arg) if (res <= 0) break; +#ifdef ENABLE_MACOSX_ETHERHELPER + if (net_if_type == NET_IF_ETHERHELPER) { + if (read_packet() < 1) { + break; + } + } +#endif if (ether_driver_opened) { // Trigger Ethernet interrupt D(bug(" packet received, triggering Ethernet interrupt\n")); @@ -1008,6 +1090,18 @@ void ether_do_interrupt(void) ether_udp_read(packet, length, &from); } else +#endif +#ifdef ENABLE_MACOSX_ETHERHELPER + if (net_if_type == NET_IF_ETHERHELPER) { + unsigned short *pkt_len; + uint32 p = packet; + + pkt_len = (unsigned short *)packet_buffer; + length = *pkt_len; + memcpy(Mac2HostAddr(packet), pkt_len + 1, length); + ether_dispatch_packet(p, length); + break; + } else #endif { #ifdef HAVE_LIBVDEPLUG @@ -1023,7 +1117,7 @@ void ether_do_interrupt(void) length = read(fd, Mac2HostAddr(packet), 1514); #endif } - + if (length < 14) break; @@ -1141,3 +1235,144 @@ static int slirp_add_redir(const char *redir_str) WarningAlert(str); return -1; } + +#ifdef ENABLE_MACOSX_ETHERHELPER +static int get_mac_address(const char* dev, unsigned char *addr) +{ + struct ifaddrs *ifaddrs, *next; + int ret = -1; +#ifdef __APPLE__ + struct sockaddr_dl *sa; +#endif + +#ifdef __linux__ + struct sockaddr_ll *sa; +#endif + if (getifaddrs(&ifaddrs) != 0) { + perror("getifaddrs"); + return -1; + } + + next = ifaddrs; + while (next != NULL) { + switch (next->ifa_addr->sa_family) { +#ifdef __APPLE__ + case AF_LINK: + if (!strcmp(dev, next->ifa_name)) { + sa = (struct sockaddr_dl *)next->ifa_addr; + memcpy(addr, LLADDR(sa), 6); + ret = 0; + } + break; +#endif + +#ifdef __linux__ + case AF_PACKET: + if (!strcmp(dev, next->ifa_name)) { + sa = (struct sockaddr_ll *)next->ifa_addr; + memcpy(addr, sa->sll_addr, 6); + ret = 0; + } + break; +#endif + default: + break; + } + next = next->ifa_next; + } + + freeifaddrs(ifaddrs); + + return ret; +} + +static bool open_ether_helper(const std::string &if_name) +{ + FILE *fp; + char str[64]; + std::string dev_name; + size_t pos; + + fp = run_tool(if_name.c_str(), "etherhelpertool"); + if (fp == NULL) { + snprintf(str, sizeof(str), "Unable to run ether helper helper tool."); + WarningAlert(str); + return false; + } + + pos = if_name.find('/'); + dev_name = if_name; + if(pos != if_name.npos) { + dev_name.erase(pos); + } + + if(strncmp(if_name.c_str(), "tap", 3) != 0) { + if (get_mac_address(dev_name.c_str(), ether_addr) != 0) { + snprintf(str, sizeof(str), "Unable to find interface %s.", + dev_name.c_str()); + WarningAlert(str); + return false; + } + } else { + /* There is something special about this address. */ + pid_t p = getpid(); + ether_addr[0] = 0xfe; + ether_addr[1] = 0xfd; + ether_addr[2] = p >> 24; + ether_addr[3] = p >> 16; + ether_addr[4] = p >> 8; + ether_addr[5] = p; + } + + fd = dup(fileno(fp)); + fclose(fp); + + if (start_thread() == false) { + close(fd); + fd = -1; + return false; + } + + return true; +} + +static int read_packet() +{ + int index; + unsigned short *pkt_len; + int ret = -1; + + pkt_len = (unsigned short *)packet_buffer; + + index = 0; + while (1) { + if (index < 2) { + ret = read(fd, packet_buffer + index, 2 - index); + } else { + ret = read(fd, packet_buffer + index, *pkt_len - index + 2); + } + + if (ret < 1) { + fprintf(stderr, "%s: read() returned %d.\n", __func__, ret); + break; + } + + index += ret; + + if (index > 1) { + if (*pkt_len > (sizeof(packet_buffer) + 2)) { + fprintf(stderr, "%s: pkt_len (%d) too large.\n", __func__, *pkt_len); + break; + } + + if (index == (*pkt_len + 2)) { + ret = *pkt_len; + break; + } + } + } + + return ret; +} + +#endif diff --git a/BasiliskII/src/Unix/flatpak/BasiliskII128.png b/BasiliskII/src/Unix/flatpak/BasiliskII128.png new file mode 100644 index 000000000..5cccc26b1 Binary files /dev/null and b/BasiliskII/src/Unix/flatpak/BasiliskII128.png differ diff --git a/BasiliskII/src/Unix/flatpak/BasiliskII64.png b/BasiliskII/src/Unix/flatpak/BasiliskII64.png new file mode 100644 index 000000000..9554ee420 Binary files /dev/null and b/BasiliskII/src/Unix/flatpak/BasiliskII64.png differ diff --git a/BasiliskII/src/Unix/flatpak/net.cebix.basilisk.desktop b/BasiliskII/src/Unix/flatpak/net.cebix.basilisk.desktop new file mode 100644 index 000000000..5d2d7acff --- /dev/null +++ b/BasiliskII/src/Unix/flatpak/net.cebix.basilisk.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Basilisk II +GenericName=Macintosh Emulator +Comment=68k Macintosh Emulator +Categories=System;Emulator; +Icon=net.cebix.basilisk +Exec=BasiliskII +Terminal=false diff --git a/BasiliskII/src/Unix/flatpak/net.cebix.basilisk.metainfo.xml b/BasiliskII/src/Unix/flatpak/net.cebix.basilisk.metainfo.xml new file mode 100644 index 000000000..a5e0dd94b --- /dev/null +++ b/BasiliskII/src/Unix/flatpak/net.cebix.basilisk.metainfo.xml @@ -0,0 +1,38 @@ + + + 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 + + + + + + +

Stability fixes. Happy Juneteenth!

+
+
+ + +

First Flathub release.

+
+
+
+
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) } -} diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp old mode 100644 new mode 100755 index ce4db79e5..a041e4091 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -31,52 +31,25 @@ # include #endif -#ifndef USE_SDL_VIDEO -# include -#endif - #ifdef HAVE_PTHREADS # 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 -# ifdef HAVE_GNOMEUI -# include -# endif # if !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND) # include # endif #endif -#ifdef ENABLE_XF86_DGA -# include -# include -#endif - #include using std::string; -#include "cpu_emulation.h" #include "sys.h" #include "rom_patches.h" #include "xpram.h" @@ -89,14 +62,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 -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif - #ifdef ENABLE_MON # include "mon.h" #endif @@ -104,49 +72,9 @@ 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; -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 -#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 @@ -167,18 +95,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 - #if !defined(HAVE_PTHREADS) static struct sigaction timer_sa; // sigaction used for timer @@ -193,23 +109,13 @@ 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 - // Prototypes 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; @@ -231,23 +137,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 */ @@ -279,16 +168,18 @@ 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); 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); + m68k_dumpstate(stderr, &nextpc); +#else extern void m68k_dumpstate(uaecptr *nextpc); m68k_dumpstate(&nextpc); #endif @@ -304,7 +195,6 @@ static void sigsegv_dump_state(sigsegv_info_t *sip) QuitEmulator(); } - /* * Update virtual clock and trigger interrupts if necessary */ @@ -388,8 +278,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 @@ -397,25 +286,16 @@ int main(int argc, char **argv) char str[256]; // Initialize variables - RAMBaseHost = NULL; - ROMBaseHost = NULL; srand(time(NULL)); 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 1023*1024*1024) // Cap to 1023MB (APD crashes at 1GB) - RAMSize = 1023*1024*1024; - -#if REAL_ADDRESSING || 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) { - 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 REAL_ADDRESSING - RAMBaseMac = Host2MacAddr(RAMBaseHost); - 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(); - } - -#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(); 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)); - -#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); @@ -845,9 +506,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) { @@ -887,10 +545,8 @@ void QuitEmulator(void) { D(bug("QuitEmulator\n")); -#if EMULATED_68K // Exit 680x0 emulation Exit680x0(); -#endif #if defined(USE_CPU_EMUL_SERVICES) // Show statistics @@ -931,42 +587,12 @@ 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 - -#if REAL_ADDRESSING - // Delete Low Memory area - if (lm_area_mapped) - vm_release(0, 0x2000); -#endif - - // Exit VM wrappers - vm_exit(); - // Exit system routines SysExit(); // Exit preferences PrefsExit(); - // 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) @@ -976,33 +602,17 @@ 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 -#if !EMULATED_68K && defined(__NetBSD__) - m68k_sync_icache(start, size); -#endif -} - - /* * SIGINT handler, enters mon */ #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); + m68k_dumpstate(stderr, &nextpc); +#else extern void m68k_dumpstate(uaecptr *nextpc); m68k_dumpstate(&nextpc); #endif @@ -1132,38 +742,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) @@ -1258,312 +847,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 */ @@ -1579,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); @@ -1596,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 637e1e672..966a369a2 100644 --- a/BasiliskII/src/Unix/prefs_editor_gtk.cpp +++ b/BasiliskII/src/Unix/prefs_editor_gtk.cpp @@ -28,10 +28,6 @@ #include #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 */ @@ -71,7 +64,7 @@ static void read_settings(void); struct opt_desc { int label_id; - GtkSignalFunc func; + GCallback func; }; struct combo_desc { @@ -84,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) @@ -137,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(); @@ -151,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++; } @@ -174,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)); @@ -280,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); @@ -296,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; } @@ -400,79 +374,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,13 +423,12 @@ 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)); - 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); @@ -508,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); @@ -524,12 +450,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[] = { @@ -560,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); @@ -569,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)); @@ -586,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); @@ -613,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); } @@ -630,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"); @@ -651,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); @@ -665,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) @@ -858,47 +776,27 @@ static GtkWidget *l_frameskip, *l_display_x, *l_display_y; static int display_type; static int dis_width, dis_height; -#ifdef ENABLE_FBDEV_DGA -static GtkWidget *w_fbdev_name, *w_fbdevice_file; -static GtkWidget *l_fbdev_name, *l_fbdevice_file; -static char fbdev_name[256]; -#endif - -static GtkWidget *w_dspdevice_file, *w_mixerdevice_file; - // Hide/show graphics widgets static void hide_show_graphics_widgets(void) { switch (display_type) { case DISPLAY_WINDOW: gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip); -#ifdef ENABLE_FBDEV_DGA - gtk_widget_show(w_display_x); gtk_widget_show(l_display_x); - gtk_widget_show(w_display_y); gtk_widget_show(l_display_y); - gtk_widget_hide(w_fbdev_name); gtk_widget_hide(l_fbdev_name); -#endif break; case DISPLAY_SCREEN: gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip); -#ifdef ENABLE_FBDEV_DGA - gtk_widget_hide(w_display_x); gtk_widget_hide(l_display_x); - gtk_widget_hide(w_display_y); gtk_widget_hide(l_display_y); - gtk_widget_show(w_fbdev_name); gtk_widget_show(l_fbdev_name); -#endif break; } } // "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(); } @@ -913,46 +811,85 @@ static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);} static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);} // 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 -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; -#ifdef ENABLE_FBDEV_DGA - fbdev_name[0] = 0; -#endif const char *str = PrefsFindString("screen"); if (str) { if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2) display_type = DISPLAY_WINDOW; -#ifdef ENABLE_FBDEV_DGA - else if (sscanf(str, "dga/%255s", fbdev_name) == 1) -#else - else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2) -#endif + 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)); @@ -967,33 +904,20 @@ static void read_graphics_settings(void) sprintf(pref, "win/%d/%d", dis_width, dis_height); break; case DISPLAY_SCREEN: -#ifdef ENABLE_FBDEV_DGA - str = gtk_entry_get_text(GTK_ENTRY(w_fbdev_name)); - sprintf(pref, "dga/%s", str); -#else sprintf(pref, "dga/%d/%d", dis_width, dis_height); -#endif break; default: PrefsRemoveItem("screen"); return; } PrefsReplaceString("screen", pref); - -#ifdef ENABLE_FBDEV_DGA - str = get_file_entry_path(w_fbdevice_file); - if (str && strlen(str)) - PrefsReplaceString("fbdevicefile", str); - else - PrefsRemoveItem("fbdevicefile"); +#ifdef USE_SDL_VIDEO + read_SDL_graphics_settings(); #endif - PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file)); - PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file)); } // 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]; @@ -1094,30 +1018,43 @@ 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 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); +#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_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_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); - w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile"); + 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)); - 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 */ @@ -1506,7 +1443,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 +1460,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"); @@ -1591,7 +1526,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); @@ -1599,7 +1534,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); @@ -1708,23 +1643,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/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index a92cd6401..5d2ab5327 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -28,30 +28,24 @@ using std::string; #include "prefs.h" - // Platform-specific preferences items prefs_desc platform_prefs_items[] = { - {"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"}, - {"keycodefile", TYPE_STRING, false, "path of keycode translation file"}, {"fbdevicefile", TYPE_STRING, false, "path of frame buffer device specification file"}, - {"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"}, - {"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"}, {"dsp", TYPE_STRING, false, "audio output (dsp) device name"}, {"mixer", TYPE_STRING, false, "audio mixer device name"}, -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif {"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 */ @@ -94,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); @@ -108,35 +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 -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - PrefsAddBool("ignoresegv", false); -#endif PrefsAddBool("idlewait", true); +#ifdef USE_SDL_VIDEO + PrefsReplaceString("sdlrender", "software"); + PrefsReplaceBool("sdl_vsync", true); +#endif } diff --git a/BasiliskII/src/Unix/sys_unix.cpp b/BasiliskII/src/Unix/sys_unix.cpp index 9c25feb50..9cfc06cec 100755 --- a/BasiliskII/src/Unix/sys_unix.cpp +++ b/BasiliskII/src/Unix/sys_unix.cpp @@ -59,7 +59,7 @@ #include "disk_unix.h" #if defined(BINCUE) -#include "bincue_unix.h" +#include "bincue.h" #endif @@ -1407,8 +1407,13 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve mac_file_handle *fh = (mac_file_handle *)arg; if (!fh) return false; - - // Not supported under Linux + +#if defined(BINCUE) + if (fh->is_bincue) + return CDScan_bincue(fh->bincue_fd,start_m,start_s,start_f,reverse); +#endif + + // Not supported outside bincue return false; } @@ -1422,6 +1427,11 @@ void SysCDSetVolume(void *arg, uint8 left, uint8 right) mac_file_handle *fh = (mac_file_handle *)arg; if (!fh) return; + +#if defined(BINCUE) + if (fh->is_bincue) + CDSetVol_bincue(fh->bincue_fd,left,right); +#endif if (fh->is_cdrom) { #if defined(__linux__) @@ -1450,6 +1460,12 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) return; left = right = 0; + +#if defined(BINCUE) + if (fh->is_bincue) + CDGetVol_bincue(fh->bincue_fd,&left,&right); +#endif + if (fh->is_cdrom) { #if defined(__linux__) cdrom_volctrl vol; diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index 7ac37f298..4f0481d9a 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -25,18 +25,16 @@ #error "Your compiler is not ANSI. Get a real one." #endif -#include "config.h" +#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 #endif +#include + #include #include #include @@ -66,41 +64,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 @@ -117,11 +91,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 @@ -219,7 +191,7 @@ typedef uae_u32 uaecptr; /* Timing functions */ extern uint64 GetTicks_usec(void); -extern void Delay_usec(uint32 usec); +extern void Delay_usec(uint64 usec); /* Spinlocks */ #ifdef __GNUC__ @@ -490,4 +462,12 @@ static inline uae_u32 do_byteswap_16(uae_u32 v) #endif #define REGPARAM2 +#ifndef UNUSED +#define UNUSED(x) ((void)x) +#endif + +#define unlikely(x) __builtin_expect(!!(x), 0) +#define ALWAYS_INLINE inline __attribute__((always_inline)) +#define memptr uint32 + #endif diff --git a/BasiliskII/src/Unix/timer_unix.cpp b/BasiliskII/src/Unix/timer_unix.cpp index 709194cd4..f00420e21 100644 --- a/BasiliskII/src/Unix/timer_unix.cpp +++ b/BasiliskII/src/Unix/timer_unix.cpp @@ -44,8 +44,8 @@ static inline void mach_current_time(tm_time_t &t) { host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &host_clock); host_clock_inited = true; } - - clock_get_time(host_clock, &t); + + clock_get_time(host_clock, (mach_timespec_t *)&t); } #endif @@ -264,7 +264,7 @@ uint64 GetTicks_usec(void) #define USE_COND_TIMEDWAIT #endif -void Delay_usec(uint32 usec) +void Delay_usec(uint64 usec) { int was_error; diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp deleted file mode 100644 index 70aacb2da..000000000 --- a/BasiliskII/src/Unix/video_x.cpp +++ /dev/null @@ -1,2790 +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; - -// Mac Screen Width and Height -uint32 MacScreenWidth; -uint32 MacScreenHeight; - -// 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 !REAL_ADDRESSING && !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; - if (TwentyFourBitAddressing) - monitor.set_mac_frame_base(MacFrameBaseMac24Bit); - else - 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); - } -} - -// This struct is designed to match the ones generated by GIMP in -// BasiliskII_*_icon.c -struct gimp_image { - unsigned int width; - unsigned int height; - unsigned int bytes_per_pixel; - unsigned char pixel_data[0]; // Variable-length -}; - -// These were generated by using 'icns2png -x -// ../MacOSX/BasiliskII.icns', then using GIMP to convert the -// resulting .png files into "C source code (*.c)". GIMP doesn't -// generate corresponding .h files with extern declarations, so just -// #include the .c files here. -#include "BasiliskII_32x32x32_icon.c" -#include "BasiliskII_128x128x32_icon.c" - -// Set window icons -static void set_window_icons(Window w) -{ - // As per the _NET_WM_ICON documentation at - // https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472568384, - // "The first two cardinals are width, height." - const unsigned int HEADER_SIZE = 2; - // We will pass 32-bit values to XChangeProperty() - const unsigned int FORMAT = 32; - - // Icon data from GIMP to be converted and passed to the - // Window Manager - const struct gimp_image* const icons[] = - {(struct gimp_image *) &icon_32x32x32, - (struct gimp_image *) &icon_128x128x32}; - const unsigned int num_icons = sizeof(icons) / sizeof(icons[0]); - unsigned int icon; - - // Work out how big the buffer needs to be to store all of our icons - unsigned int buffer_size = 0; - for (icon = 0; icon < num_icons; icon++) { - buffer_size += HEADER_SIZE + - icons[icon]->width * icons[icon]->height; - } - - // As per the XChangeProperty() man page, "If the specified - // format is 32, the property data must be a long array." - unsigned long buffer[buffer_size]; - // This points to the start of the current icon within buffer - unsigned long *buffer_icon = buffer; - - // Copy the icons into the buffer - for (icon = 0; icon < num_icons; icon++) { - const unsigned int pixel_count = icons[icon]->width * - icons[icon]->height; - assert(icons[icon]->bytes_per_pixel == 4); - buffer_icon[0] = icons[icon]->width; - buffer_icon[1] = icons[icon]->height; - unsigned long *const buffer_pixels = buffer_icon + HEADER_SIZE; - - unsigned int i; - for (i = 0; i < pixel_count; i++) { - const unsigned char *src = - &icons[icon]->pixel_data[i * icons[icon]->bytes_per_pixel]; - buffer_pixels[i] = (src[3] << 24 | - src[0] << 16 | - src[1] << 8 | - src[2]); - } - - buffer_icon += HEADER_SIZE + pixel_count; - } - - Atom net_wm_icon = XInternAtom(x_display, "_NET_WM_ICON", False); - if (net_wm_icon == None) { - ErrorAlert(STR_X_ICON_ATOM_ALLOC_ERR); - // We can still continue running, just without an icon - return; - } - XChangeProperty(x_display, w, net_wm_icon, XA_CARDINAL, FORMAT, - PropModeReplace, (const unsigned char *) buffer, - buffer_size); -} - -// 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 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, 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 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, 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(); - // set Mac screen global variabls - MacScreenWidth = VIDEO_MODE_X; - MacScreenHeight = VIDEO_MODE_Y; - D(bug("Set Mac Screen Width: %d, Mac Screen Height: %d\n", MacScreenWidth, MacScreenHeight)); - - // 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; - mode_str = PrefsFindString("screen"); - - // Determine display type and default dimensions - int default_width, default_height; - if (classic) { - default_width = 512; - default_height = 342; - } 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; -#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); - - // for classic Mac, make sure the display width is divisible by 8 - if (classic) { - default_width = (default_width / 8) * 8; - } - - // 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(default_width, default_height, 0x80, default_width/8, 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 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 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 && (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 - 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 diff --git a/BasiliskII/src/Windows/BasiliskII.ico b/BasiliskII/src/Windows/BasiliskII.ico index eb3ac0ef0..0c88aca19 100755 Binary files a/BasiliskII/src/Windows/BasiliskII.ico and b/BasiliskII/src/Windows/BasiliskII.ico differ diff --git a/BasiliskII/src/Windows/BasiliskII.sln b/BasiliskII/src/Windows/BasiliskII.sln index 1c4b7a1f9..65b6b30fc 100644 --- a/BasiliskII/src/Windows/BasiliskII.sln +++ b/BasiliskII/src/Windows/BasiliskII.sln @@ -1,140 +1,140 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BasiliskII", "BasiliskII.vcxproj", "{1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}" - ProjectSection(ProjectDependencies) = postProject - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} = {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} = {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "build68k", "build68k.vcxproj", "{7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencpu", "gencpu.vcxproj", "{1A9EA738-8DA7-422F-9E0D-BE92893C0E48}" - ProjectSection(ProjectDependencies) = postProject - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} = {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencomp", "gencomp.vcxproj", "{95933FE9-C27C-41F0-B4AF-EAAADE94FD04}" - ProjectSection(ProjectDependencies) = postProject - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} = {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDLmain", "..\..\..\..\SDL-1.2.15\VisualC\SDLmain\SDLmain.vcxproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "..\..\..\..\SDL-1.2.15\VisualC\SDL\SDL.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug JIT|x64 = Debug JIT|x64 - Debug JIT|x86 = Debug JIT|x86 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release JIT|x64 = Release JIT|x64 - Release JIT|x86 = Release JIT|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x64.ActiveCfg = Debug JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x64.Build.0 = Debug JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x86.ActiveCfg = Debug JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x86.Build.0 = Debug JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x64.ActiveCfg = Debug|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x64.Build.0 = Debug|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x86.ActiveCfg = Debug|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x86.Build.0 = Debug|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x64.ActiveCfg = Release JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x64.Build.0 = Release JIT|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x86.ActiveCfg = Release JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x86.Build.0 = Release JIT|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x64.ActiveCfg = Release|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x64.Build.0 = Release|x64 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x86.ActiveCfg = Release|Win32 - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x86.Build.0 = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x64.ActiveCfg = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x64.Build.0 = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x86.Build.0 = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x64.ActiveCfg = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x64.Build.0 = Debug|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x86.ActiveCfg = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x86.Build.0 = Debug|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x64.ActiveCfg = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x64.Build.0 = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x86.ActiveCfg = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x86.Build.0 = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x64.ActiveCfg = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x64.Build.0 = Release|x64 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x86.ActiveCfg = Release|Win32 - {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x86.Build.0 = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x64.ActiveCfg = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x64.Build.0 = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x86.Build.0 = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x64.ActiveCfg = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x64.Build.0 = Debug|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x86.ActiveCfg = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x86.Build.0 = Debug|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x64.ActiveCfg = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x64.Build.0 = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x86.ActiveCfg = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x86.Build.0 = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x64.ActiveCfg = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x64.Build.0 = Release|x64 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x86.ActiveCfg = Release|Win32 - {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x86.Build.0 = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x64.ActiveCfg = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x64.Build.0 = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x86.Build.0 = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x64.ActiveCfg = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x64.Build.0 = Debug|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x86.ActiveCfg = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x86.Build.0 = Debug|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x64.ActiveCfg = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x64.Build.0 = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x86.ActiveCfg = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x86.Build.0 = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x64.ActiveCfg = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x64.Build.0 = Release|x64 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x86.ActiveCfg = Release|Win32 - {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x86.Build.0 = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x64.ActiveCfg = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x64.Build.0 = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x86.Build.0 = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.ActiveCfg = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.Build.0 = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x64.ActiveCfg = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x64.Build.0 = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x86.ActiveCfg = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x86.Build.0 = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.ActiveCfg = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.Build.0 = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x64.ActiveCfg = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x64.Build.0 = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x86.ActiveCfg = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x86.Build.0 = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.ActiveCfg = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.Build.0 = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x64.ActiveCfg = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x64.Build.0 = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x86.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x86.Build.0 = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BasiliskII", "BasiliskII.vcxproj", "{1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}" + ProjectSection(ProjectDependencies) = postProject + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} = {1A9EA738-8DA7-422F-9E0D-BE92893C0E48} + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} = {95933FE9-C27C-41F0-B4AF-EAAADE94FD04} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "build68k", "build68k.vcxproj", "{7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencpu", "gencpu.vcxproj", "{1A9EA738-8DA7-422F-9E0D-BE92893C0E48}" + ProjectSection(ProjectDependencies) = postProject + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} = {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencomp", "gencomp.vcxproj", "{95933FE9-C27C-41F0-B4AF-EAAADE94FD04}" + ProjectSection(ProjectDependencies) = postProject + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} = {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2", "..\..\..\external\SDL\VisualC\SDL\SDL.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2main", "..\..\..\external\SDL\VisualC\SDLmain\SDLmain.vcxproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug JIT|x64 = Debug JIT|x64 + Debug JIT|x86 = Debug JIT|x86 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release JIT|x64 = Release JIT|x64 + Release JIT|x86 = Release JIT|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x64.ActiveCfg = Debug JIT|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x64.Build.0 = Debug JIT|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x86.ActiveCfg = Debug JIT|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug JIT|x86.Build.0 = Debug JIT|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x64.ActiveCfg = Debug|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x64.Build.0 = Debug|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x86.ActiveCfg = Debug|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Debug|x86.Build.0 = Debug|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x64.ActiveCfg = Release JIT|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x64.Build.0 = Release JIT|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x86.ActiveCfg = Release JIT|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release JIT|x86.Build.0 = Release JIT|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x64.ActiveCfg = Release|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x64.Build.0 = Release|x64 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x86.ActiveCfg = Release|Win32 + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0}.Release|x86.Build.0 = Release|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x64.ActiveCfg = Debug|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x64.Build.0 = Debug|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x86.ActiveCfg = Debug|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug JIT|x86.Build.0 = Debug|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x64.ActiveCfg = Debug|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x64.Build.0 = Debug|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x86.ActiveCfg = Debug|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Debug|x86.Build.0 = Debug|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x64.ActiveCfg = Release|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x64.Build.0 = Release|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x86.ActiveCfg = Release|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release JIT|x86.Build.0 = Release|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x64.ActiveCfg = Release|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x64.Build.0 = Release|x64 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x86.ActiveCfg = Release|Win32 + {7BCEAB0D-0C62-46E1-BA1E-AF42798B67D0}.Release|x86.Build.0 = Release|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x64.ActiveCfg = Debug|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x64.Build.0 = Debug|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x86.ActiveCfg = Debug|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug JIT|x86.Build.0 = Debug|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x64.ActiveCfg = Debug|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x64.Build.0 = Debug|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x86.ActiveCfg = Debug|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Debug|x86.Build.0 = Debug|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x64.ActiveCfg = Release|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x64.Build.0 = Release|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x86.ActiveCfg = Release|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release JIT|x86.Build.0 = Release|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x64.ActiveCfg = Release|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x64.Build.0 = Release|x64 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x86.ActiveCfg = Release|Win32 + {1A9EA738-8DA7-422F-9E0D-BE92893C0E48}.Release|x86.Build.0 = Release|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x64.ActiveCfg = Debug|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x64.Build.0 = Debug|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x86.ActiveCfg = Debug|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug JIT|x86.Build.0 = Debug|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x64.ActiveCfg = Debug|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x64.Build.0 = Debug|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x86.ActiveCfg = Debug|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Debug|x86.Build.0 = Debug|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x64.ActiveCfg = Release|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x64.Build.0 = Release|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x86.ActiveCfg = Release|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release JIT|x86.Build.0 = Release|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x64.ActiveCfg = Release|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x64.Build.0 = Release|x64 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x86.ActiveCfg = Release|Win32 + {95933FE9-C27C-41F0-B4AF-EAAADE94FD04}.Release|x86.Build.0 = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x64.ActiveCfg = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x64.Build.0 = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x86.ActiveCfg = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug JIT|x86.Build.0 = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.ActiveCfg = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.Build.0 = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x64.ActiveCfg = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x64.Build.0 = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x86.ActiveCfg = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release JIT|x86.Build.0 = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.ActiveCfg = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.Build.0 = Release|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x64.ActiveCfg = Debug|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x64.Build.0 = Debug|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x86.ActiveCfg = Debug|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug JIT|x86.Build.0 = Debug|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.ActiveCfg = Debug|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x86.Build.0 = Debug|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x64.ActiveCfg = Release|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x64.Build.0 = Release|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x86.ActiveCfg = Release|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release JIT|x86.Build.0 = Release|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.ActiveCfg = Release|Win32 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/BasiliskII/src/Windows/BasiliskII.vcxproj b/BasiliskII/src/Windows/BasiliskII.vcxproj index cd05c309f..4437453dc 100644 --- a/BasiliskII/src/Windows/BasiliskII.vcxproj +++ b/BasiliskII/src/Windows/BasiliskII.vcxproj @@ -1,685 +1,697 @@ - - - - - Debug JIT - Win32 - - - Debug JIT - x64 - - - Debug - Win32 - - - Debug - x64 - - - Release JIT - Win32 - - - Release JIT - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {81ce8daf-ebb2-4761-8e45-b71abcca8c68} - - - {da956fd3-e142-46f2-9dd5-c78bebb56b7a} - - - - {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0} - Win32Proj - BasiliskII - 8.1 - - - - Application - true - v140_xp - Unicode - - - Application - true - v140_xp - Unicode - - - Application - true - v140_xp - Unicode - - - Application - true - v140_xp - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - false - v140_xp - true - Unicode - - - Application - false - v140_xp - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - true - - - true - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - true - - - false - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - false - - - false - $(Configuration)\$(ProjectName)\ - ClCompile - - - ClCompile - false - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;USE_JIT;USE_JIT_FPU;JIT_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - - Level3 - Disabled - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;USE_JIT;USE_JIT_FPU;JIT_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;USE_JIT;USE_JIT_FPU;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - Level3 - - - MaxSpeed - true - true - HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;USE_JIT;USE_JIT_FPU;%(PreprocessorDefinitions) - ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\..\SDL-1.2.15\include - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - $(IntDir)%(RelativeDir) - - - Windows - true - true - true - WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) - - - cd ..\uae_cpu -"$(ToolsDir)gencpu" -"$(ToolsDir)gencomp" - - - - Generating CPU emulation sources... - - - ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) - - - $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe - - - - - - \ No newline at end of file + + + + + Debug JIT + Win32 + + + Debug JIT + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release JIT + Win32 + + + Release JIT + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + + + + {1AAA5D96-9498-4EB5-A436-0143E2B7A0B0} + Win32Proj + BasiliskII + 8.1 + + + + Application + true + v140_xp + Unicode + + + Application + true + v140_xp + Unicode + + + Application + true + v140_xp + Unicode + + + Application + true + v140_xp + Unicode + + + Application + false + v140_xp + true + Unicode + + + Application + false + v140_xp + true + Unicode + + + Application + false + v140_xp + true + Unicode + + + Application + false + v140_xp + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(Configuration)\$(ProjectName)\ + ClCompile + + + ClCompile + true + + + true + $(Configuration)\$(ProjectName)\ + ClCompile + + + ClCompile + true + + + false + $(Configuration)\$(ProjectName)\ + ClCompile + + + ClCompile + false + + + false + $(Configuration)\$(ProjectName)\ + ClCompile + + + ClCompile + false + + + + + + Level3 + Disabled + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + BasiliskII_MSVC_PostBuild.bat "$(SolutionDir)" "$(Platform)" "$(Configuration)" "$(OutDir)" + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;USE_JIT;USE_JIT_FPU;JIT_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + BasiliskII_MSVC_PostBuild.bat "$(SolutionDir)" "$(Platform)" "$(Configuration)" "$(OutDir)" + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;USE_JIT;USE_JIT_FPU;JIT_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + true + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + BasiliskII_MSVC_PostBuild.bat "$(SolutionDir)" "$(Platform)" "$(Configuration)" "$(OutDir)" + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + true + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;USE_JIT;USE_JIT_FPU;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + true + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + BasiliskII_MSVC_PostBuild.bat "$(SolutionDir)" "$(Platform)" "$(Configuration)" "$(OutDir)" + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;DIRECT_ADDRESSING;UNALIGNED_PROFITABLE;MSVC_INTRINSICS;OPTIMIZED_FLAGS;SAHF_SETO_PROFITABLE;FPU_IEEE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;OPTIMIZED_FLAGS;USE_JIT;USE_JIT_FPU;%(PreprocessorDefinitions) + ..\include;..\uae_cpu;.;..\CrossPlatform;..\slirp;..\..\..\external\SDL\include + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + $(IntDir)%(RelativeDir) + + + Windows + true + true + true + WS2_32.lib;IPHlpApi.lib;%(AdditionalDependencies) + + + cd ..\uae_cpu +"$(ToolsDir)gencpu" +"$(ToolsDir)gencomp" + + + + Generating CPU emulation sources... + + + ..\uae_cpu\cpustbl.cpp;..\uae_cpu\cpustbl_nf.cpp;..\uae_cpu\cputbl.h;..\uae_cpu\cpuemu.cpp;..\uae_cpu\cpuemu_nf.cpp;..\uae_cpu\compstbl.cpp;..\uae_cpu\comptbl.h;..\uae_cpu\compemu.cpp;%(Outputs) + + + $(ToolsDir)gencpu.exe;$(ToolsDir)gencomp.exe + + + + + + diff --git a/BasiliskII/src/Windows/BasiliskII.vcxproj.filters b/BasiliskII/src/Windows/BasiliskII.vcxproj.filters index 50eae3d1a..2d460b26f 100644 --- a/BasiliskII/src/Windows/BasiliskII.vcxproj.filters +++ b/BasiliskII/src/Windows/BasiliskII.vcxproj.filters @@ -270,6 +270,9 @@ Source Files + + Source Files + Source Files diff --git a/BasiliskII/src/Windows/BasiliskII_MSVC_PostBuild.bat b/BasiliskII/src/Windows/BasiliskII_MSVC_PostBuild.bat new file mode 100644 index 000000000..54d63182a --- /dev/null +++ b/BasiliskII/src/Windows/BasiliskII_MSVC_PostBuild.bat @@ -0,0 +1,7 @@ +@echo off +set SOLUTION_DIR=%~1 +set PLATFORM=%~2 +set CONFIGURATION=%~3 +set CONFIGURATION=%CONFIGURATION: JIT=% +set OUT_DIR=%~4 +xcopy /y "%SOLUTION_DIR%%PLATFORM%\%CONFIGURATION%\SDL2.dll" "%OUT_DIR%" diff --git a/BasiliskII/src/Windows/Makefile.in b/BasiliskII/src/Windows/Makefile.in index dfa59a60e..a0f795ef9 100755 --- a/BasiliskII/src/Windows/Makefile.in +++ b/BasiliskII/src/Windows/Makefile.in @@ -31,6 +31,8 @@ SLIRP_SRCS = \ ../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=$(OBJ_DIR)/slirp-%.o) +USE_BINCUE = @USE_BINCUE@ + LN_S = @LN_S@ WINDRES = @WINDRES@ CC = @CC@ @@ -39,9 +41,10 @@ CFLAGS = @CFLAGS@ $(SDL_CFLAGS) CXXFLAGS = @CXXFLAGS@ $(SDL_CFLAGS) CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../CrossPlatform @CPUINCLUDES@ -I../slirp DEFS = @DEFS@ @DEFINES@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -lwsock32 -liphlpapi +LDFLAGS = @LDFLAGS@ -Wl,-Bstatic +LIBS = @LIBS@ -lws2_32 -lwsock32 -liphlpapi CPUSRCS = @CPUSRCS@ +EXTRASRCS = @EXTRASRCS@ HOST_CC = gcc HOST_CXX = g++ @@ -63,12 +66,12 @@ 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 \ + ../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 \ ../dummy/prefs_editor_dummy.cpp BasiliskII.rc \ - $(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(SLIRP_OBJS) + $(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(EXTRASRCS) $(SLIRP_OBJS) UI_SRCS = ../prefs.cpp prefs_windows.cpp prefs_editor_gtk.cpp xpram_windows.cpp \ ../prefs_items.cpp ../user_strings.cpp user_strings_windows.cpp util_windows.cpp \ @@ -118,7 +121,7 @@ $(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS) $(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS) $(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS) - $(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin + $(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) -Wl,-Bdynamic $(GTK_LIBS) -Wl,-Bstatic -mwindows -static-libgcc mostlyclean: rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak @@ -149,7 +152,7 @@ $(OBJ_DIR)/%.o : %.cpp $(OBJ_DIR)/%.o : %.s $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@ $(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp - $(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@ + $(CXX) -O2 -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@ # Windows resources $(OBJ_DIR)/%.o: %.rc diff --git a/BasiliskII/src/Windows/b2ether/packet32.cpp b/BasiliskII/src/Windows/b2ether/packet32.cpp index 72efb1fe9..93dd647f8 100755 --- a/BasiliskII/src/Windows/b2ether/packet32.cpp +++ b/BasiliskII/src/Windows/b2ether/packet32.cpp @@ -26,7 +26,6 @@ #include #include #include "cpu_emulation.h" -typedef unsigned long ULONG_PTR, *PULONG_PTR; // VC6 does not have this, Platform SDK has. // In case of errors, try to comment out, the needed 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/configure.ac b/BasiliskII/src/Windows/configure.ac index fc9027047..20e11eedc 100755 --- a/BasiliskII/src/Windows/configure.ac +++ b/BasiliskII/src/Windows/configure.ac @@ -1,18 +1,14 @@ 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]) +#AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no]) dnl JIT compiler options. AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes]) @@ -36,6 +32,9 @@ AC_ARG_ENABLE(fpe, dnl External packages. AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes]) +AC_ARG_WITH(bincue, + AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode])) + dnl Addressing modes. AC_ARG_ENABLE(addressing, [ --enable-addressing=AM specify the addressing mode to use [default=fastest]], @@ -75,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 ]) @@ -85,6 +84,14 @@ AC_SUBST(WANT_GTK) dnl We use 64-bit file size support if possible. AC_SYS_LARGEFILE +dnl BINCUE +AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no]) +AS_IF([test "x$have_bincue" = "xyes" ], [ + DEFINES="$DEFINES -DBINCUE" + CPPFLAGS="$CPPFLAGS -DBINCUE" + AC_SUBST(USE_BINCUE, yes) +], [AC_SUBST(USE_BINCUE, no)]) + dnl Checks for header files. AC_HEADER_STDC @@ -131,7 +138,7 @@ AC_CACHE_CHECK([whether VirtualProtect works], #define HAVE_WIN32_VM 1 #define CONFIGURE_TEST_VM_MAP #define TEST_VM_PROT_$test_def - #include "../Unix/vm_alloc.cpp" + #include "../CrossPlatform/vm_alloc.cpp" ], ac_cv_VirtualProtect_works=no, rm -f core, dnl When cross-compiling, assume it works ac_cv_VirtualProtect_works="yes" @@ -141,7 +148,7 @@ AC_CACHE_CHECK([whether VirtualProtect works], #define HAVE_WIN32_VM 1 #define CONFIGURE_TEST_VM_MAP #define TEST_VM_PROT_RDWR_WRITE - #include "../Unix/vm_alloc.cpp" + #include "../CrossPlatform/vm_alloc.cpp" ], , ac_cv_VirtualProtect_works=no, dnl When cross-compiling, assume it works ac_cv_VirtualProtect_works="yes" @@ -163,8 +170,8 @@ AC_CACHE_CHECK([whether your system supports Windows exceptions], AC_TRY_RUN([ #define HAVE_WIN32_EXCEPTIONS 1 #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../Unix/vm_alloc.cpp" - #include "../Unix/sigsegv.cpp" + #include "../CrossPlatform/vm_alloc.cpp" + #include "../CrossPlatform/sigsegv.cpp" ], ac_cv_have_win32_exceptions=yes, ac_cv_have_win32_exceptions=no, @@ -188,8 +195,8 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler], AC_TRY_RUN([ #define HAVE_SIGSEGV_SKIP_INSTRUCTION 1 #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../Unix/vm_alloc.cpp" - #include "../Unix/sigsegv.cpp" + #include "../CrossPlatform/vm_alloc.cpp" + #include "../CrossPlatform/sigsegv.cpp" ], ac_cv_have_skip_instruction=yes, ac_cv_have_skip_instruction=no, dnl When cross-compiling, do not assume anything. ac_cv_have_skip_instruction=no @@ -269,10 +276,13 @@ if [[ "x$HAVE_GCC30" = "xyes" ]]; then AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing], ac_cv_gcc_no_strict_aliasing, [ AC_TRY_COMPILE([],[], - [ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")], + [ac_cv_gcc_no_strict_aliasing=yes], [ac_cv_gcc_no_strict_aliasing=no]) ]) CFLAGS="$SAVED_CFLAGS" + if test "x$ac_cv_gcc_no_strict_aliasing" = xyes; then + AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing") + fi fi dnl Select appropriate CPU source and REGPARAM define. @@ -304,6 +314,11 @@ elif [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_X86_64" = "xyes" ]]; then fi fi +dnl BINCUE overrides +if [[ "x$have_bincue" = "xyes" ]]; then + EXTRASRCS="$EXTRASRCS bincue.cpp" +fi + dnl Enable JIT compiler, if possible. if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o" @@ -524,19 +539,20 @@ 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 We really want SDL for now -AC_CHECK_TOOL(sdl_config, sdl-config, [AC_MSG_ERROR([Sorry, you currently need SDL for this port])]) +AC_CHECK_TOOL(sdl_config, sdl2-config, no) +AS_IF([test "x$sdl_config" = xno], [AC_MSG_ERROR([Sorry, you currently need SDL for this port])]) SDL_CFLAGS=`$sdl_config --cflags` AC_SUBST(SDL_CFLAGS) -if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then +#if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then SDL_LIBS=`$sdl_config --static-libs` - sdl_prefix=`$sdl_config --exec-prefix` - if [[ -n "$sdl_prefix" ]]; then - SDL_LIBS=`echo "$SDL_LIBS" | sed -e "s,-l\(SDLmain\|SDL\),$sdl_prefix/lib/lib\1.a,g"` - fi - SDL_LIBS="$SDL_LIBS -lwinmm" -else - SDL_LIBS=`$sdl_config --libs` -fi +# sdl_prefix=`$sdl_config --exec-prefix` +# if [[ -n "$sdl_prefix" ]]; then +# SDL_LIBS=`echo "$SDL_LIBS" | sed -e "s,-l\(SDLmain\|SDL\),$sdl_prefix/lib/lib\1.a,g"` +# fi +# SDL_LIBS="$SDL_LIBS -lwinmm" +#else +# SDL_LIBS=`$sdl_config --libs` +#fi AC_SUBST(SDL_LIBS) AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support]) @@ -552,6 +568,7 @@ dnl Generate Makefile. AC_SUBST(DEFINES) AC_SUBST(CPUINCLUDES) AC_SUBST(CPUSRCS) +AC_SUBST(EXTRASRCS) AC_CONFIG_FILES([Makefile]) AC_OUTPUT @@ -564,6 +581,7 @@ echo JIT debug mode ......................... : $WANT_JIT_DEBUG echo Floating-Point emulation core .......... : $FPE_CORE echo Assembly optimizations ................. : $ASM_OPTIMIZATIONS echo Addressing mode ........................ : $ADDRESSING_MODE +echo BINCUE support ......................... : $have_bincue echo GTK user interface ..................... : $WANT_GTK echo echo "Configuration done. Now type \"make\" (or \"gmake\")." diff --git a/BasiliskII/src/Windows/ether_windows.cpp b/BasiliskII/src/Windows/ether_windows.cpp index cc6aa4116..1f9e245e5 100755 --- a/BasiliskII/src/Windows/ether_windows.cpp +++ b/BasiliskII/src/Windows/ether_windows.cpp @@ -39,7 +39,10 @@ #include "ether_windows.h" #include "router/router.h" #include "util_windows.h" +// somehow util_windows undefines min +#define min(x,y) ((x) < (y) ? (x) : (y)) #include "libslirp.h" +#include "ctl.h" // Define to let the slirp library determine the right timeout for select() #define USE_SLIRP_TIMEOUT 1 @@ -99,6 +102,14 @@ static int net_if_type = -1; // Ethernet device type #ifdef SHEEPSHAVER static bool net_open = false; // Flag: initialization succeeded, network device open uint8 ether_addr[6]; // Our Ethernet address + +#else +const bool ether_driver_opened = true; // Flag: Driver is open on MacOS side + // so ether.h layer is ready for + // calls. + // B2 doesn't provide this + // but also calls don't need it + #endif // These are protected by queue_csection @@ -134,6 +145,8 @@ static LPPACKET send_queue = 0; static CRITICAL_SECTION wpool_csection; static LPPACKET write_packet_pool = 0; +// Calling slirp functions from multiple threads concurrently is unsafe; guard it +static CRITICAL_SECTION slirp_single_call_csection; // Try to deal with echos. Protected by fetch_csection. @@ -188,6 +201,8 @@ static int16 ether_do_add_multicast(uint8 *addr); static int16 ether_do_del_multicast(uint8 *addr); static int16 ether_do_write(uint32 arg); static void ether_do_interrupt(void); +static void slirp_add_redirs(); +static int slirp_add_redir(const char *redir_str); /* @@ -251,6 +266,7 @@ bool ether_init(void) WarningAlert(GetString(STR_SLIRP_NO_DNS_FOUND_WARN)); return false; } + slirp_add_redirs(); } // Open ethernet device @@ -406,6 +422,8 @@ bool ether_init(void) InitializeCriticalSectionAndSpinCount( &send_csection, 5000 ); InitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 ); + InitializeCriticalSection( &slirp_single_call_csection ); + ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid ); if (!ether_th) { D(bug("Failed to create ethernet thread\n")); @@ -555,6 +573,7 @@ void ether_exit(void) DeleteCriticalSection( &queue_csection ); DeleteCriticalSection( &send_csection ); DeleteCriticalSection( &wpool_csection ); + DeleteCriticalSection( &slirp_single_call_csection ); D(bug("Freeing read packets\n")); free_read_packets(); @@ -1008,7 +1027,9 @@ unsigned int WINAPI ether_thread_write_packets(void *arg) } break; case NET_IF_SLIRP: + EnterCriticalSection( &slirp_single_call_csection ); slirp_input((uint8 *)Packet->Buffer, Packet->Length); + LeaveCriticalSection( &slirp_single_call_csection ); Packet->bIoComplete = TRUE; recycle_write_packet(Packet); break; @@ -1362,7 +1383,9 @@ unsigned int WINAPI slirp_receive_func(void *arg) FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); + EnterCriticalSection( &slirp_single_call_csection ); timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); + LeaveCriticalSection( &slirp_single_call_csection ); #if ! USE_SLIRP_TIMEOUT timeout = 10000; #endif @@ -1378,8 +1401,11 @@ unsigned int WINAPI slirp_receive_func(void *arg) tv.tv_usec = timeout; ret = select(0, &rfds, &wfds, &xfds, &tv); } - if (ret >= 0) + if (ret >= 0) { + EnterCriticalSection( &slirp_single_call_csection ); slirp_select_poll(&rfds, &wfds, &xfds); + LeaveCriticalSection( &slirp_single_call_csection ); + } } D(bug("slirp_receive_func exit\n")); @@ -1569,10 +1595,16 @@ unsigned int WINAPI ether_thread_feed_int(void *arg) D(bug("Triggering\n")); looping = true; while(thread_active && looping) { - trigger_queue(); - // Wait for interrupt acknowledge by EtherInterrupt() - WaitForSingleObject(int_ack,INFINITE); - if(thread_active) looping = set_wait_request(); + if (ether_driver_opened) { + trigger_queue(); + // Wait for interrupt acknowledge by EtherInterrupt() + WaitForSingleObject(int_ack,INFINITE); + if(thread_active) looping = set_wait_request(); + } else { + // Ether driver is closed on the MacOS side + // ether.h calls in this case are undefined + Delay_usec(20000); + } } D(bug("Queue empty.\n")); } @@ -1612,6 +1644,97 @@ static void ether_do_interrupt(void) } } +// Helper function for port forwarding +static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) +{ + const char *p, *p1; + int len; + p = *pp; + p1 = strchr(p, sep); + if (!p1) + return -1; + len = p1 - p; + p1++; + if (buf_size > 0) { + if (len > buf_size - 1) + len = buf_size - 1; + memcpy(buf, p, len); + buf[len] = '\0'; + } + *pp = p1; + return 0; +} + +// Set up port forwarding for slirp +static void slirp_add_redirs() +{ + int index = 0; + const char *str; + while ((str = PrefsFindString("redir", index++)) != NULL) { + slirp_add_redir(str); + } +} + +// Add a port forward/redirection for slirp +static int slirp_add_redir(const char *redir_str) +{ + // code adapted from qemu source + struct in_addr guest_addr = {0}; + int host_port, guest_port; + const char *p; + char buf[256]; + int is_udp; + char *end; + char str[256]; + + p = redir_str; + if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + if (!strcmp(buf, "tcp") || buf[0] == '\0') { + is_udp = 0; + } else if (!strcmp(buf, "udp")) { + is_udp = 1; + } else { + goto fail_syntax; + } + + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + host_port = strtol(buf, &end, 0); + if (*end != '\0' || host_port < 1 || host_port > 65535) { + goto fail_syntax; + } + + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + // 0.0.0.0 doesn't seem to work, so default to a client address + // if none is specified + if (buf[0] == '\0' ? + !inet_pton(AF_INET, CTL_LOCAL, &guest_addr) : + !inet_pton(AF_INET, buf, &guest_addr)) { + goto fail_syntax; + } + + guest_port = strtol(p, &end, 0); + if (*end != '\0' || guest_port < 1 || guest_port > 65535) { + goto fail_syntax; + } + + if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) { + sprintf(str, "could not set up host forwarding rule '%s'", redir_str); + WarningAlert(str); + return -1; + } + return 0; + + fail_syntax: + sprintf(str, "invalid host forwarding rule '%s'", redir_str); + WarningAlert(str); + return -1; +} #if DEBUG #pragma optimize("",on) #endif diff --git a/BasiliskII/src/Windows/main_windows.cpp b/BasiliskII/src/Windows/main_windows.cpp index 184a2dc65..ec34daa18 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,14 +45,9 @@ 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" -#if USE_JIT -extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp -#endif - #ifdef ENABLE_MON # include "mon.h" #endif @@ -61,19 +55,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,21 +71,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 - -#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); static void one_tick(...); - /* * Ersatz functions */ @@ -122,17 +93,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 */ @@ -207,20 +167,16 @@ 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(); // 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 +extern SDL_Window *sdl_window; HWND GetMainWindowHandle(void) { SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); - return SDL_GetWMInfo(&wmInfo) ? wmInfo.window : NULL; + if (!sdl_window) { + return NULL; + } + if (!SDL_GetWindowWMInfo(sdl_window, &wmInfo)) { + return NULL; + } + if (wmInfo.subsystem != SDL_SYSWM_WINDOWS) { + return NULL; + } + return wmInfo.info.win.window; } #endif diff --git a/BasiliskII/src/Windows/posix_emu.cpp b/BasiliskII/src/Windows/posix_emu.cpp index 8d671abc2..c93b2e095 100755 --- a/BasiliskII/src/Windows/posix_emu.cpp +++ b/BasiliskII/src/Windows/posix_emu.cpp @@ -392,14 +392,23 @@ void init_posix_emu(void) int fd = my_creat( custom_icon_name, 0 ); if(fd >= 0) { my_close(fd); + struct my_stat custom_icon_stat; + int stat_result = my_stat( custom_icon_name, &custom_icon_stat ); fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT ); if(fd >= 0) { my_write( fd, my_comp_icon, sizeof(my_comp_icon) ); my_close(fd); - static uint8 host_finfo[SIZEOF_FInfo]; + // need room for the things from around the finfo that set_finfo reads + static uint8 custom_icon_hfile[ioFlXFndrInfo + SIZEOF_FXInfo]; + memset(custom_icon_hfile, 0, ioFlXFndrInfo + SIZEOF_FXInfo); + static uint8 * host_finfo = custom_icon_hfile + ioFlFndrInfo; uint32 finfo = Host2MacAddr(host_finfo); get_finfo(custom_icon_name, finfo, 0, false); WriteMacInt16(finfo + fdFlags, kIsInvisible); + if (stat_result == 0) { + WriteMacInt32(finfo - ioFlFndrInfo + ioFlCrDat, TimeToMacTime(custom_icon_stat.st_ctime)); + WriteMacInt32(finfo - ioFlFndrInfo + ioFlMdDat, TimeToMacTime(custom_icon_stat.st_mtime)); + } set_finfo(custom_icon_name, finfo, 0, false); get_finfo(my_computer, finfo, 0, true); WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon); diff --git a/BasiliskII/src/Windows/posix_emu.h b/BasiliskII/src/Windows/posix_emu.h index 730d63df2..a238beceb 100755 --- a/BasiliskII/src/Windows/posix_emu.h +++ b/BasiliskII/src/Windows/posix_emu.h @@ -79,24 +79,33 @@ extern int my_errno; // must hook all other functions that manipulate file names #ifndef NO_POSIX_API_HOOK -#define stat my_stat -#define fstat my_fstat -#define open my_open -#define rename my_rename -#define access my_access -#define mkdir my_mkdir -#define remove my_remove -#define creat my_creat -#define close my_close -#define lseek my_lseek -#define read my_read -#define write my_write -#define ftruncate my_chsize -#define locking my_locking -#define utime my_utime - -#undef errno -#define errno my_errno +# ifdef stat +# undef stat +# endif +# define stat my_stat +# ifdef fstat +# undef fstat +# endif +# define fstat my_fstat +# define open my_open +# define rename my_rename +# define access my_access +# define mkdir my_mkdir +# define remove my_remove +# define creat my_creat +# define close my_close +# ifdef lseek +# undef lseek +# endif +# define lseek my_lseek +# define read my_read +# define write my_write +# define ftruncate my_chsize +# define locking my_locking +# define utime my_utime + +# undef errno +# define errno my_errno #endif //!NO_POSIX_API_HOOK #ifndef S_ISDIR @@ -125,6 +134,6 @@ struct my_utimbuf }; // Your compiler may have different "struct stat" -> edit "struct my_stat" -#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) ) +#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct _stat) ) #define st_crtime st_ctime diff --git a/BasiliskII/src/Windows/prefs_editor_gtk.cpp b/BasiliskII/src/Windows/prefs_editor_gtk.cpp index 66ad44c4f..c44e3d41f 100644 --- a/BasiliskII/src/Windows/prefs_editor_gtk.cpp +++ b/BasiliskII/src/Windows/prefs_editor_gtk.cpp @@ -26,6 +26,8 @@ #include #include +#include + #include "user_strings.h" #include "version.h" #include "cdrom.h" @@ -76,6 +78,27 @@ enum { * Utility functions */ +gchar * tchar_to_g_utf8(const TCHAR * str) { + gchar * out; + if (str == NULL) + return NULL; + int len = _tcslen(str) + 1; + #ifdef _UNICODE + /* First call just to find what the output size will be */ + int size = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL); + if (size == 0) + return NULL; + out = (gchar *) g_malloc(size); + if (out == NULL) + return NULL; + WideCharToMultiByte(CP_UTF8, 0, str, len, out, size, NULL, NULL); + #else /* _UNICODE */ + out = g_locale_to_utf8(str, -1, NULL, NULL, NULL); + #endif /* _UNICODE */ + return out; +} + + struct opt_desc { int label_id; GtkSignalFunc func; @@ -411,47 +434,40 @@ static void dl_quit(GtkWidget *dialog) } // "About" button clicked -static void cb_about(...) -{ - GtkWidget *dialog; - - GtkWidget *label, *button; - - char str[512]; - sprintf(str, - PROGRAM_NAME "\nVersion %d.%d\n\n" - "Copyright (C) 1997-2008 Christian Bauer et al.\n" - "E-mail: cb@cebix.net\n" +static void cb_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 - "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 @@ -672,11 +688,11 @@ static GList *add_cdrom_names(void) { GList *glist = NULL; - char rootdir[4] = "X:\\"; - for (char letter = 'C'; letter <= 'Z'; letter++) { + TCHAR rootdir[4] = TEXT("X:\\"); + for (TCHAR letter = TEXT('C'); letter <= TEXT('Z'); letter++) { rootdir[0] = letter; if (GetDriveType(rootdir) == DRIVE_CDROM) - glist = g_list_append(glist, strdup(rootdir)); + glist = g_list_append(glist, _tcsdup(rootdir)); } return glist; @@ -887,11 +903,12 @@ static void create_jit_pane(GtkWidget *top) #endif set_jit_sensitive(); -#endif #ifdef SHEEPSHAVER make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k)); #endif + +#endif } /* @@ -951,30 +968,14 @@ static int dis_width, dis_height; // Hide/show graphics widgets static void hide_show_graphics_widgets(void) { - switch (display_type) { - case DISPLAY_WINDOW: - gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip); - break; - case DISPLAY_SCREEN: - gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip); - break; - } + } // "Window" video type selected -static void mn_window(...) -{ - display_type = DISPLAY_WINDOW; - hide_show_graphics_widgets(); -} +static void mn_window(...) {display_type = DISPLAY_WINDOW;} // "Fullscreen" video type selected -static void mn_fullscreen(...) -{ - display_type = DISPLAY_SCREEN; - hide_show_graphics_widgets(); - PrefsReplaceInt32("frameskip", 1); -} +static void mn_fullscreen(...) {display_type = DISPLAY_SCREEN;} // "5 Hz".."60Hz" selected static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);} @@ -1006,6 +1007,33 @@ static void tb_nosound(GtkWidget *widget) set_graphics_sensitive(); } +// SDL Graphics +#ifdef USE_SDL_VIDEO +// SDL Renderer Render Driver +enum { + RENDER_SOFTWARE = 0, + RENDER_OPENGL = 1, + RENDER_DIRECT3D = 2 +}; + +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;} +static void mn_sdl_direct3d(...) {render_driver = RENDER_DIRECT3D;} + +// 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) { @@ -1025,6 +1053,40 @@ static void parse_graphics_prefs(void) else 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; + else if (strcmp(drv, "direct3d") == 0) + render_driver = RENDER_DIRECT3D; + } + #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; + case RENDER_DIRECT3D: + rpref = "direct3d"; + break; + default: + PrefsRemoveItem("sdlrender"); + return; + } + PrefsReplaceString("sdlrender", rpref); } // Read settings from widgets and set preferences @@ -1051,6 +1113,10 @@ static void read_graphics_settings(void) return; } PrefsReplaceString("screen", pref); + + #ifdef USE_SDL_VIDEO + read_SDL_graphics_settings(); + #endif } // Create "Graphics/Sound" pane @@ -1160,6 +1226,39 @@ static void create_graphics_pane(GtkWidget *top) make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel)); #endif +#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)); + add_menu_item(menu, STR_DIRECT3D_LAB, GTK_SIGNAL_FUNC(mn_sdl_direct3d)); + 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; + case RENDER_DIRECT3D: + gtk_menu_set_active(GTK_MENU(menu), 2); + 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)); @@ -1466,24 +1565,25 @@ static int create_ether_menu(GtkWidget *menu) n_items++; // Basilisk II Ethernet Adapter - PacketOpenAdapter("", 0); + PacketOpenAdapter(TEXT(""), 0); { ULONG sz; - char names[1024]; + TCHAR names[1024]; sz = sizeof(names); if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) { - char *p = names; + TCHAR *p = names; while (*p) { - const char DEVICE_HEADER[] = "\\Device\\B2ether_"; - if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) { + const TCHAR DEVICE_HEADER[] = TEXT("\\Device\\B2ether_"); + if (_tcsnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) { LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0); if (fd) { - char guid[256]; - sprintf(guid, "%s", p + sizeof(DEVICE_HEADER) - 1); - const char *name = ether_guid_to_name(guid); - if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) { - add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(guid)); - if (etherguid && strcmp(guid, etherguid) == 0 && + TCHAR guid[256]; + _stprintf(guid, TEXT("%s"), p + sizeof(DEVICE_HEADER) - 1); + const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid)); + if (name) { + std::string str_guid = to_string(guid); + add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(str_guid.c_str())); + if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 && ether && strcmp(ether, "b2ether") == 0) active = n_items; n_items++; @@ -1491,26 +1591,27 @@ static int create_ether_menu(GtkWidget *menu) PacketCloseAdapter(fd); } } - p += strlen(p) + 1; + p += _tcslen(p) + 1; } } } PacketCloseAdapter(NULL); // TAP-Win32 - const char *tap_devices; + const TCHAR *tap_devices; if ((tap_devices = ether_tap_devices()) != NULL) { - const char *guid = tap_devices; + const TCHAR *guid = tap_devices; while (*guid) { - const char *name = ether_guid_to_name(guid); - if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) { - add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(guid)); - if (etherguid && strcmp(guid, etherguid) == 0 && + const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid)); + if (name) { + std::string str_guid = to_string(guid); + add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(str_guid.c_str())); + if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 && ether && strcmp(ether, "tap") == 0) active = n_items; n_items++; } - guid += strlen(guid) + 1; + guid += _tcslen(guid) + 1; } free((char *)tap_devices); } @@ -1659,9 +1760,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)}, @@ -1734,31 +1833,76 @@ void SysAddSerialPrefs(void) * Display alerts */ +static HWND GetMainWindowHandle() { + return NULL; +} + static void display_alert(int title_id, const char *text, int flags) { - MessageBox(NULL, text, GetString(title_id), MB_OK | flags); + HWND hMainWnd = GetMainWindowHandle(); + MessageBoxA(hMainWnd, text, GetString(title_id), MB_OK | flags); +} +#ifdef _UNICODE +static void display_alert(int title_id, const wchar_t *text, int flags) +{ + HWND hMainWnd = GetMainWindowHandle(); + MessageBoxW(hMainWnd, text, GetStringW(title_id).get(), MB_OK | flags); } +#endif + + +/* + * Display error alert + */ void ErrorAlert(const char *text) { + if (PrefsFindBool("nogui")) + return; + display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP); } +#ifdef _UNICODE +void ErrorAlert(const wchar_t *text) +{ + if (PrefsFindBool("nogui")) + return; + + display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP); +} +#endif + + +/* + * Display warning alert + */ void WarningAlert(const char *text) { + if (PrefsFindBool("nogui")) + return; + display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP); } +#ifdef _UNICODE +void WarningAlert(const wchar_t *text) +{ + if (PrefsFindBool("nogui")) + return; + display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP); +} +#endif /* * 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); @@ -1774,23 +1918,23 @@ int main(int argc, char *argv[]) // Transfer control to the executable if (start) { - char path[_MAX_PATH]; + TCHAR path[_MAX_PATH]; bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0; if (ok) { - char b2_path[_MAX_PATH]; - char *p = strrchr(path, '\\'); - *++p = '\0'; + TCHAR b2_path[_MAX_PATH]; + TCHAR *p = _tcsrchr(path, TEXT('\\')); + *++p = TEXT('\0'); SetCurrentDirectory(path); - strcpy(b2_path, path); - strcat(b2_path, PROGRAM_NAME); - strcat(b2_path, ".exe"); - HINSTANCE h = ShellExecute(GetDesktopWindow(), "open", - b2_path, "", path, SW_SHOWNORMAL); + _tcscpy(b2_path, path); + _tcscat(b2_path, TEXT(PROGRAM_NAME)); + _tcscat(b2_path, TEXT(".exe")); + HINSTANCE h = ShellExecute(GetDesktopWindow(), TEXT("open"), + b2_path, TEXT(""), path, SW_SHOWNORMAL); if ((int)h <= 32) ok = false; } if (!ok) { - ErrorAlert("Coult not start " PROGRAM_NAME " executable"); + ErrorAlert(TEXT("Could not start ") TEXT(PROGRAM_NAME) TEXT(" executable")); return 1; } } diff --git a/BasiliskII/src/Windows/prefs_windows.cpp b/BasiliskII/src/Windows/prefs_windows.cpp index ed837b865..527dcbfc2 100755 --- a/BasiliskII/src/Windows/prefs_windows.cpp +++ b/BasiliskII/src/Windows/prefs_windows.cpp @@ -35,9 +35,6 @@ prefs_desc platform_prefs_items[] = { {"keycodefile", TYPE_STRING, false, "path of keycode translation file"}, {"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"}, {"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"}, -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, {"enableextfs", TYPE_BOOLEAN, false, "enable extfs system"}, {"debugextfs", TYPE_BOOLEAN, false, "debug extfs system"}, @@ -52,6 +49,10 @@ prefs_desc platform_prefs_items[] = { {"tcp_port", TYPE_STRING, false, "TCP ports list"}, {"portfile0", TYPE_STRING, false, "output file for serial port 0"}, {"portfile1", TYPE_STRING, false, "output file for serial port 1"}, +#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 }; @@ -123,9 +124,6 @@ void AddPlatformPrefsDefaults(void) PrefsReplaceString("extdrives", "CDEFGHIJKLMNOPQRSTUVWXYZ"); PrefsReplaceInt32("mousewheelmode", 1); PrefsReplaceInt32("mousewheellines", 3); -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - PrefsAddBool("ignoresegv", false); -#endif PrefsAddBool("idlewait", true); PrefsReplaceBool("etherpermanentaddress", true); PrefsReplaceInt32("ethermulticastmode", 0); @@ -134,4 +132,8 @@ void AddPlatformPrefsDefaults(void) PrefsReplaceString("serialb", "COM2"); PrefsReplaceString("portfile0", "C:\\B2TEMP0.OUT"); PrefsReplaceString("portfile1", "C:\\B2TEMP1.OUT"); +#ifdef USE_SDL_VIDEO + PrefsReplaceString("sdlrender", "software"); + PrefsReplaceBool("sdl_vsync", false); +#endif } diff --git a/BasiliskII/src/Windows/serial_windows.cpp b/BasiliskII/src/Windows/serial_windows.cpp index 5a062b32b..194bf8381 100755 --- a/BasiliskII/src/Windows/serial_windows.cpp +++ b/BasiliskII/src/Windows/serial_windows.cpp @@ -28,6 +28,8 @@ #include "main.h" #include "util_windows.h" +// somehow util_windows undefines min +#define min(x,y) ((x) < (y) ? (x) : (y)) #include "macos_util.h" #include "prefs.h" #include "serial.h" @@ -310,12 +312,12 @@ int16 XSERDPort::open(uint16 config) if (input_thread_active) { TerminateThread(input_thread_active,0); CloseHandle(input_signal); - input_thread_active = false; + input_thread_active = 0; } if (output_thread_active) { TerminateThread(output_thread_active,0); CloseHandle(output_signal); - output_thread_active = false; + output_thread_active = 0; } if(fd != INVALID_HANDLE_VALUE) { CloseHandle(fd); @@ -674,13 +676,13 @@ int16 XSERDPort::close() if (input_thread_active) { quitting = true; ReleaseSemaphore(input_signal,1,NULL); - input_thread_active = false; + input_thread_active = 0; CloseHandle(input_signal); } if (output_thread_active) { quitting = true; ReleaseSemaphore(output_signal,1,NULL); - output_thread_active = false; + output_thread_active = 0; // bugfix: was: CloseHandle(&output_signal); CloseHandle(output_signal); } diff --git a/BasiliskII/src/Windows/sys_windows.cpp b/BasiliskII/src/Windows/sys_windows.cpp index 21e2df0e0..264ee3668 100755 --- a/BasiliskII/src/Windows/sys_windows.cpp +++ b/BasiliskII/src/Windows/sys_windows.cpp @@ -40,6 +40,10 @@ using std::min; #include "cdenable/cache.h" #include "cdenable/eject_nt.h" +#if defined(BINCUE) +#include "bincue.h" +#endif + #define DEBUG 0 #include "debug.h" @@ -56,6 +60,12 @@ struct file_handle { loff_t file_size; // Size of file data (only valid if is_file is true) cachetype cache; bool is_media_present; + +#if defined(BINCUE) + bool is_bincue; // Flag: BIN CUE file + void *bincue_fd; + file_handle() {is_bincue = false;} // default bincue false +#endif }; // Open file handles @@ -74,7 +84,7 @@ static char *sector_buffer = NULL; // Prototypes static bool is_cdrom_readable(file_handle *fh); - +static DWORD file_offset_read(HANDLE fh, loff_t offset, int count, char *buf); /* * Initialization @@ -256,12 +266,42 @@ void SysAddSerialPrefs(void) * Can't give too much however, would be annoying, this is difficult.. */ -static inline int cd_read_with_retry(file_handle *fh, ULONG LBA, int count, char *buf ) +static inline int cd_read_with_retry(file_handle *fh, ULONG offset, int count, char *buf ) { if (!fh || !fh->fh) return 0; - return CdenableSysReadCdBytes(fh->fh, LBA, count, buf); + DWORD bytes_read = CdenableSysReadCdBytes(fh->fh, offset, count, buf); + + if (bytes_read == 0) { + // fall back to logical volume handle read in the case where there's no cdenable + bytes_read = file_offset_read(fh->fh, offset, count, buf); + } + + return bytes_read; +} + +/* + * Generic offset read function for a file or a device that behaves like one + */ + +static DWORD file_offset_read(HANDLE fh, loff_t offset, int count, char *buf) +{ + // Seek to position + LONG lo = (LONG)offset; + LONG hi = (LONG)(offset >> 32); + DWORD r = SetFilePointer(fh, lo, &hi, FILE_BEGIN); + if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { + return 0; + } + + DWORD bytes_read; + + // Read data + if (ReadFile(fh, buf, count, &bytes_read, NULL) == 0) + bytes_read = 0; + + return bytes_read; } static int cd_read(file_handle *fh, cachetype *cptr, ULONG LBA, int count, char *buf) @@ -462,6 +502,11 @@ void *Sys_open(const char *path_name, bool read_only) read_only = true; // Open file + +#if defined(BINCUE) + void *binfd = open_bincue(name); // check if bincue +#endif + HANDLE h = CreateFile( name, read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, @@ -486,6 +531,16 @@ void *Sys_open(const char *path_name, bool read_only) fh->is_floppy = false; fh->is_cdrom = false; +#if defined(BINCUE) + if (binfd) { + fh->bincue_fd = binfd; + fh->is_bincue = true; + fh->is_media_present = true; + sys_add_file_handle(fh); + return fh; + } +#endif + // Detect disk image file layout loff_t size = GetFileSize(h, NULL); DWORD bytes_read; @@ -517,6 +572,11 @@ void Sys_close(void *arg) sys_remove_file_handle(fh); +#if defined(BINCUE) + if (fh->is_bincue) + close_bincue(fh->bincue_fd); +#endif + if (fh->is_cdrom) { cache_final(&fh->cache); SysAllowRemoval((void *)fh); @@ -543,19 +603,15 @@ size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length) if (!fh) return 0; +#if defined(BINCUE) + if (fh->is_bincue) + return read_bincue(fh->bincue_fd, buffer, offset, length); +#endif + DWORD bytes_read = 0; if (fh->is_file) { - // Seek to position - LONG lo = (LONG)offset; - LONG hi = (LONG)(offset >> 32); - DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN); - if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) - return 0; - - // Read data - if (ReadFile(fh->fh, buffer, length, &bytes_read, NULL) == 0) - bytes_read = 0; + bytes_read = file_offset_read(fh->fh, offset, length, (char *)buffer); } else if (fh->is_cdrom) { int bytes_left, try_bytes, got_bytes; @@ -623,6 +679,11 @@ loff_t SysGetFileSize(void *arg) if (!fh) return true; +#if defined(BINCUE) + if (fh->is_bincue) + return size_bincue(fh->bincue_fd); +#endif + if (fh->is_file) return fh->file_size; else if (fh->is_cdrom) @@ -644,6 +705,13 @@ void SysEject(void *arg) if (!fh) return; +#if defined(BINCUE) + if (fh->is_bincue) { + fh->is_media_present = false; + return; + } +#endif + if (fh->is_cdrom && fh->fh) { fh->is_media_present = false; // Commented out because there was some problems, but can't remember @@ -782,16 +850,26 @@ void SysAllowRemoval(void *arg) bool SysCDReadTOC(void *arg, uint8 *toc) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - DWORD dummy; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_READ_TOC, - NULL, 0, - toc, min((int)sizeof(CDROM_TOC), 804), - &dummy, - NULL) != FALSE; +#if defined(BINCUE) + if (fh->is_bincue) + return readtoc_bincue(fh->bincue_fd, toc); +#endif + + if (fh->is_cdrom) { + + DWORD dummy; + return DeviceIoControl(fh->fh, + IOCTL_CDROM_READ_TOC, + NULL, 0, + toc, min((int)sizeof(CDROM_TOC), 804), + &dummy, + NULL) != FALSE; + + } else + return false; } @@ -802,26 +880,34 @@ bool SysCDReadTOC(void *arg, uint8 *toc) bool SysCDGetPosition(void *arg, uint8 *pos) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - SUB_Q_CHANNEL_DATA q_data; - - CDROM_SUB_Q_DATA_FORMAT q_format; - q_format.Format = IOCTL_CDROM_CURRENT_POSITION; - q_format.Track = 0; // used only by ISRC reads - - DWORD dwBytesReturned = 0; - bool ok = DeviceIoControl(fh->fh, - IOCTL_CDROM_READ_Q_CHANNEL, - &q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT), - &q_data, sizeof(SUB_Q_CHANNEL_DATA), - &dwBytesReturned, - NULL) != FALSE; - if (ok) - memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION)); +#if defined(BINCUE) + if (fh->is_bincue) + return GetPosition_bincue(fh->bincue_fd, pos); +#endif - return ok; + if (fh->is_cdrom) { + SUB_Q_CHANNEL_DATA q_data; + + CDROM_SUB_Q_DATA_FORMAT q_format; + q_format.Format = IOCTL_CDROM_CURRENT_POSITION; + q_format.Track = 0; // used only by ISRC reads + + DWORD dwBytesReturned = 0; + bool ok = DeviceIoControl(fh->fh, + IOCTL_CDROM_READ_Q_CHANNEL, + &q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT), + &q_data, sizeof(SUB_Q_CHANNEL_DATA), + &dwBytesReturned, + NULL) != FALSE; + if (ok) + memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION)); + + return ok; + } else + return false; } @@ -832,24 +918,32 @@ bool SysCDGetPosition(void *arg, uint8 *pos) 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 || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - CDROM_PLAY_AUDIO_MSF msf; - msf.StartingM = start_m; - msf.StartingS = start_s; - msf.StartingF = start_f; - msf.EndingM = end_m; - msf.EndingS = end_s; - msf.EndingF = end_f; +#if defined(BINCUE) + if (fh->is_bincue) + return CDPlay_bincue(fh->bincue_fd, start_m, start_s, start_f, end_m, end_s, end_f); +#endif - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_PLAY_AUDIO_MSF, - &msf, sizeof(CDROM_PLAY_AUDIO_MSF), - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; + if (fh->is_cdrom) { + CDROM_PLAY_AUDIO_MSF msf; + msf.StartingM = start_m; + msf.StartingS = start_s; + msf.StartingF = start_f; + msf.EndingM = end_m; + msf.EndingS = end_s; + msf.EndingF = end_f; + + DWORD dwBytesReturned = 0; + return DeviceIoControl(fh->fh, + IOCTL_CDROM_PLAY_AUDIO_MSF, + &msf, sizeof(CDROM_PLAY_AUDIO_MSF), + NULL, 0, + &dwBytesReturned, + NULL) != FALSE; + } else + return false; } @@ -860,16 +954,24 @@ bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end bool SysCDPause(void *arg) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_PAUSE_AUDIO, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; +#if defined(BINCUE) + if (fh->is_bincue) + return CDPause_bincue(fh->bincue_fd); +#endif + + if (fh->is_cdrom) { + DWORD dwBytesReturned = 0; + return DeviceIoControl(fh->fh, + IOCTL_CDROM_PAUSE_AUDIO, + NULL, 0, + NULL, 0, + &dwBytesReturned, + NULL) != FALSE; + } else + return false; } @@ -880,15 +982,23 @@ bool SysCDPause(void *arg) bool SysCDResume(void *arg) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_RESUME_AUDIO, - NULL, 0, - NULL, 0, - &dwBytesReturned, NULL) != FALSE; +#if defined(BINCUE) + if (fh->is_bincue) + return CDResume_bincue(fh->bincue_fd); +#endif + + if (fh->is_cdrom) { + DWORD dwBytesReturned = 0; + return DeviceIoControl(fh->fh, + IOCTL_CDROM_RESUME_AUDIO, + NULL, 0, + NULL, 0, + &dwBytesReturned, NULL) != FALSE; + } else + return false; } @@ -899,16 +1009,24 @@ bool SysCDResume(void *arg) bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_STOP_AUDIO, - NULL, 0, - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; +#if defined(BINCUE) + if (fh->is_bincue) + return CDStop_bincue(fh->bincue_fd); +#endif + + if (fh->is_cdrom) { + DWORD dwBytesReturned = 0; + return DeviceIoControl(fh->fh, + IOCTL_CDROM_STOP_AUDIO, + NULL, 0, + NULL, 0, + &dwBytesReturned, + NULL) != FALSE; + } else + return false; } @@ -919,21 +1037,30 @@ bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f) bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return false; - CDROM_SEEK_AUDIO_MSF msf; - msf.M = start_m; - msf.S = start_s; - msf.F = start_f; +#if defined(BINCUE) + if (fh->is_bincue) + return CDScan_bincue(fh->bincue_fd,start_m,start_s,start_f,reverse); +#endif + + if (fh->is_cdrom) { - DWORD dwBytesReturned = 0; - return DeviceIoControl(fh->fh, - IOCTL_CDROM_SEEK_AUDIO_MSF, - &msf, sizeof(CDROM_SEEK_AUDIO_MSF), - NULL, 0, - &dwBytesReturned, - NULL) != FALSE; + CDROM_SEEK_AUDIO_MSF msf; + msf.M = start_m; + msf.S = start_s; + msf.F = start_f; + + DWORD dwBytesReturned = 0; + return DeviceIoControl(fh->fh, + IOCTL_CDROM_SEEK_AUDIO_MSF, + &msf, sizeof(CDROM_SEEK_AUDIO_MSF), + NULL, 0, + &dwBytesReturned, + NULL) != FALSE; + } else + return false; } @@ -944,22 +1071,30 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve void SysCDSetVolume(void *arg, uint8 left, uint8 right) { file_handle *fh = (file_handle *)arg; - if (!fh || !fh->fh || !fh->is_cdrom) + if (!fh) return; - VOLUME_CONTROL vc; - vc.PortVolume[0] = left; - vc.PortVolume[1] = right; - vc.PortVolume[2] = left; - vc.PortVolume[3] = right; +#if defined(BINCUE) + if (fh->is_bincue) + CDSetVol_bincue(fh->bincue_fd,left,right); +#endif + + if (fh->is_cdrom) { + + VOLUME_CONTROL vc; + vc.PortVolume[0] = left; + vc.PortVolume[1] = right; + vc.PortVolume[2] = left; + vc.PortVolume[3] = right; - DWORD dwBytesReturned = 0; - DeviceIoControl(fh->fh, - IOCTL_CDROM_SET_VOLUME, - &vc, sizeof(VOLUME_CONTROL), - NULL, 0, - &dwBytesReturned, - NULL); + DWORD dwBytesReturned = 0; + DeviceIoControl(fh->fh, + IOCTL_CDROM_SET_VOLUME, + &vc, sizeof(VOLUME_CONTROL), + NULL, 0, + &dwBytesReturned, + NULL); + } } @@ -974,21 +1109,27 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right) return; left = right = 0; - if (!fh->fh || !fh->is_cdrom) - return; - VOLUME_CONTROL vc; - memset(&vc, 0, sizeof(vc)); +#if defined(BINCUE) + if (fh->is_bincue) + CDGetVol_bincue(fh->bincue_fd,&left,&right); +#endif + + if (fh->is_cdrom) { - DWORD dwBytesReturned = 0; - if (DeviceIoControl(fh->fh, - IOCTL_CDROM_GET_VOLUME, - NULL, 0, - &vc, sizeof(VOLUME_CONTROL), - &dwBytesReturned, - NULL)) - { - left = vc.PortVolume[0]; - right = vc.PortVolume[1]; + VOLUME_CONTROL vc; + memset(&vc, 0, sizeof(vc)); + + DWORD dwBytesReturned = 0; + if (DeviceIoControl(fh->fh, + IOCTL_CDROM_GET_VOLUME, + NULL, 0, + &vc, sizeof(VOLUME_CONTROL), + &dwBytesReturned, + NULL)) + { + left = vc.PortVolume[0]; + right = vc.PortVolume[1]; + } } } diff --git a/BasiliskII/src/Windows/sysdeps.h b/BasiliskII/src/Windows/sysdeps.h index 3f11226f0..d1d8f59b8 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 @@ -47,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 @@ -318,6 +302,8 @@ static inline uae_u32 do_byteswap_16_g(uae_u32 v) #ifdef _MSC_VER #define ATTRIBUTE_PACKED +#else +#define ATTRIBUTE_PACKED __attribute__((__packed__)) #endif #endif diff --git a/BasiliskII/src/Windows/user_strings_windows.cpp b/BasiliskII/src/Windows/user_strings_windows.cpp index 0d98d61ff..dc2993dab 100755 --- a/BasiliskII/src/Windows/user_strings_windows.cpp +++ b/BasiliskII/src/Windows/user_strings_windows.cpp @@ -20,7 +20,7 @@ #include "sysdeps.h" #include "user_strings.h" - +#include "util_windows.h" // Platform-specific string definitions user_string_def platform_strings[] = { @@ -81,7 +81,11 @@ static const char *get_volume_name(void) HKEY hHelpKey; DWORD key_type, cbData; - static char volume[256]; + #ifdef _UNICODE + static char out_volume[256]; + #endif + + static TCHAR volume[256]; memset(volume, 0, sizeof(volume)); // Try Windows 2000 key first @@ -118,14 +122,20 @@ static const char *get_volume_name(void) } // Fix the error that some "tweak" apps do. - if (_stricmp(volume, "%USERNAME% on %COMPUTER%") == 0) - volume[0] = '\0'; + if (_tcsicmp(volume, TEXT("%USERNAME% on %COMPUTER%")) == 0) + volume[0] = TEXT('\0'); // No volume name found, default to "My Computer" if (volume[0] == 0) - strcpy(volume, "My Computer"); + _tcscpy(volume, TEXT("My Computer")); + + #ifdef _UNICODE + strlcpy(out_volume, volume, 256); + return out_volume; + #else return volume; + #endif } diff --git a/BasiliskII/src/Windows/util_windows.cpp b/BasiliskII/src/Windows/util_windows.cpp index 28ef4ab99..f719bd6fd 100755 --- a/BasiliskII/src/Windows/util_windows.cpp +++ b/BasiliskII/src/Windows/util_windows.cpp @@ -271,7 +271,8 @@ bool check_drivers(void) else { TCHAR str[256]; _sntprintf(str, lengthof(str), TEXT("The CD-ROM driver file \"%s\" is missing."), path); - WarningAlert(str); + //WarningAlert(str); + } return true; diff --git a/BasiliskII/src/adb.cpp b/BasiliskII/src/adb.cpp index 27d1de73b..f89c40925 100644 --- a/BasiliskII/src/adb.cpp +++ b/BasiliskII/src/adb.cpp @@ -57,6 +57,11 @@ const int KEY_BUFFER_SIZE = 16; static uint8 key_buffer[KEY_BUFFER_SIZE]; static unsigned int key_read_ptr = 0, key_write_ptr = 0; +// O2S: Button event buffer (Mac button with up/down flag) -> avoid to loose tap on a trackpad +const int BUTTON_BUFFER_SIZE = 32; +static uint8 button_buffer[BUTTON_BUFFER_SIZE]; +static unsigned int button_read_ptr = 0, button_write_ptr = 0; + static uint8 mouse_reg_3[2] = {0x63, 0x01}; // Mouse ADB register 3 static uint8 key_reg_2[2] = {0xff, 0xff}; // Keyboard ADB register 2 @@ -152,7 +157,7 @@ void ADBOp(uint8 op, uint8 *data) break; case 3: // Address/HandlerID data[0] = 2; - data[1] = mouse_reg_3[0] & 0xf0 | (rand() & 0x0f); + data[1] = (mouse_reg_3[0] & 0xf0) | (rand() & 0x0f); data[2] = mouse_reg_3[1]; break; default: @@ -211,7 +216,7 @@ void ADBOp(uint8 op, uint8 *data) } case 3: // Address/HandlerID data[0] = 2; - data[1] = key_reg_3[0] & 0xf0 | (rand() & 0x0f); + data[1] = (key_reg_3[0] & 0xf0) | (rand() & 0x0f); data[2] = key_reg_3[1]; break; default: @@ -245,13 +250,17 @@ void ADBMouseMoved(int x, int y) } -/* +/* * Mouse button pressed */ void ADBMouseDown(int button) { - mouse_button[button] = true; + // O2S: Add button to buffer + button_buffer[button_write_ptr] = button; + button_write_ptr = (button_write_ptr + 1) % BUTTON_BUFFER_SIZE; + + // O2S: mouse_button[button] = true; SetInterruptFlag(INTFLAG_ADB); TriggerInterrupt(); } @@ -263,7 +272,11 @@ void ADBMouseDown(int button) void ADBMouseUp(int button) { - mouse_button[button] = false; + // O2S: Add button to buffer + button_buffer[button_write_ptr] = button | 0x80; + button_write_ptr = (button_write_ptr + 1) % BUTTON_BUFFER_SIZE; + + // O2S: mouse_button[button] = false; SetInterruptFlag(INTFLAG_ADB); TriggerInterrupt(); } @@ -278,7 +291,7 @@ void ADBSetRelMouseMode(bool relative) if (relative_mouse != relative) { relative_mouse = relative; mouse_x = mouse_y = 0; - } + } } @@ -347,34 +360,39 @@ void ADBInterrupt(void) uint32 mouse_base = adb_base + 16; if (relative_mouse) { - - // Mouse movement (relative) and buttons - if (mx != 0 || my != 0 || mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) { - - // Call mouse ADB handler - if (mouse_reg_3[1] == 4) { - // Extended mouse protocol - WriteMacInt8(tmp_data, 3); - WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80)); - WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80)); - WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mb[2] ? 0x08 : 0x88)); - } else { - // 100/200 dpi mode - WriteMacInt8(tmp_data, 2); - WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80)); - WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80)); - } - r.a[0] = tmp_data; - r.a[1] = ReadMacInt32(mouse_base); - r.a[2] = ReadMacInt32(mouse_base + 4); - r.a[3] = adb_base; - r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0 - Execute68k(r.a[1], &r); - - old_mouse_button[0] = mb[0]; - old_mouse_button[1] = mb[1]; - old_mouse_button[2] = mb[2]; - } + while (mx != 0 || my != 0 || button_read_ptr != button_write_ptr) { + if (button_read_ptr != button_write_ptr) { + // Read button event + uint8 button = button_buffer[button_read_ptr]; + button_read_ptr = (button_read_ptr + 1) % BUTTON_BUFFER_SIZE; + mouse_button[button & 0x3] = (button & 0x80) ? false : true; + } + // Call mouse ADB handler + if (mouse_reg_3[1] == 4) { + // Extended mouse protocol + WriteMacInt8(tmp_data, 3); + WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80)); + WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80)); + WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mouse_button[2] ? 0x08 : 0x88)); + } else { + // 100/200 dpi mode + WriteMacInt8(tmp_data, 2); + WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80)); + WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80)); + } + r.a[0] = tmp_data; + r.a[1] = ReadMacInt32(mouse_base); + r.a[2] = ReadMacInt32(mouse_base + 4); + r.a[3] = adb_base; + r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0 + Execute68k(r.a[1], &r); + + old_mouse_button[0] = mouse_button[0]; + old_mouse_button[1] = mouse_button[1]; + old_mouse_button[2] = mouse_button[2]; + mx = 0; + my = 0; + } } else { @@ -405,34 +423,42 @@ void ADBInterrupt(void) old_mouse_y = my; } - // Send mouse button events - if (mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) { - uint32 mouse_base = adb_base + 16; - - // Call mouse ADB handler - if (mouse_reg_3[1] == 4) { - // Extended mouse protocol - WriteMacInt8(tmp_data, 3); - WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80); - WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80); - WriteMacInt8(tmp_data + 3, mb[2] ? 0x08 : 0x88); - } else { - // 100/200 dpi mode - WriteMacInt8(tmp_data, 2); - WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80); - WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80); - } - r.a[0] = tmp_data; - r.a[1] = ReadMacInt32(mouse_base); - r.a[2] = ReadMacInt32(mouse_base + 4); - r.a[3] = adb_base; - r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0 - Execute68k(r.a[1], &r); - - old_mouse_button[0] = mb[0]; - old_mouse_button[1] = mb[1]; - old_mouse_button[2] = mb[2]; - } + // O2S: Process accumulated button events + while (button_read_ptr != button_write_ptr) { + // Read button event + uint8 button = button_buffer[button_read_ptr]; + button_read_ptr = (button_read_ptr + 1) % BUTTON_BUFFER_SIZE; + mouse_button[button & 0x3] = (button & 0x80) ? false : true; + + if (mouse_button[0] != old_mouse_button[0] || mouse_button[1] != old_mouse_button[1] || mouse_button[2] != old_mouse_button[2]) { + uint32 mouse_base = adb_base + 16; + + // Call mouse ADB handler + if (mouse_reg_3[1] == 4) { + // Extended mouse protocol + WriteMacInt8(tmp_data, 3); + WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80); + WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80); + WriteMacInt8(tmp_data + 3, mouse_button[2] ? 0x08 : 0x88); + } else { + // 100/200 dpi mode + WriteMacInt8(tmp_data, 2); + WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80); + WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80); + } + r.a[0] = tmp_data; + r.a[1] = ReadMacInt32(mouse_base); + r.a[2] = ReadMacInt32(mouse_base + 4); + r.a[3] = adb_base; + r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0 + Execute68k(r.a[1], &r); + + old_mouse_button[0] = mouse_button[0]; + old_mouse_button[1] = mouse_button[1]; + old_mouse_button[2] = mouse_button[2]; + } + } + } // Process accumulated keyboard events diff --git a/BasiliskII/src/audio.cpp b/BasiliskII/src/audio.cpp index 00a89996f..f3543fc79 100644 --- a/BasiliskII/src/audio.cpp +++ b/BasiliskII/src/audio.cpp @@ -31,6 +31,8 @@ #include "main.h" #include "audio.h" #include "audio_defs.h" +#include "user_strings.h" +#include "cdrom.h" #define DEBUG 0 #include "debug.h" @@ -51,6 +53,9 @@ static int open_count = 0; // Open/close nesting count bool AudioAvailable = false; // Flag: audio output available (from the software point of view) +int SoundInSource = 2; +int SoundInPlaythrough = 7; +int SoundInGain = 65536; // FIXED 4-byte from 0.5 to 1.5; this is middle value (1) as int /* * Reset audio emulation @@ -406,8 +411,8 @@ adat_error: printf("FATAL: audio component data block initialization error\n"); // Close Apple Mixer r.a[0] = AudioStatus.mixer; Execute68k(audio_data + adatCloseMixer, &r); + D(bug(" CloseMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer)); AudioStatus.mixer = 0; - return r.d[0]; } r.a[0] = audio_data; Execute68kTrap(0xa01f, &r); // DisposePtr() @@ -533,7 +538,7 @@ adat_error: printf("FATAL: audio component data block initialization error\n"); } } - +// not currently using these functions /* * Sound input driver Open() routine */ @@ -553,7 +558,20 @@ int16 SoundInPrime(uint32 pb, uint32 dce) { D(bug("SoundInPrime\n")); //!! - return paramErr; + + uint16 code = ReadMacInt16(pb + csCode); + D(bug("SoundInControl %d\n", code)); + + if (code == 1) { + D(bug(" SoundInKillIO\n")); + //!! + return noErr; + } + + if (code != 2) + return -231; // siUnknownInfoType + + return noErr; } @@ -574,12 +592,39 @@ int16 SoundInControl(uint32 pb, uint32 dce) if (code != 2) return -231; // siUnknownInfoType - - uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam); - uint32 selector = param[0]; - D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector)); + + uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above) switch (selector) { + case siInitializeDriver: { +// If possible, the driver initializes the device to a sampling rate of 22 kHz, a sample size of 8 bits, mono recording, no compression, automatic gain control on, and all other features off. + return noErr; + } + + case siCloseDriver: { +// The sound input device driver should stop any recording in progress, deallocate the input hardware, and initialize local variables to default settings. + return noErr; + } + + case siInputSource: { + SoundInSource = ReadMacInt16(pb + csParam + 4); + return noErr; + } + + case siPlayThruOnOff: { + SoundInPlaythrough = ReadMacInt16(pb + csParam + 4); + return noErr; + } + + case siOptionsDialog: { + return noErr; + } + + case siInputGain: { + SoundInGain = ReadMacInt32(pb + csParam + 4); + return noErr; + } + default: return -231; // siUnknownInfoType } @@ -590,58 +635,187 @@ int16 SoundInControl(uint32 pb, uint32 dce) * Sound input driver Status() routine */ -int16 SoundInStatus(uint32 pb, uint32 dce) +int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parameter block (pb) and A1 to device control entry (dce) { uint16 code = ReadMacInt16(pb + csCode); D(bug("SoundInStatus %d\n", code)); if (code != 2) return -231; // siUnknownInfoType + + // two choices on return + // 1: if under 18 bytes, place # of bytes at (pb+csParam) and write from (pb+csParam+4) on + // 2: if over 18 bytes, place 0 at (pb+csParam) and directly write into address pointed to by (pb+csParam+4) + uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above) + uint32 bufferptr = ReadMacInt32(pb + csParam + 4); // 4-byte address to the buffer in vm memory - uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam); - uint32 selector = param[0]; - D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector)); switch (selector) { -#if 0 - case siDeviceName: { - const char *str = GetString(STR_SOUND_IN_NAME); - param[0] = 0; - memcpy((void *)param[1], str, strlen(str)); + case siDeviceName: { // return name in STR255 format + const uint8 str[] = { // size 9 + 0x08, // 1-byte length + 0x42, 0x75, // Bu + 0x69, 0x6c, // il + 0x74, 0x2d, // t- + 0x69, 0x6e // in + }; +// const uint8 str[] = { // size 12 +// 0x0b, // 1-byte length +// 0x53, 0x68, // Sh +// 0x65, 0x65, // ee +// 0x70, 0x73, // ps +// 0x68, 0x61, // ha +// 0x76, 0x65, // ve +// 0x72 // r +// }; + WriteMacInt32(pb + csParam, 0); // response will be written directly into buffer + Host2Mac_memcpy(bufferptr, str, sizeof(str)); + return noErr; } case siDeviceIcon: { + // todo: add soundin ICN, borrow from CD ROM for now + WriteMacInt32(pb + csParam, 0); + M68kRegisters r; - static const uint8 proc[] = { - 0x55, 0x8f, // subq.l #2,sp - 0xa9, 0x94, // CurResFile - 0x42, 0x67, // clr.w -(sp) - 0xa9, 0x98, // UseResFile - 0x59, 0x8f, // subq.l #4,sp - 0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp) - 0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp) - 0xa9, 0xa0, // GetResource - 0x24, 0x5f, // move.l (sp)+,a2 - 0xa9, 0x98, // UseResFile - 0x20, 0x0a, // move.l a2,d0 - 0x66, 0x04, // bne 1 - 0x70, 0x00, // moveq #0,d0 - M68K_RTS >> 8, M68K_RTS & 0xff, - 0x2f, 0x0a, //1 move.l a2,-(sp) - 0xa9, 0x92, // DetachResource - 0x20, 0x4a, // move.l a2,a0 - 0xa0, 0x4a, // HNoPurge - 0x70, 0x01, // moveq #1,d0 - M68K_RTS >> 8, M68K_RTS & 0xff + r.d[0] = sizeof(CDROMIcon); + Execute68kTrap(0xa122, &r); // NewHandle() + uint32 h = r.a[0]; + if (h == 0) + return memFullErr; + WriteMacInt32(bufferptr, h); + uint32 sp = ReadMacInt32(h); + Host2Mac_memcpy(sp, CDROMIcon, sizeof(CDROMIcon)); + + return noErr; + + // 68k code causes crash in sheep and link error in basilisk +// M68kRegisters r; +// static const uint8 proc[] = { +// 0x55, 0x8f, // subq.l #2,sp +// 0xa9, 0x94, // CurResFile +// 0x42, 0x67, // clr.w -(sp) +// 0xa9, 0x98, // UseResFile +// 0x59, 0x8f, // subq.l #4,sp +// 0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp) +// 0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp) +// 0xa9, 0xa0, // GetResource +// 0x24, 0x5f, // move.l (sp)+,a2 +// 0xa9, 0x98, // UseResFile +// 0x20, 0x0a, // move.l a2,d0 +// 0x66, 0x04, // bne 1 +// 0x70, 0x00, // moveq #0,d0 +// M68K_RTS >> 8, M68K_RTS & 0xff, +// 0x2f, 0x0a, //1 move.l a2,-(sp) +// 0xa9, 0x92, // DetachResource +// 0x20, 0x4a, // move.l a2,a0 +// 0xa0, 0x4a, // HNoPurge +// 0x70, 0x01, // moveq #1,d0 +// M68K_RTS >> 8, M68K_RTS & 0xff +// }; +// Execute68k(Host2MacAddr((uint8 *)proc), &r); +// if (r.d[0]) { +// WriteMacInt32(pb + csParam, 4); // Length of returned data +// WriteMacInt32(pb + csParam + 4, r.a[2]); // Handle to icon suite +// return noErr; +// } else +// return -192; // resNotFound + } + + case siInputSource: { + // return -231 if only 1 or index of current source if more + + WriteMacInt32(pb + csParam, 2); + WriteMacInt16(pb + csParam + 4, SoundInSource); // index of selected source + return noErr; + } + + case siInputSourceNames: { + // return -231 if only 1 or handle to STR# resource if more + + const uint8 str[] = { + 0x00, 0x02, // 2-byte count of #strings + // byte size indicator (up to 255 length supported) + 0x0a, // size is 10 + 0x4d, 0x69, // Mi + 0x63, 0x72, // cr + 0x6f, 0x70, // op + 0x68, 0x6f, // ho + 0x6e, 0x65, // ne + 0x0b, // size is 11 + 0x49, 0x6e, // start of string in ASCII, In + 0x74, 0x65, // te + 0x72, 0x6e, // rn + 0x61, 0x6c, // al + 0x20, 0x43, // C + 0x44, // D }; - Execute68k(Host2MacAddr((uint8 *)proc), &r); - if (r.d[0]) { - param[0] = 4; // Length of returned data - param[1] = r.a[2]; // Handle to icon suite - return noErr; - } else - return -192; // resNotFound + + WriteMacInt32(pb + csParam, 0); + + M68kRegisters r; + r.d[0] = sizeof(str); + Execute68kTrap(0xa122, &r); // NewHandle() + uint32 h = r.a[0]; + if (h == 0) + return memFullErr; + WriteMacInt32(bufferptr, h); + uint32 sp = ReadMacInt32(h); + Host2Mac_memcpy(sp, str, sizeof(str)); + + return noErr; + } + + case siOptionsDialog: { + // 0 if no options box supported and 1 if so + WriteMacInt32(pb + csParam, 2); // response not in buffer, need to copy integer + WriteMacInt16(pb + csParam + 4, 1); // Integer data type + return noErr; + } + + case siPlayThruOnOff: { + // playthrough volume, 0 is off and 7 is max + WriteMacInt32(pb + csParam, 2); + WriteMacInt16(pb + csParam + 4, SoundInPlaythrough); + return noErr; + } + + case siNumberChannels: { + // 1 is mono and 2 is stereo + WriteMacInt32(pb + csParam, 2); + WriteMacInt16(pb + csParam + 4, 2); + return noErr; + } + + case siSampleRate: { + WriteMacInt32(pb + csParam, 0); + WriteMacInt32(bufferptr, 0xac440000); // 44100.00000 Hz, of Fixed data type + return noErr; + } + + case siSampleRateAvailable: { + WriteMacInt32(pb + csParam, 0); + + M68kRegisters r; + r.d[0] = 4; + Execute68kTrap(0xa122, &r); // NewHandle() + uint32 h = r.a[0]; + if (h == 0) + return memFullErr; + WriteMacInt16(bufferptr, 1); // 1 sample rate available + WriteMacInt32(bufferptr + 2, h); // handle to sample rate list + uint32 sp = ReadMacInt32(h); + WriteMacInt32(sp, 0xac440000); // 44100.00000 Hz, of Fixed data type + + return noErr; + } + + case siInputGain: { + WriteMacInt32(pb + csParam, 4); + WriteMacInt32(pb + csParam + 4, SoundInGain); + return noErr; } -#endif + + default: return -231; // siUnknownInfoType } diff --git a/BasiliskII/src/Unix/bincue_unix.cpp b/BasiliskII/src/bincue.cpp similarity index 56% rename from BasiliskII/src/Unix/bincue_unix.cpp rename to BasiliskII/src/bincue.cpp index b20b8543f..a500811f3 100644 --- a/BasiliskII/src/Unix/bincue_unix.cpp +++ b/BasiliskII/src/bincue.cpp @@ -41,6 +41,8 @@ #include #include +#include + #ifdef OSX_CORE_AUDIO #include "../MacOSX/MacOSX_sound_if.h" static int bincue_core_audio_callback(void); @@ -51,15 +53,20 @@ static int bincue_core_audio_callback(void); #include #endif -#include "bincue_unix.h" +#ifdef WIN32 +#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) +#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0) +#endif + +#include "bincue.h" #define DEBUG 0 #include "debug.h" #define MAXTRACK 100 #define MAXLINE 512 #define CD_FRAMES 75 -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 +//#define RAW_SECTOR_SIZE 2352 +//#define COOKED_SECTOR_SIZE 2048 // Bits of Track Control Field -- These are standard for scsi cd players @@ -91,6 +98,7 @@ typedef struct { unsigned int length; // Track length in frames loff_t fileoffset; // Track frame start within file unsigned int pregap; // Silence in frames to generate + unsigned int postgap; // Silence in frames to generate at end unsigned char tcf; // Track control field } Track; @@ -99,7 +107,10 @@ typedef struct { unsigned int length; // file length in frames int binfh; // binary file handle int tcnt; // number of tracks - Track tracks[MAXTRACK]; + Track tracks[MAXTRACK]; // Track management + int raw_sector_size; // Raw bytes to read per sector + int cooked_sector_size; // Actual data bytes per sector (depends on Mode) + int header_size; // Number of bytes used in header } CueSheet; typedef struct { @@ -110,10 +121,17 @@ typedef struct { unsigned int audioend; // end position if playing (frames) unsigned int silence; // pregap (silence) bytes unsigned char audiostatus; // See defines above for status + uint8 volume_left; // CD player volume (left) + uint8 volume_right; // CD player volume (right) + uint8 volume_mono; // CD player single-channel volume loff_t fileoffset; // offset from file beginning to audiostart + bool audio_enabled = false; // audio initialized for this player? #ifdef OSX_CORE_AUDIO OSXsoundOutput soundoutput; #endif +#ifdef USE_SDL_AUDIO + SDL_AudioStream *stream; +#endif } CDPlayer; // Minute,Second,Frame data type @@ -127,15 +145,24 @@ typedef struct { static unsigned int totalPregap; static unsigned int prestart; -// Audio System State +// Audio System Variables -static bool audio_enabled = false; static uint8 silence_byte; -// CD Player state. Note only one player is supported ! +// CD Player state; multiple players supported through vectors + +std::vector players; -static CDPlayer player; +CDPlayer* currently_playing = NULL; + +CDPlayer* CSToPlayer(CueSheet* cs) +{ + for (std::vector::iterator it = players.begin(); it != players.end(); ++it) + if (cs == (*it)->cs) // look for cuesheet matching existing player + return *it; + return NULL; // if no player with the cuesheet found, return null player +} static void FramesToMSF(unsigned int frames, MSF *msf) { @@ -181,7 +208,7 @@ static bool AddTrack(CueSheet *cs) } } - curr->fileoffset = curr->start * RAW_SECTOR_SIZE; + curr->fileoffset = curr->start * cs->raw_sector_size; // now we patch up the indicated time @@ -236,6 +263,11 @@ static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile) totalPregap = 0; prestart = 0; + + // Use Audio CD settings by default, otherwise data mode will be specified + cs->raw_sector_size = 2352; + cs->cooked_sector_size = 2352; + cs->header_size = 0; while (fgets(line, MAXLINE, fh) != NULL) { Track *curr = &cs->tracks[cs->tcnt]; @@ -294,11 +326,24 @@ static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile) } curr->number = i_track; - // parse track type + // parse track type and update sector size for data discs if applicable field = strtok(NULL, " \t\n\r"); - if (!strcmp("MODE1/2352", field)) { + if (!strcmp("MODE1/2352", field)) { // red-book CD-ROM standard + curr->tcf = DATA; + cs->raw_sector_size = 2352; + cs->cooked_sector_size = 2048; + cs->header_size = 16; // remaining 288 bytes for error detection + } else if (!strcmp("MODE2/2352", field)) { // yellow-book CD-ROM standard + curr->tcf = DATA; + cs->raw_sector_size = 2352; + cs->cooked_sector_size = 2336; // no error bytes at end + cs->header_size = 16; + } else if (!strcmp("MODE1/2048", field)) { // pure data CD-ROM curr->tcf = DATA; + cs->raw_sector_size = 2048; + cs->cooked_sector_size = 2048; + cs->header_size = 0; // no header or error bytes } else if (!strcmp("AUDIO", field)) { curr->tcf = AUDIO; } else { @@ -342,8 +387,18 @@ static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile) } curr->pregap = MSFToFrames(msf); + } else if (!strcmp("POSTGAP", keyword)) { + MSF msf; + char *field = strtok(NULL, " \t\n\r"); + if (3 != sscanf(field, "%d:%d:%d", + &msf.m, &msf.s, &msf.f)) { + D(bug("Expected postgap frame\n")); + goto fail; + } + curr->postgap = MSFToFrames(msf); + // Ignored directives - + } else if (!strcmp("TITLE", keyword)) { } else if (!strcmp("PERFORMER", keyword)) { } else if (!strcmp("REM", keyword)) { @@ -377,8 +432,12 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs) if (!ParseCueSheet(fh, cs, cuefile)) goto fail; // Open bin file and find length - - if ((binfh = open(cs->binfile,O_RDONLY)) < 0) { + #ifdef WIN32 + binfh = open(cs->binfile,O_RDONLY|O_BINARY); + #else + binfh = open(cs->binfile,O_RDONLY); + #endif + if (binfh < 0) { D(bug("Can't read bin file %s\n", cs->binfile)); goto fail; } @@ -392,7 +451,7 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs) tlast = &cs->tracks[cs->tcnt - 1]; - tlast->length = buf.st_size/RAW_SECTOR_SIZE + tlast->length = buf.st_size/cs->raw_sector_size - tlast->start + totalPregap; if (tlast->length < 0) { @@ -402,7 +461,7 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs) // save bin file length and pointer - cs->length = buf.st_size/RAW_SECTOR_SIZE; + cs->length = buf.st_size/cs->raw_sector_size; cs->binfh = binfh; fclose(fh); @@ -423,45 +482,62 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs) void *open_bincue(const char *name) { - CueSheet *cs; - - if (player.cs == NULL) { - cs = (CueSheet *) malloc(sizeof(CueSheet)); - if (!cs) { - D(bug("malloc failed\n")); - return NULL; - } + CueSheet *cs = (CueSheet *) malloc(sizeof(CueSheet)); + if (!cs) { + D(bug("malloc failed\n")); + return NULL; + } - if (LoadCueSheet(name, cs)) { - player.cs = cs; + if (LoadCueSheet(name, cs)) { + CDPlayer *player = (CDPlayer *) malloc(sizeof(CDPlayer)); + player->cs = cs; + player->volume_left = 0; + player->volume_right = 0; + player->volume_mono = 0; #ifdef OSX_CORE_AUDIO - audio_enabled = true; + player->audio_enabled = true; #endif - if (audio_enabled) - player.audiostatus = CDROM_AUDIO_NO_STATUS; - else - player.audiostatus = CDROM_AUDIO_INVALID; - player.audiofh = dup(cs->binfh); - return cs; - } + if (player->audio_enabled) + player->audiostatus = CDROM_AUDIO_NO_STATUS; else - free(cs); + player->audiostatus = CDROM_AUDIO_INVALID; + player->audiofh = dup(cs->binfh); + + // add to list of available CD players + players.push_back(player); + + return cs; } + else + free(cs); + return NULL; } void close_bincue(void *fh) { - - + CueSheet *cs = (CueSheet *) fh; + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + free(cs); +#ifdef USE_SDL_AUDIO + if (player->stream) // if audiostream has been opened, free it as well + free(player->stream); +#endif + free(player); + } } /* * File read (cooked) * Data are stored in raw sectors of which only COOKED_SECTOR_SIZE - * bytes are valid -- the remaining include 16 bytes at the beginning + * bytes are valid -- the remaining include header bytes at the beginning * of each raw sector and RAW_SECTOR_SIZE - COOKED_SECTOR_SIZE - bytes - * at the end + * at the end for error correction + * + * The actual number of bytes used for header, raw, cooked, error depend + * on mode specified in the cuesheet * * We assume that a read request can land in the middle of * sector. We compute the byte address of that sector (sec) @@ -473,20 +549,20 @@ void close_bincue(void *fh) size_t read_bincue(void *fh, void *b, loff_t offset, size_t len) { + CueSheet *cs = (CueSheet *) fh; + size_t bytes_read = 0; // bytes read so far unsigned char *buf = (unsigned char *) b; // target buffer - unsigned char secbuf[RAW_SECTOR_SIZE]; // temporary buffer + unsigned char secbuf[cs->raw_sector_size]; // temporary buffer - off_t sec = ((offset/COOKED_SECTOR_SIZE) * RAW_SECTOR_SIZE); - off_t secoff = offset % COOKED_SECTOR_SIZE; + off_t sec = ((offset/cs->cooked_sector_size) * cs->raw_sector_size); + off_t secoff = offset % cs->cooked_sector_size; // sec contains location (in bytes) of next raw sector to read // secoff contains offset within that sector at which to start // reading since we can request a read that starts in the middle // of a sector - CueSheet *cs = (CueSheet *) fh; - if (cs == NULL || lseek(cs->binfh, sec, SEEK_SET) < 0) { return -1; } @@ -495,19 +571,19 @@ size_t read_bincue(void *fh, void *b, loff_t offset, size_t len) // bytes available in next raw sector or len (bytes) // we want whichever is less - size_t available = COOKED_SECTOR_SIZE - secoff; + size_t available = cs->cooked_sector_size - secoff; available = (available > len) ? len : available; // read the next raw sector - if (read(cs->binfh, secbuf, RAW_SECTOR_SIZE) != RAW_SECTOR_SIZE) { + if (read(cs->binfh, secbuf, cs->raw_sector_size) != cs->raw_sector_size) { return bytes_read; } - // copy cooked sector bytes (skip first 16) + // copy cooked sector bytes (skip header if needed, typically 16 bytes) // we want out of those available - bcopy(&secbuf[16+secoff], &buf[bytes_read], available); + bcopy(&secbuf[cs->header_size+secoff], &buf[bytes_read], available); // next sector we start at the beginning @@ -524,8 +600,9 @@ size_t read_bincue(void *fh, void *b, loff_t offset, size_t len) loff_t size_bincue(void *fh) { if (fh) { - return ((CueSheet *)fh)->length * COOKED_SECTOR_SIZE; + return ((CueSheet *)fh)->length * ((CueSheet *)fh)->cooked_sector_size; } + return 0; } bool readtoc_bincue(void *fh, unsigned char *toc) @@ -564,25 +641,28 @@ bool readtoc_bincue(void *fh, unsigned char *toc) *toc++ = toc_size & 0xff; return true; } + return false; } bool GetPosition_bincue(void *fh, uint8 *pos) { CueSheet *cs = (CueSheet *) fh; - if (cs && player.cs == cs) { + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { MSF abs, rel; - int fpos = player.audioposition / RAW_SECTOR_SIZE + player.audiostart; + int fpos = player->audioposition / cs->raw_sector_size + player->audiostart; int trackno = PositionToTrack(cs, fpos); - if (!audio_enabled) + if (!(player->audio_enabled)) return false; FramesToMSF(fpos, &abs); if (trackno < cs->tcnt) { // compute position relative to start of frame - unsigned int position = player.audioposition/RAW_SECTOR_SIZE + - player.audiostart - player.cs->tracks[trackno].start; + unsigned int position = player->audioposition/cs->raw_sector_size + + player->audiostart - player->cs->tracks[trackno].start; FramesToMSF(position, &rel); } @@ -590,7 +670,7 @@ bool GetPosition_bincue(void *fh, uint8 *pos) FramesToMSF(0, &rel); *pos++ = 0; - *pos++ = player.audiostatus; + *pos++ = player->audiostatus; *pos++ = 0; *pos++ = 12; // Sub-Q data length *pos++ = 0; @@ -606,7 +686,7 @@ bool GetPosition_bincue(void *fh, uint8 *pos) *pos++ = rel.m; *pos++ = rel.s; *pos++ = rel.f; - *pos++ = 0; +// *pos++ = 0; // D(bug("CDROM position %02d:%02d:%02d track %02d\n", abs.m, abs.s, abs.f, trackno)); return true; } @@ -614,14 +694,26 @@ bool GetPosition_bincue(void *fh, uint8 *pos) return false; } +void CDPause_playing(CDPlayer* player) { + if (currently_playing && currently_playing != player) { + currently_playing->audiostatus = CDROM_AUDIO_PAUSED; + currently_playing = NULL; + } +} + bool CDPause_bincue(void *fh) { CueSheet *cs = (CueSheet *) fh; - if (cs && cs == player.cs) { - if (player.audiostatus == CDROM_AUDIO_PLAY) { - player.audiostatus = CDROM_AUDIO_PAUSED; - return true; - } + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + // Pause another player if needed + CDPause_playing(player); + + // doesn't matter if it was playing, just ensure it's now paused + player->audiostatus = CDROM_AUDIO_PAUSED; + currently_playing = NULL; + return true; } return false; } @@ -629,13 +721,19 @@ bool CDPause_bincue(void *fh) bool CDStop_bincue(void *fh) { CueSheet *cs = (CueSheet *) fh; - - if (cs && cs == player.cs) { + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + // Pause another player if needed + CDPause_playing(player); + #ifdef OSX_CORE_AUDIO - player.soundoutput.stop(); + player->soundoutput.stop(); #endif - if (player.audiostatus != CDROM_AUDIO_INVALID) - player.audiostatus = CDROM_AUDIO_NO_STATUS; + if (player->audiostatus != CDROM_AUDIO_INVALID) + player->audiostatus = CDROM_AUDIO_NO_STATUS; + + currently_playing = NULL; return true; } return false; @@ -644,11 +742,16 @@ bool CDStop_bincue(void *fh) bool CDResume_bincue(void *fh) { CueSheet *cs = (CueSheet *) fh; - if (cs && cs == player.cs) { - if (player.audiostatus == CDROM_AUDIO_PAUSED) { - player.audiostatus = CDROM_AUDIO_PLAY; - return true; - } + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + // Pause another player if needed + CDPause_playing(player); + + // doesn't matter if it was paused, just ensure this one plays now + player->audiostatus = CDROM_AUDIO_PLAY; + currently_playing = player; + return true; } return false; } @@ -656,8 +759,13 @@ bool CDResume_bincue(void *fh) bool CDPlay_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f) { - CueSheet *cs = (CueSheet *)fh; - if (cs && cs == player.cs) { + CueSheet *cs = (CueSheet *) fh; + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + // Pause another player if needed + CDPause_playing(player); + int track; MSF msf; @@ -665,42 +773,42 @@ bool CDPlay_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f, SDL_LockAudio(); #endif - player.audiostatus = CDROM_AUDIO_NO_STATUS; + player->audiostatus = CDROM_AUDIO_NO_STATUS; - player.audiostart = (start_m * 60 * CD_FRAMES) + + player->audiostart = (start_m * 60 * CD_FRAMES) + (start_s * CD_FRAMES) + start_f; - player.audioend = (end_m * 60 * CD_FRAMES) + (end_s * CD_FRAMES) + end_f; + player->audioend = (end_m * 60 * CD_FRAMES) + (end_s * CD_FRAMES) + end_f; - track = PositionToTrack(player.cs, player.audiostart); + track = PositionToTrack(player->cs, player->audiostart); - if (track < player.cs->tcnt) { - player.audioposition = 0; + if (track < player->cs->tcnt) { + player->audioposition = 0; // here we need to compute silence - if (player.audiostart - player.cs->tracks[track].start > - player.cs->tracks[track].pregap) - player.silence = 0; + if (player->audiostart - player->cs->tracks[track].start > + player->cs->tracks[track].pregap) + player->silence = 0; else - player.silence = (player.cs->tracks[track].pregap - - player.audiostart + - player.cs->tracks[track].start) * RAW_SECTOR_SIZE; + player->silence = (player->cs->tracks[track].pregap - + player->audiostart + + player->cs->tracks[track].start) * cs->raw_sector_size; - player.fileoffset = player.cs->tracks[track].fileoffset; + player->fileoffset = player->cs->tracks[track].fileoffset; - D(bug("file offset %d\n", (unsigned int) player.fileoffset)); + D(bug("file offset %d\n", (unsigned int) player->fileoffset)); // fix up file offset if beyond the silence bytes - if (!player.silence) // not at the beginning - player.fileoffset += (player.audiostart - - player.cs->tracks[track].start - - player.cs->tracks[track].pregap) * RAW_SECTOR_SIZE; + if (!player->silence) // not at the beginning + player->fileoffset += (player->audiostart - + player->cs->tracks[track].start - + player->cs->tracks[track].pregap) * cs->raw_sector_size; - FramesToMSF(player.cs->tracks[track].start, &msf); + FramesToMSF(player->cs->tracks[track].start, &msf); D(bug("CDPlay_bincue track %02d start %02d:%02d:%02d silence %d", - player.cs->tracks[track].number, msf.m, msf.s, msf.f, - player.silence/RAW_SECTOR_SIZE)); + player->cs->tracks[track].number, msf.m, msf.s, msf.f, + player->silence/cs->raw_sector_size)); D(bug(" Stop %02u:%02u:%02u\n", end_m, end_s, end_f)); } else @@ -710,21 +818,71 @@ bool CDPlay_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f, SDL_UnlockAudio(); #endif - if (audio_enabled) { - player.audiostatus = CDROM_AUDIO_PLAY; + if (player->audio_enabled) { + player->audiostatus = CDROM_AUDIO_PLAY; #ifdef OSX_CORE_AUDIO D(bug("starting os x sound")); - player.soundoutput.setCallback(bincue_core_audio_callback); + player->soundoutput.setCallback(bincue_core_audio_callback); // should be from current track ! - player.soundoutput.start(16, 2, 44100); + player->soundoutput.start(16, 2, 44100); #endif + currently_playing = player; return true; } } return false; } -static uint8 *fill_buffer(int stream_len) +bool CDScan_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) { + CueSheet *cs = (CueSheet *) fh; + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + uint8 scanrate = 8; // 8x scan default but could use different value or make configurable + + MSF msf; + msf.m = start_m; msf.s = start_s; msf.f = start_f; + int current_frame = MSFToFrames(msf); + + if (reverse) { + msf.s -= scanrate; + int goto_frame = MSFToFrames(msf); + player->audioposition -= (current_frame - goto_frame) * player->cs->raw_sector_size; + } + else { + msf.s += scanrate; + int goto_frame = MSFToFrames(msf); + player->audioposition += (goto_frame - current_frame) * player->cs->raw_sector_size; + } + return true; + } + return false; +} + +void CDSetVol_bincue(void* fh, uint8 left, uint8 right) { + CueSheet *cs = (CueSheet *) fh; + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { + // Convert from classic Mac's 0-255 to 0-128; + // calculate mono mix as well in place of panning + player->volume_left = (left*128)/255; + player->volume_right = (right*128)/255; + player->volume_mono = (player->volume_left + player->volume_right)/2; // use avg + } +} + +void CDGetVol_bincue(void* fh, uint8* left, uint8* right) { + CueSheet *cs = (CueSheet *) fh; + CDPlayer *player = CSToPlayer(cs); + + if (cs && player) { // Convert from 0-128 to 0-255 scale + *left = (player->volume_left*255)/128; + *right = (player->volume_right*255)/128; + } +} + +static uint8 *fill_buffer(int stream_len, CDPlayer* player) { static uint8 *buf = 0; static int bufsize = 0; @@ -743,44 +901,44 @@ static uint8 *fill_buffer(int stream_len) } memset(buf, silence_byte, stream_len); + + if (player->audiostatus == CDROM_AUDIO_PLAY) { + int remaining_silence = player->silence - player->audioposition; - if (player.audiostatus == CDROM_AUDIO_PLAY) { - int remaining_silence = player.silence - player.audioposition; - - if (player.audiostart + player.audioposition/RAW_SECTOR_SIZE - >= player.audioend) { - player.audiostatus = CDROM_AUDIO_COMPLETED; + if (player->audiostart + player->audioposition/player->cs->raw_sector_size + >= player->audioend) { + player->audiostatus = CDROM_AUDIO_COMPLETED; return buf; } if (remaining_silence >= stream_len) { - player.audioposition += stream_len; + player->audioposition += stream_len; return buf; } if (remaining_silence > 0) { offset += remaining_silence; - player.audioposition += remaining_silence; + player->audioposition += remaining_silence; } int ret = 0; - int available = ((player.audioend - player.audiostart) * - RAW_SECTOR_SIZE) - player.audioposition; + int available = ((player->audioend - player->audiostart) * + player->cs->raw_sector_size) - player->audioposition; if (available > (stream_len - offset)) available = stream_len - offset; - if (lseek(player.audiofh, - player.fileoffset + player.audioposition - player.silence, + if (lseek(player->audiofh, + player->fileoffset + player->audioposition - player->silence, SEEK_SET) < 0) return NULL; if (available < 0) { - player.audioposition += available; // correct end !; + player->audioposition += available; // correct end !; available = 0; } - if ((ret = read(player.audiofh, &buf[offset], available)) >= 0) { - player.audioposition += ret; + if ((ret = read(player->audiofh, &buf[offset], available)) >= 0) { + player->audioposition += ret; offset += ret; available -= ret; } @@ -788,33 +946,56 @@ static uint8 *fill_buffer(int stream_len) while (offset < stream_len) { buf[offset++] = silence_byte; if (available-- > 0){ - player.audioposition++; + player->audioposition++; } } - } + } return buf; } #ifdef USE_SDL_AUDIO -void MixAudio_bincue(uint8 *stream, int stream_len) +void MixAudio_bincue(uint8 *stream, int stream_len, int volume) { - if (audio_enabled && (player.audiostatus == CDROM_AUDIO_PLAY)) { - uint8 *buf = fill_buffer(stream_len); - if (buf) - SDL_MixAudio(stream, buf, stream_len, SDL_MIX_MAXVOLUME); + if (currently_playing) { + + CDPlayer *player = currently_playing; + + if (player->audiostatus == CDROM_AUDIO_PLAY) { + uint8 *buf = fill_buffer(stream_len, player); + if (buf) + SDL_AudioStreamPut(player->stream, buf, stream_len); + int avail = SDL_AudioStreamAvailable(player->stream); + if (avail >= stream_len) { + uint8 converted[stream_len]; + SDL_AudioStreamGet(player->stream, converted, stream_len); + SDL_MixAudio(stream, converted, stream_len, player->volume_mono); + } + } + } } -void OpenAudio_bincue(int freq, int format, int channels, uint8 silence) +void OpenAudio_bincue(int freq, int format, int channels, uint8 silence, int volume) { - if (freq == 44100 && format == AUDIO_S16MSB && channels == 2) { - audio_enabled = true; - silence_byte = silence; - } - else { - D(bug("unexpected frequency %d , format %d, or channels %d\n", - freq, format, channels)); + // setup silence at init + silence_byte = silence; + + // init players + for (std::vector::iterator it = players.begin(); it != players.end(); ++it) + { + CDPlayer *player = *it; + + // set player volume based on SDL volume + player->volume_left = player->volume_right = player->volume_mono = volume; + // audio stream handles converting cd audio to destination output + player->stream = SDL_NewAudioStream(AUDIO_S16LSB, 2, 44100, format, channels, freq); + if (player->stream == NULL) { + D(bug("Failed to open CD player audio stream using SDL!")); + } + else { + player->audio_enabled = true; + } } } #endif @@ -822,13 +1003,18 @@ void OpenAudio_bincue(int freq, int format, int channels, uint8 silence) #ifdef OSX_CORE_AUDIO static int bincue_core_audio_callback(void) { - int frames = player.soundoutput.bufferSizeFrames(); - uint8 *buf = fill_buffer(frames*4); + for (std::vector::iterator it = players.begin(); it != players.end(); ++it) + { + CDPlayer *player = *it; + + int frames = player->soundoutput.bufferSizeFrames(); + uint8 *buf = fill_buffer(frames*4); - // D(bug("Audio request %d\n", stream_len)); + // D(bug("Audio request %d\n", stream_len)); - player.soundoutput.sendAudioBuffer((void *) buf, (buf ? frames : 0)); + player->soundoutput.sendAudioBuffer((void *) buf, (buf ? frames : 0)); - return 1; + return 1; + } } #endif diff --git a/BasiliskII/src/cdrom.cpp b/BasiliskII/src/cdrom.cpp index 370322d1c..964f116df 100644 --- a/BasiliskII/src/cdrom.cpp +++ b/BasiliskII/src/cdrom.cpp @@ -58,7 +58,7 @@ const uint8 CDROMIcon[258] = { 0x8a, 0xaa, 0xaa, 0xe4, 0x8d, 0x55, 0x55, 0xc4, 0x86, 0xaa, 0xab, 0xc4, 0x83, 0x55, 0x57, 0x84, 0x81, 0xaa, 0xaf, 0x04, 0x80, 0xf5, 0x7e, 0x04, 0x80, 0x3f, 0xf8, 0x04, 0x80, 0x0f, 0xe0, 0x04, 0xff, 0xff, 0xff, 0xfc, 0x80, 0x00, 0x00, 0x04, 0x80, 0x1f, 0xf0, 0x04, 0x7f, 0xff, 0xff, 0xf8, - + 0x3f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, @@ -67,7 +67,7 @@ const uint8 CDROMIcon[258] = { 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xf8, - + 0, 0 }; @@ -103,7 +103,7 @@ static const uint8 bin2bcd[256] = { }; static const uint8 bcd2bin[256] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -126,9 +126,9 @@ static const uint8 bcd2bin[256] = { struct cdrom_drive_info { cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0) {} cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0) {} - + void close_fh(void) { SysAllowRemoval(fh); Sys_close(fh); } - + int num; // Drive number void *fh; // File handle int block_size; // CD-ROM block size @@ -136,12 +136,15 @@ struct cdrom_drive_info { loff_t start_byte; // Start of HFS partition on disk bool to_be_mounted; // Flag: drive must be mounted in accRun bool mount_non_hfs; // Flag: Issue disk-inserted events for non-HFS disks - + uint8 toc[804]; // TOC of currently inserted disk uint8 lead_out[3]; // MSF address of lead-out track uint8 stop_at[3]; // MSF address of audio play stopping point - + uint8 start_at[3]; // MSF address of position set by track search or audio play + uint8 play_mode; // Audio play mode + uint8 play_order; // Play mode order (normal, shuffle, program) + bool repeat; // Repeat flag uint8 power_mode; // Power mode uint32 status; // Mac address of drive status record }; @@ -150,6 +153,8 @@ struct cdrom_drive_info { typedef vector drive_vec; static drive_vec drives; +int last_drive_num; // track last drive called to support multiple audio CDs + // Icon address (Mac address space, set by PatchROM()) uint32 CDROMIconAddr; @@ -165,8 +170,10 @@ static drive_vec::iterator get_drive_info(int num) { drive_vec::iterator info, end = drives.end(); for (info = drives.begin(); info != end; ++info) { - if (info->num == num) + if (info->num == num) { + last_drive_num = num; return info; + } } return info; } @@ -181,18 +188,18 @@ static void find_hfs_partition(cdrom_drive_info &info) info.start_byte = 0; uint8 *map = new uint8[512]; D(bug("Looking for HFS partitions on CD-ROM...\n")); - + // Search first 64 blocks for HFS partition for (int i=0; i<64; i++) { if (Sys_read(info.fh, map, i * 512, 512) != 512) break; D(bug(" block %d, signature '%c%c' (%02x%02x)\n", i, map[0], map[1], map[0], map[1])); - + // Not a partition map block? Then look at next block uint16 sig = (map[0] << 8) | map[1]; if (sig != 0x504d) continue; - + // Partition map block found, Apple HFS partition? if (strcmp((char *)(map + 48), "Apple_HFS") == 0) { info.start_byte = (loff_t)((map[8] << 24) | (map[9] << 16) | (map[10] << 8) | map[11]) << 9; @@ -214,7 +221,7 @@ static void read_toc(cdrom_drive_info &info) // Read TOC memset(info.toc, 0, sizeof(info.toc)); SysCDReadTOC(info.fh, info.toc); - + #if DEBUG // Dump TOC for debugging D(bug(" TOC:\n %02x%02x%02x%02x : %d bytes, first track = %d, last track = %d\n", info.toc[0], info.toc[1], info.toc[2], info.toc[3], (info.toc[0] << 8) | info.toc[1], info.toc[2], info.toc[3])); @@ -226,7 +233,12 @@ static void read_toc(cdrom_drive_info &info) break; } #endif - + + // Default start + info.start_at[0] = 0; + info.start_at[1] = 0; + info.start_at[2] = 0; + // Find lead-out track info.lead_out[0] = 0; info.lead_out[1] = 0; @@ -288,9 +300,10 @@ static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 po void CDROMInit(void) { // No drives specified in prefs? Then add defaults - if (PrefsFindString("cdrom", 0) == NULL) + if (PrefsFindString("cdrom", 0) == NULL) { SysAddCDROMPrefs(); - + } + // Add drives specified in preferences int index = 0; const char *str; @@ -299,6 +312,13 @@ void CDROMInit(void) if (fh) drives.push_back(cdrom_drive_info(fh)); } + + if (!drives.empty()) { // set to first drive by default + last_drive_num = drives.begin()->num; + } + else { + last_drive_num = 0; + } } @@ -348,15 +368,15 @@ static void mount_mountable_volumes(void) { drive_vec::iterator info, end = drives.end(); for (info = drives.begin(); info != end; ++info) { - + // Disk in drive? if (ReadMacInt8(info->status + dsDiskInPlace) == 0) { - + // No, check if disk was inserted if (SysIsDiskInserted(info->fh)) CDROMMountVolume(info->fh); } - + // Mount disk if flagged if (info->to_be_mounted) { D(bug(" mounting drive %d\n", info->num)); @@ -377,25 +397,27 @@ static void mount_mountable_volumes(void) int16 CDROMOpen(uint32 pb, uint32 dce) { D(bug("CDROMOpen\n")); - + // Set up DCE WriteMacInt32(dce + dCtlPosition, 0); acc_run_called = false; - + // Install drives drive_vec::iterator info, end = drives.end(); for (info = drives.begin(); info != end; ++info) { - + info->num = FindFreeDriveNumber(1); info->to_be_mounted = false; - + if (info->fh) { info->mount_non_hfs = true; info->block_size = 512; info->twok_offset = -1; info->play_mode = 0x09; + info->play_order = 0; + info->repeat = 0; info->power_mode = 0; - + // Allocate drive status record M68kRegisters r; r.d[0] = SIZEOF_DrvSts; @@ -404,12 +426,12 @@ int16 CDROMOpen(uint32 pb, uint32 dce) continue; info->status = r.a[0]; D(bug(" DrvSts at %08lx\n", info->status)); - + // Set up drive status WriteMacInt8(info->status + dsWriteProt, 0x80); WriteMacInt8(info->status + dsInstalled, 1); WriteMacInt8(info->status + dsSides, 1); - + // Disk in drive? if (SysIsDiskInserted(info->fh)) { SysPreventRemoval(info->fh); @@ -418,7 +440,7 @@ int16 CDROMOpen(uint32 pb, uint32 dce) find_hfs_partition(*info); info->to_be_mounted = true; } - + // Add drive to drive queue D(bug(" adding drive %d\n", info->num)); r.d[0] = (info->num << 16) | (CDROMRefNum & 0xffff); @@ -426,6 +448,9 @@ int16 CDROMOpen(uint32 pb, uint32 dce) Execute68kTrap(0xa04e, &r); // AddDrive() } } + + CDROMOpenDone(); + return noErr; } @@ -437,14 +462,14 @@ int16 CDROMOpen(uint32 pb, uint32 dce) int16 CDROMPrime(uint32 pb, uint32 dce) { WriteMacInt32(pb + ioActCount, 0); - + // Drive valid and disk inserted? drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); if (info == drives.end()) return nsDrvErr; if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - + // Get parameters void *buffer = Mac2HostAddr(ReadMacInt32(pb + ioBuffer)); size_t length = ReadMacInt32(pb + ioReqCount); @@ -452,17 +477,17 @@ int16 CDROMPrime(uint32 pb, uint32 dce) if ((length & (info->block_size - 1)) || (position & (info->block_size - 1))) return paramErr; info->twok_offset = (position + info->start_byte) & 0x7ff; - + size_t actual = 0; if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) { - + // Read actual = Sys_read(info->fh, buffer, position + info->start_byte, length); if (actual != length) { - + // Read error, tried to read HFS root block? if (length == 0x200 && position == 0x400) { - + // Yes, fake (otherwise audio CDs won't get mounted) memset(buffer, 0, 0x200); actual = 0x200; @@ -473,7 +498,7 @@ int16 CDROMPrime(uint32 pb, uint32 dce) } else { return wPrErr; } - + // Update ParamBlock and DCE WriteMacInt32(pb + ioActCount, actual); WriteMacInt32(dce + dCtlPosition, ReadMacInt32(dce + dCtlPosition) + actual); @@ -489,34 +514,37 @@ int16 CDROMControl(uint32 pb, uint32 dce) { uint16 code = ReadMacInt16(pb + csCode); D(bug("CDROMControl %d\n", code)); - + // General codes switch (code) { case 1: // KillIO return noErr; - + case 65: { // Periodic action (accRun, "insert" disks on startup) mount_mountable_volumes(); WriteMacInt16(dce + dCtlFlags, ReadMacInt16(dce + dCtlFlags) & ~0x2000); // Disable periodic action acc_run_called = true; return noErr; } - + case 81: // Set poll freq WriteMacInt16(dce + dCtlDelay, ReadMacInt16(pb + csParam)); return noErr; } - + // Drive valid? drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); if (info == drives.end()) { if (drives.empty()) { return nsDrvErr; } else { - info = drives.begin(); // This is needed for Apple's Audio CD program + // Audio calls tend to end up without correct reference + // Real mac would just play first disc, but we can guess correct one from last data call + info = get_drive_info(last_drive_num); + if (info == drives.end()) return nsDrvErr; } } - + // Drive-specific codes switch (code) { case 5: // VerifyTheDisc @@ -524,28 +552,54 @@ int16 CDROMControl(uint32 pb, uint32 dce) return noErr; else return offLinErr; - + case 6: // FormatTheDisc return writErr; - + case 7: // EjectTheDisc if (ReadMacInt8(info->status + dsDiskInPlace) > 0) { SysAllowRemoval(info->fh); SysEject(info->fh); WriteMacInt8(info->status + dsDiskInPlace, 0); info->twok_offset = -1; + return noErr; + } else { + return offLinErr; } - return noErr; - + case 21: // GetDriveIcon case 22: // GetMediaIcon WriteMacInt32(pb + csParam, CDROMIconAddr); return noErr; - + case 23: // GetDriveInfo WriteMacInt32(pb + csParam, 0x00000b01); // Unspecified external removable SCSI disk return noErr; - + + // TODO: revist this section, is it necessary with DriverGestalt also in Status section? + case 43: { // DriverGestalt + int selector = ReadMacInt32(pb + csParam); + switch (selector) { + case FOURCC('v','e','r','s'): + WriteMacInt32(pb + csParam + 4, 0x05208000); // vers 5.2.0 + break; + case FOURCC('d','e','v','t'): + WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m')); + break; + case FOURCC('i','n','t','f'): + case FOURCC('d','A','P','I'): + WriteMacInt32(pb + csParam + 4, FOURCC('a','t','p','i')); + break; + case FOURCC('s','y','n','c'): + WriteMacInt32(pb + csParam + 4, 1); // true/false = sync/async + break; + case FOURCC('c','d','3','d'): + WriteMacInt32(pb + csParam + 4, 0); + break; + } + return noErr; + } + case 70: { // SetPowerMode uint8 mode = ReadMacInt8(pb + csParam); if (mode > 3) { @@ -555,11 +609,11 @@ int16 CDROMControl(uint32 pb, uint32 dce) return noErr; } } - + case 76: // ModifyPostEvent info->mount_non_hfs = ReadMacInt16(pb + csParam) != 0; return noErr; - + case 79: { // Change block size uint16 size = ReadMacInt16(pb + csParam); D(bug(" change block size to %d bytes\n", size)); @@ -570,7 +624,7 @@ int16 CDROMControl(uint32 pb, uint32 dce) return noErr; } } - + case 80: // SetUserEject if (ReadMacInt8(info->status + dsDiskInPlace) > 0) { if (ReadMacInt16(pb + csParam) == 1) @@ -581,11 +635,11 @@ int16 CDROMControl(uint32 pb, uint32 dce) } else { return offLinErr; } - + case 100: { // ReadTOC if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - + int action = ReadMacInt16(pb + csParam); D(bug(" read TOC %d\n", action)); switch (action) { @@ -594,26 +648,26 @@ int16 CDROMControl(uint32 pb, uint32 dce) WriteMacInt8(pb + csParam + 1, bin2bcd[info->toc[3]]); WriteMacInt16(pb + csParam + 2, 0); break; - + case 2: // Get lead out MSF starting address WriteMacInt8(pb + csParam, bin2bcd[info->lead_out[0]]); WriteMacInt8(pb + csParam + 1, bin2bcd[info->lead_out[1]]); WriteMacInt8(pb + csParam + 2, bin2bcd[info->lead_out[2]]); WriteMacInt8(pb + csParam + 3, 0); break; - + case 3: { // Get track starting address uint32 buf = ReadMacInt32(pb + csParam + 2); uint16 buf_size = ReadMacInt16(pb + csParam + 6); int track = bcd2bin[ReadMacInt8(pb + csParam + 8)]; - + // Search start track in TOC int i; for (i=4; i<804; i+=8) { if (info->toc[i+2] == track) break; } - + // Fill buffer if (i != 804) { while (buf_size > 0) { @@ -621,18 +675,91 @@ int16 CDROMControl(uint32 pb, uint32 dce) WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++; // M WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++; // S WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++; // F - + // Lead-Out? Then stop if (info->toc[i+2] == 0xaa) break; - + buf_size -= 4; i += 8; } } break; } - + + case 4: { // Type 4 TOC for non-AppleCD SC + uint32 buf = ReadMacInt32(pb + csParam + 2); + uint16 buf_size = 512; // buffer must be 512 bytes for this TOC type + + // start filling buffer + WriteMacInt8(buf, 0); buf++; // first byte reserved for 0 + buf_size--; + + int i = 4; + // in TOC, first 4 are session and/or track number; so tracks start at i = 4 + // (info->toc[2] is first track num and info->toc[3] is last num) + // each track entry is 8 bytes: + // 0: unused, 1: control, 2: tracknum, 3: unused + // 4: unused, 5: MIN, 6: SEC, 7: FRAME + + // entry for point A0 (first track num) + WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++; // control field + WriteMacInt8(buf, bin2bcd[info->toc[2]]); buf++; // track number + WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++; // PMIN + WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++; // PSEC + WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++; // PFRAME + buf_size -= 5; // every 8 bits written decreases byte buffer size by 1 + + // entry for point A1 (last track) + int buf_a1 = buf; // save for filling last track num + buf += 5; buf_size -= 5; + + // entry for point A2 (address of start of lead out) + int buf_a2 = buf; // save for filling at end + buf += 5; buf_size -= 5; + + // Fill buffer + while (i <= 804 && buf_size > 1) { // index 511 never used + // Lead out? then fill a2 and stop + if (info->toc[i+2] == 0xaa) { + // entry for point a2 + WriteMacInt8(buf_a2, info->toc[i+1] & 0x0f); // Control + WriteMacInt8(buf_a2 + 1, bin2bcd[info->toc[i+2]]); // tracknum + WriteMacInt8(buf_a2 + 2, bin2bcd[info->lead_out[0]]); // M, same as toc[i+5] + WriteMacInt8(buf_a2 + 3, bin2bcd[info->lead_out[1]]); // S + WriteMacInt8(buf_a2 + 4, bin2bcd[info->lead_out[2]]); // F + break; + } + + WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++; // Control + WriteMacInt8(buf, bin2bcd[info->toc[i+2]]); buf++; // tracknum + WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++; // M + WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++; // S + WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++; // F + + // Last track? fill a1 as well + if (info->toc[i+2] == info->toc[3]) { + // entry for point a1 + WriteMacInt8(buf_a1, info->toc[i+1] & 0x0f); // Control + WriteMacInt8(buf_a1 + 1, bin2bcd[info->toc[3]]); // tracknum + WriteMacInt8(buf_a1 + 2, bin2bcd[info->toc[i+5]]); // M + WriteMacInt8(buf_a1 + 3, bin2bcd[info->toc[i+6]]); // S + WriteMacInt8(buf_a1 + 4, bin2bcd[info->toc[i+7]]); // F + } + + buf_size -= 5; + i += 8; + } + + // fill rest of buffer with zeroes + while (buf_size > 0) { + WriteMacInt8(buf, 0); buf++; + buf_size--; + } + + break; + } + case 5: // Get session information WriteMacInt16(pb + csParam, 1); // First session number WriteMacInt16(pb + csParam + 2, 1); // Last session number @@ -642,20 +769,20 @@ int16 CDROMControl(uint32 pb, uint32 dce) WriteMacInt8(pb + csParam + 8, bin2bcd[info->toc[10]]); // S WriteMacInt8(pb + csParam + 9, bin2bcd[info->toc[11]]); // F break; - + default: printf("FATAL: .AppleCD/Control(100): unimplemented TOC type\n"); return paramErr; } return noErr; } - + case 101: { // ReadTheQSubcode if (ReadMacInt8(info->status + dsDiskInPlace) == 0) { Mac_memset(pb + csParam, 0, 10); return offLinErr; } - + uint8 pos[16]; if (SysCDGetPosition(info->fh, pos)) { uint32 p = pb + csParam; @@ -674,51 +801,51 @@ int16 CDROMControl(uint32 pb, uint32 dce) return ioErr; } } - + case 102: // ReadHeader printf("FATAL: .AppleCD/Control(102): unimplemented call\n"); return controlErr; - + case 103: { // AudioTrackSearch D(bug(" AudioTrackSearch postype %d, pos %08x, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6))); if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - - uint8 start_m, start_s, start_f; - if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f)) + + if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, info->start_at[0], info->start_at[1], info->start_at[2])) return paramErr; info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f; - if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2])) + if (!SysCDPlay(info->fh, info->start_at[0], info->start_at[1], info->start_at[2], info->stop_at[0], info->stop_at[1], info->stop_at[2])) return paramErr; if (ReadMacInt16(pb + csParam + 6) == 0) // Hold SysCDPause(info->fh); return noErr; } - + case 104: // AudioPlay D(bug(" AudioPlay postype %d, pos %08lx, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6))); if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - + + if (ReadMacInt16(pb + csParam + 6)) { // Given stopping address if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2])) return paramErr; } else { // Given starting address - uint8 start_m, start_s, start_f; - if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f)) - return paramErr; - info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f; - if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2])) + if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, info->start_at[0], info->start_at[1], info->start_at[2])) return paramErr; } + // Still need to process the AudioPlay command + info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f; + if (!SysCDPlay(info->fh, info->start_at[0], info->start_at[1], info->start_at[2], info->stop_at[0], info->stop_at[1], info->stop_at[2])) + return paramErr; return noErr; - + case 105: // AudioPause if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - + switch (ReadMacInt32(pb + csParam)) { case 0: if (!SysCDResume(info->fh)) @@ -732,12 +859,12 @@ int16 CDROMControl(uint32 pb, uint32 dce) return paramErr; } return noErr; - + case 106: // AudioStop D(bug(" AudioStop postype %d, pos %08lx\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2))); if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - + if (ReadMacInt16(pb + csParam) == 0 && ReadMacInt32(pb + csParam + 2) == 0) { // Stop immediately if (!SysCDStop(info->fh, info->lead_out[0], info->lead_out[1], info->lead_out[2])) @@ -748,15 +875,15 @@ int16 CDROMControl(uint32 pb, uint32 dce) return paramErr; } return noErr; - + case 107: { // AudioStatus if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - + uint8 pos[16]; if (!SysCDGetPosition(info->fh, pos)) return paramErr; - + uint32 p = pb + csParam; switch (pos[1]) { case 0x11: @@ -783,34 +910,33 @@ int16 CDROMControl(uint32 pb, uint32 dce) WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs) return noErr; } - + case 108: { // AudioScan if (ReadMacInt8(info->status + dsDiskInPlace) == 0) return offLinErr; - - uint8 start_m, start_s, start_f; - if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f)) + + if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, info->start_at[0], info->start_at[1], info->start_at[2])) return paramErr; - - if (!SysCDScan(info->fh, start_m, start_s, start_f, ReadMacInt16(pb + csParam + 6) != 0)) { + + if (!SysCDScan(info->fh, info->start_at[0], info->start_at[1], info->start_at[2], ReadMacInt16(pb + csParam + 6) != 0)) { return paramErr; } else { return noErr; } } - + case 109: // AudioControl SysCDSetVolume(info->fh, ReadMacInt8(pb + csParam), ReadMacInt8(pb + csParam + 1)); return noErr; - + case 110: // ReadMCN printf("FATAL: .AppleCD/Control(110): unimplemented call\n"); return controlErr; - + case 111: // ReadISRC printf("FATAL: .AppleCD/Control(111): unimplemented call\n"); return controlErr; - + case 112: { // ReadAudioVolume uint8 left = 0, right = 0; SysCDGetVolume(info->fh, left, right); @@ -818,43 +944,50 @@ int16 CDROMControl(uint32 pb, uint32 dce) WriteMacInt8(pb + csParam + 1, right); return noErr; } - + case 113: // GetSpindleSpeed WriteMacInt16(pb + csParam, 0xff); return noErr; - + case 114: // SetSpindleSpeed return noErr; - + case 115: // ReadAudio printf("FATAL: .AppleCD/Control(115): unimplemented call\n"); return controlErr; - + case 116: // ReadAllSubcodes printf("FATAL: .AppleCD/Control(116): unimplemented call\n"); return controlErr; - + case 122: // SetTrackList printf("FATAL: .AppleCD/Control(122): unimplemented call\n"); return controlErr; - + case 123: // GetTrackList printf("FATAL: .AppleCD/Control(123): unimplemented call\n"); return controlErr; - + case 124: // GetTrackIndex printf("FATAL: .AppleCD/Control(124): unimplemented call\n"); return controlErr; - + case 125: // SetPlayMode - D(bug(" SetPlayMode %04x\n", ReadMacInt16(pb + csParam))); - printf("FATAL: .AppleCD/Control(125): unimplemented call\n"); - return controlErr; - + // repeat flag (0 is off, 1 is on) + info->repeat = ReadMacInt8(pb + csParam); + // playmode (0 is normal, 1 is shuffle, 2 is program mode) + info->play_order = ReadMacInt8(pb + csParam + 1); + // D(bug(" SetPlayMode %04x\n", ReadMacInt16(pb + csParam))); + // printf("FATAL: .AppleCD/Control(125): unimplemented call\n"); + return noErr; + case 126: // GetPlayMode (Apple's Audio CD program needs this) - WriteMacInt16(pb + csParam, 0); + // repeat flag + WriteMacInt8(pb + csParam, bcd2bin[info->repeat]); + // playmode + WriteMacInt8(pb + csParam + 1, bcd2bin[info->play_order]); return noErr; - + default: printf("WARNING: Unknown CDROMControl(%d)\n", code); return controlErr; @@ -871,7 +1004,7 @@ int16 CDROMStatus(uint32 pb, uint32 dce) drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum)); uint16 code = ReadMacInt16(pb + csCode); D(bug("CDROMStatus %d\n", code)); - + // General codes (we can get these even if the drive was invalid) switch (code) { case 43: { // DriverGestalt @@ -885,10 +1018,12 @@ int16 CDROMStatus(uint32 pb, uint32 dce) WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m')); break; case FOURCC('i','n','t','f'): // Interface type - WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4); +// WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4); + WriteMacInt32(pb + csParam + 4, FOURCC('a','t','p','i')); break; case FOURCC('s','y','n','c'): // Only synchronous operation? WriteMacInt32(pb + csParam + 4, 0x01000000); +// WriteMacInt32(pb + csParam + 4, 1); break; case FOURCC('b','o','o','t'): // Boot ID if (info != drives.end()) @@ -912,12 +1047,15 @@ int16 CDROMStatus(uint32 pb, uint32 dce) case FOURCC('v','m','o','p'): // Virtual memory attributes WriteMacInt32(pb + csParam + 4, 0); // Drive not available for VM break; + case FOURCC('c', 'd', '3', 'd'): + WriteMacInt16(pb + csParam + 4, 0); + break; default: return statusErr; } return noErr; } - + case 97: { // WhoIsThere uint8 drives_present = 0; drive_vec::iterator info, end = drives.end(); @@ -929,15 +1067,17 @@ int16 CDROMStatus(uint32 pb, uint32 dce) return noErr; } } - + // Drive valid? if (info == drives.end()) { - if (drives.empty()) + if (drives.empty()) { return nsDrvErr; - else - info = drives.begin(); // This is needed for Apple's Audio CD program + } else { + info = get_drive_info(last_drive_num); + if (info == drives.end()) return nsDrvErr; + } } - + // Drive-specific codes switch (code) { case 6: // Return format list @@ -950,15 +1090,15 @@ int16 CDROMStatus(uint32 pb, uint32 dce) } else { return paramErr; } - + case 8: // DriveStatus Mac2Mac_memcpy(pb + csParam, info->status, 22); return noErr; - + case 70: // GetPowerMode WriteMacInt16(pb + csParam, info->power_mode << 8); return noErr; - + case 95: // Get2KOffset if (info->twok_offset > 0) { WriteMacInt16(pb + csParam, info->twok_offset); @@ -966,24 +1106,24 @@ int16 CDROMStatus(uint32 pb, uint32 dce) } else { return statusErr; } - + case 96: // Get drive type WriteMacInt16(pb + csParam, 3); // Apple CD 300 or newer return noErr; - + case 98: // Get block size WriteMacInt16(pb + csParam, info->block_size); return noErr; - + case 120: // Return device ident WriteMacInt32(pb + csParam, 0); return noErr; - + case 121: // Get CD features WriteMacInt16(pb + csParam, 0x0200); // 300 KB/s WriteMacInt16(pb + csParam + 2, 0x0c00); // SCSI-2, stereo return noErr; - + default: printf("WARNING: Unknown CDROMStatus(%d)\n", code); return statusErr; @@ -999,6 +1139,6 @@ void CDROMInterrupt(void) { if (!acc_run_called) return; - + mount_mountable_volumes(); } diff --git a/BasiliskII/src/dummy/prefs_dummy.cpp b/BasiliskII/src/dummy/prefs_dummy.cpp index 84dd31ec9..1b33489cd 100644 --- a/BasiliskII/src/dummy/prefs_dummy.cpp +++ b/BasiliskII/src/dummy/prefs_dummy.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "prefs.h" @@ -33,14 +34,20 @@ prefs_desc platform_prefs_items[] = { // Prefs file name and path +#if defined(__APPLE__) && defined(__MACH__) +const char PREFS_FILE_NAME[] = "/tmp/BasiliskII/BasiliskII_Prefs"; // HACK: for now, just load stuff from a fixed dir, inside /tmp +#else const char PREFS_FILE_NAME[] = "BasiliskII_Prefs"; +#endif + +std::string UserPrefsPath; /* * Load preferences from settings file */ -void LoadPrefs(void) +void LoadPrefs(const char * vmdir) // TODO: load prefs from 'vmdir' { // Read preferences from settings file FILE *f = fopen(PREFS_FILE_NAME, "r"); diff --git a/BasiliskII/src/dummy/user_strings_dummy.cpp b/BasiliskII/src/dummy/user_strings_dummy.cpp index 5f97823da..2ff2ead7b 100644 --- a/BasiliskII/src/dummy/user_strings_dummy.cpp +++ b/BasiliskII/src/dummy/user_strings_dummy.cpp @@ -23,7 +23,7 @@ // Platform-specific string definitions -const user_string_def platform_strings[] = { +user_string_def platform_strings[] = { {-1, NULL} // End marker }; @@ -32,7 +32,7 @@ const user_string_def platform_strings[] = { * Fetch pointer to string, given the string number */ -char *GetString(int num) +const char *GetString(int num) { // First search for platform-specific string int i = 0; diff --git a/BasiliskII/src/ether.cpp b/BasiliskII/src/ether.cpp index d5471029d..132217890 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)) { @@ -453,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) @@ -485,4 +475,3 @@ EthernetPacket::~EthernetPacket() bug("WARNING: Nested allocation of ethernet packets!\n"); } } -#endif diff --git a/BasiliskII/src/extfs.cpp b/BasiliskII/src/extfs.cpp index e18d1df1f..b3ce3eec0 100644 --- a/BasiliskII/src/extfs.cpp +++ b/BasiliskII/src/extfs.cpp @@ -106,7 +106,7 @@ static uint32 fs_data = 0; // Mac address of global data static char FS_NAME[32], VOLUME_NAME[32]; // This directory is our root (read from prefs) -static const char *RootPath; +static char RootPath[MAX_PATH_LENGTH]; static bool ready = false; static struct stat root_stat; @@ -196,7 +196,7 @@ static uint32 get_creation_time(const char *path) { if (path == NULL) return 0; - if (path == RootPath) { + if (!strcmp(path, RootPath)) { static uint32 root_crtime = UINT_MAX; if (root_crtime == UINT_MAX) root_crtime = do_get_creation_time(path); @@ -435,7 +435,11 @@ void ExtFSInit(void) p->guest_name[31] = 0; // Find path for root - if ((RootPath = PrefsFindString("extfs")) != NULL) { + *RootPath = 0; + const char *path = PrefsFindString("extfs"); + if (path != NULL) { + strncpy(RootPath, path, MAX_PATH_LENGTH - 1); + RootPath[MAX_PATH_LENGTH - 1] = 0; if (stat(RootPath, &root_stat)) return; if (!S_ISDIR(root_stat.st_mode)) @@ -1049,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)); @@ -1114,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)); @@ -1308,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)); @@ -1433,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/audio_defs.h b/BasiliskII/src/include/audio_defs.h index c52b7d706..3460593ef 100644 --- a/BasiliskII/src/include/audio_defs.h +++ b/BasiliskII/src/include/audio_defs.h @@ -72,14 +72,21 @@ const uint32 siHardwareMute = FOURCC('h','m','u','t'); // mute state of all ha const uint32 siHardwareVolume = FOURCC('h','v','o','l'); // volume level of all hardware const uint32 siHardwareVolumeSteps = FOURCC('h','s','t','p'); // number of volume steps for hardware const uint32 siHardwareBusy = FOURCC('h','w','b','s'); // sound hardware is in use +const uint32 siHardwareFormat = FOURCC('h','w','f','m'); // hardware format const uint32 siHeadphoneMute = FOURCC('p','m','u','t'); // mute state of headphone const uint32 siHeadphoneVolume = FOURCC('p','v','o','l'); // volume level of headphone const uint32 siHeadphoneVolumeSteps = FOURCC('h','d','s','t'); // number of volume steps for headphone const uint32 siSpeakerMute = FOURCC('s','m','u','t'); // mute state of all built-in speakers const uint32 siSpeakerVolume = FOURCC('s','v','o','l'); // volume level of built-in speaker -const uint32 siDeviceName = FOURCC('n','a','m','e'); -const uint32 siDeviceIcon = FOURCC('i','c','o','n'); -const uint32 siHardwareFormat = FOURCC('h','w','f','m'); +const uint32 siDeviceName = FOURCC('n','a','m','e'); // sound input name +const uint32 siDeviceIcon = FOURCC('i','c','o','n'); // sound input icon resource location +const uint32 siInputSourceNames = FOURCC('s','n','a','m'); // sound input source names +const uint32 siInputSource = FOURCC('s','o','u','r'); // sound input source selector +const uint32 siInputGain = FOURCC('g','a','i','n'); // sound input gain +const uint32 siOptionsDialog = FOURCC('o','p','t','d'); // display options dialog box +const uint32 siPlayThruOnOff = FOURCC('p','l','t','h'); // play-through state +const uint32 siInitializeDriver = FOURCC('i','n','i','t'); // open sound input device +const uint32 siCloseDriver = FOURCC('c','l','o','s'); // close sound input device enum { // ComponentResource struct componentType = 0, diff --git a/BasiliskII/src/Unix/bincue_unix.h b/BasiliskII/src/include/bincue.h similarity index 79% rename from BasiliskII/src/Unix/bincue_unix.h rename to BasiliskII/src/include/bincue.h index dbf5d8b58..85a894862 100644 --- a/BasiliskII/src/Unix/bincue_unix.h +++ b/BasiliskII/src/include/bincue.h @@ -1,5 +1,5 @@ /* - * bincue_unix.h -- support for cdrom image files in bin/cue format + * bincue.h -- support for cdrom image files in bin/cue format * * (C) 2010 Geoffrey Brown * @@ -34,10 +34,13 @@ extern bool CDPlay_bincue(void *, uint8, uint8, extern bool CDPause_bincue(void *); extern bool CDResume_bincue(void *); extern bool CDStop_bincue(void *); +extern bool CDScan_bincue(void *, uint8, uint8, uint8, bool); +extern void CDSetVol_bincue(void *, uint8, uint8); +extern void CDGetVol_bincue(void *, uint8 *, uint8 *); #ifdef USE_SDL_AUDIO -extern void OpenAudio_bincue(int, int, int, uint8); -extern void MixAudio_bincue(uint8 *, int); +extern void OpenAudio_bincue(int, int, int, uint8, int); +extern void MixAudio_bincue(uint8 *, int, int); #endif #endif diff --git a/BasiliskII/src/include/cdrom.h b/BasiliskII/src/include/cdrom.h index 0ab114a57..bf899e617 100644 --- a/BasiliskII/src/include/cdrom.h +++ b/BasiliskII/src/include/cdrom.h @@ -40,4 +40,6 @@ extern int16 CDROMPrime(uint32 pb, uint32 dce); extern int16 CDROMControl(uint32 pb, uint32 dce); extern int16 CDROMStatus(uint32 pb, uint32 dce); +extern void CDROMOpenDone(void); // Called by CDROMOpen() once drives have been to the drive queue + #endif diff --git a/BasiliskII/src/include/debug.h b/BasiliskII/src/include/debug.h index 414ad3242..11fa4df78 100644 --- a/BasiliskII/src/include/debug.h +++ b/BasiliskII/src/include/debug.h @@ -30,6 +30,8 @@ #include #include +#include "main.h" + static inline void _cdecl vwinbug(const char *s, va_list vargs) { char msg[1024], date[50], hours[50]; @@ -87,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/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/include/main.h b/BasiliskII/src/include/main.h index cfe9730fb..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; @@ -34,8 +33,15 @@ extern bool TwentyFourBitAddressing; // 68k register structure (for Execute68k()) struct M68kRegisters { uint32 d[8]; +#ifdef UPDATE_UAE + memptr a[8]; + uint16 sr; + memptr usp, isp, msp; + memptr pc; +#else uint32 a[8]; uint16 sr; +#endif }; // General functions diff --git a/BasiliskII/src/include/prefs.h b/BasiliskII/src/include/prefs.h index 216137f2a..380f5590b 100644 --- a/BasiliskII/src/include/prefs.h +++ b/BasiliskII/src/include/prefs.h @@ -48,6 +48,7 @@ extern void PrefsReplaceBool(const char *name, bool b); extern void PrefsReplaceInt32(const char *name, int32 val); extern const char *PrefsFindString(const char *name, int index = 0); +extern "C" const char *PrefsFindStringC(const char *name, int index = 0); extern bool PrefsFindBool(const char *name); extern int32 PrefsFindInt32(const char *name); diff --git a/BasiliskII/src/include/user_strings.h b/BasiliskII/src/include/user_strings.h index 6ac31da99..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, @@ -162,6 +161,12 @@ enum { STR_24_BIT_1600x1200_LAB, STR_SOUND_CTRL, STR_NOSOUND_CTRL, + STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL, + STR_SOFTWARE_LAB, + STR_OPENGL_LAB, + STR_DIRECT3D_LAB, + STR_GRAPHICS_SDL_VSYNC_CTRL, + STR_DEFAULT_LAB, STR_SERIAL_NETWORK_PANE_TITLE = 3500, // Serial/Networking pane STR_SERIALA_CTRL, @@ -188,36 +193,7 @@ enum { STR_RAMSIZE_FMT, STR_MODELID_CTRL, STR_MODELID_5_LAB, - STR_MODELID_7_LAB, - STR_MODELID_12_LAB, - STR_MODELID_13_LAB, STR_MODELID_14_LAB, - STR_MODELID_15_LAB, - STR_MODELID_16_LAB, - STR_MODELID_19_LAB, - STR_MODELID_20_LAB, - STR_MODELID_21_LAB, - STR_MODELID_24_LAB, - STR_MODELID_29_LAB, - STR_MODELID_30_LAB, - STR_MODELID_31_LAB, - STR_MODELID_38_LAB, - STR_MODELID_39_LAB, - STR_MODELID_42_LAB, - STR_MODELID_43_LAB, - STR_MODELID_46_LAB, - STR_MODELID_47_LAB, - STR_MODELID_50_LAB, - STR_MODELID_54_LAB, - STR_MODELID_56_LAB, - STR_MODELID_72_LAB, - STR_MODELID_74_LAB, - STR_MODELID_82_LAB, - STR_MODELID_83_LAB, - STR_MODELID_86_LAB, - STR_MODELID_87_LAB, - STR_MODELID_92_LAB, - STR_MODELID_93_LAB, STR_CPU_CTRL, STR_CPU_68020_LAB, STR_CPU_68020_FPU_LAB, @@ -241,8 +217,6 @@ enum { // Mac window STR_WINDOW_TITLE = 4000, - STR_WINDOW_TITLE_FROZEN, - STR_WINDOW_TITLE_GRABBED, STR_WINDOW_TITLE_GRABBED0, STR_WINDOW_TITLE_GRABBED1, STR_WINDOW_TITLE_GRABBED2, @@ -254,6 +228,9 @@ enum { STR_WINDOW_ITEM_MOUNT, STR_SUSPEND_WINDOW_TITLE, + // Audio + STR_SOUND_IN_NAME = 6000, + // External file system STR_EXTFS_NAME = 5000, STR_EXTFS_VOLUME_NAME diff --git a/BasiliskII/src/include/version.h b/BasiliskII/src/include/version.h index 44819c702..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 = 0; - -#define VERSION_STRING "Basilisk II V1.0" +#ifdef PACKAGE_VERSION // from config.h +#define VERSION_STRING PACKAGE_VERSION +#else +#define VERSION_STRING "1.0" +#endif #endif diff --git a/BasiliskII/src/include/video.h b/BasiliskII/src/include/video.h index a90212596..23bba5e86 100644 --- a/BasiliskII/src/include/video.h +++ b/BasiliskII/src/include/video.h @@ -76,13 +76,16 @@ inline video_depth DepthModeForPixelDepth(int depth) } } -// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width +// Returns the name of a video_depth, or an empty string if the depth is unknown +const char * NameOfDepth(video_depth depth); + +// Return a bytes-per-row value (assuming enough bytes to fit the bits but no further padding) for the specified depth and pixel width inline uint32 TrivialBytesPerRow(uint32 width, video_depth depth) { switch (depth) { - case VDEPTH_1BIT: return width / 8; - case VDEPTH_2BIT: return width / 4; - case VDEPTH_4BIT: return width / 2; + case VDEPTH_1BIT: return (width + 7) / 8; + case VDEPTH_2BIT: return (width + 3) / 4; + case VDEPTH_4BIT: return (width + 1) / 2; case VDEPTH_8BIT: return width; case VDEPTH_16BIT: return width * 2; case VDEPTH_32BIT: return width * 4; @@ -202,8 +205,8 @@ class monitor_desc { // Set palette to 50% gray void set_gray_palette(void); - // Load gamma-corrected black-to-white ramp to palette for direct-color mode - void load_ramp_palette(void); + // Load gamma-corrected black-to-white ramp + void load_gamma_ramp(void); // Allocate gamma table of specified size bool allocate_gamma_table(int size); @@ -247,16 +250,15 @@ class monitor_desc { 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; + + // 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() extern vector VideoMonitors; -// Guest OS Screen Width -extern uint32 MacScreenWidth; -// Guest OS Screen Height -extern uint32 MacScreenHeight; + extern int16 VideoDriverOpen(uint32 pb, uint32 dce); extern int16 VideoDriverControl(uint32 pb, uint32 dce); diff --git a/BasiliskII/src/macos_util.cpp b/BasiliskII/src/macos_util.cpp index 6de3877fc..ba7ac8746 100644 --- a/BasiliskII/src/macos_util.cpp +++ b/BasiliskII/src/macos_util.cpp @@ -26,6 +26,8 @@ #include "disk.h" #include "cdrom.h" #include "macos_util.h" +#include "prefs.h" +#include #define DEBUG 0 #include "debug.h" @@ -131,9 +133,18 @@ uint32 TimeToMacTime(time_t t) // This code is taken from glibc 2.2 // Convert to number of seconds elapsed since 1-Jan-1904 + + #ifdef WIN32 + if (t == -1) { + // failsafe as this will segfault + return 0; + } + #endif struct tm *local = localtime(&t); const int TM_EPOCH_YEAR = 1900; const int MAC_EPOCH_YEAR = 1904; + // Clip year and day offsets to prevent dates earlier than 1-Jan-1904 + local->tm_year = std::max(MAC_EPOCH_YEAR - TM_EPOCH_YEAR, local->tm_year + PrefsFindInt32("yearofs")); int a4 = ((local->tm_year + TM_EPOCH_YEAR) >> 2) - !(local->tm_year & 3); int b4 = (MAC_EPOCH_YEAR >> 2) - !(MAC_EPOCH_YEAR & 3); int a100 = a4 / 25 - (a4 % 25 < 0); @@ -142,7 +153,10 @@ uint32 TimeToMacTime(time_t t) int b400 = b100 >> 2; int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); uint32 days = local->tm_yday + 365 * (local->tm_year - 4) + intervening_leap_days; - return local->tm_sec + 60 * (local->tm_min + 60 * (local->tm_hour + 24 * days)); + int32 dayofs = -PrefsFindInt32("dayofs"); + if(dayofs > 0 && dayofs > days) + dayofs = days; + return local->tm_sec + 60 * (local->tm_min + 60 * (local->tm_hour + 24 * (days - dayofs))); } /* diff --git a/BasiliskII/src/main.cpp b/BasiliskII/src/main.cpp index dcb86e9c2..37484db6a 100644 --- a/BasiliskII/src/main.cpp +++ b/BasiliskII/src/main.cpp @@ -45,31 +45,30 @@ #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 +// CPU and FPU type, addressing mode +int CPUType; +int FPUType; +bool TwentyFourBitAddressing; /* * 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; } -#if EMULATED_68K // Set CPU and FPU type (UAE emulation) switch (ROMVersion) { case ROM_VERSION_64K: @@ -96,8 +95,6 @@ bool InitAll(const char *vmdir) TwentyFourBitAddressing = false; break; } - CPUIs68060 = false; -#endif // Load XPRAM XPRAMInit(vmdir); @@ -180,18 +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; -#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()) { 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(); @@ -202,6 +197,8 @@ bool InitAll(const char *vmdir) return true; } +void CDROMOpenDone() { +} /* * Deinitialize everything @@ -248,6 +245,8 @@ void ExitAll(void) CDROMExit(); DiskExit(); SonyExit(); + + MacMemExit(); } 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/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/prefs.cpp b/BasiliskII/src/prefs.cpp index 434992ce3..d6eb615d5 100644 --- a/BasiliskII/src/prefs.cpp +++ b/BasiliskII/src/prefs.cpp @@ -328,6 +328,11 @@ const char *PrefsFindString(const char *name, int index) return NULL; } +extern "C" const char *PrefsFindStringC(const char *name, int index) +{ + return PrefsFindString(name, index); +} + bool PrefsFindBool(const char *name) { prefs_node *p = find_node(name, TYPE_BOOLEAN, 0); diff --git a/BasiliskII/src/prefs_items.cpp b/BasiliskII/src/prefs_items.cpp index 834dfc7d6..33f3254a3 100644 --- a/BasiliskII/src/prefs_items.cpp +++ b/BasiliskII/src/prefs_items.cpp @@ -68,6 +68,23 @@ prefs_desc common_prefs_items[] = { {"jitinline", TYPE_BOOLEAN, false, "enable translation through constant jumps"}, {"jitblacklist", TYPE_STRING, false, "blacklist opcodes from translation"}, {"keyboardtype", TYPE_INT32, false, "hardware keyboard type"}, + {"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"}, + {"keycodefile", TYPE_STRING, false, "path of keycode translation file"}, + {"mousewheelmode", TYPE_INT32, false, "mouse wheel support (0=page up/down, 1=cursor up/down)"}, + {"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"}, + {"hotkey",TYPE_INT32,false,"hotkey modifier"}, + {"scale_nearest",TYPE_BOOLEAN,false,"nearest neighbor scaling"}, + {"scale_integer",TYPE_BOOLEAN,false,"integer scaling"}, + {"yearofs", TYPE_INT32, 0, "year offset"}, + {"dayofs", TYPE_INT32, 0, "day offset"}, + {"mag_rate", TYPE_INT32, 0, "rate of magnification"}, + {"gammaramp", TYPE_STRING, false, "gamma ramp (on, off or fullscreen)"}, + {"swap_opt_cmd", TYPE_BOOLEAN, false, "swap option and command key"}, + {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, + {"host_domain", TYPE_STRING, true, "handle DNS requests for this domain on the host (slirp only)"}, + {"title", TYPE_STRING, false, "window title"}, + {"sound_buffer", TYPE_INT32, false, "sound buffer length"}, + {"name_encoding", TYPE_INT32, false, "file name encoding"}, {NULL, TYPE_END, false, NULL} // End of list }; @@ -96,7 +113,7 @@ void AddPrefsDefaults(void) #if USE_JIT // JIT compiler specific options - PrefsAddBool("jit", true); +// PrefsAddBool("jit", true); PrefsAddBool("jitfpu", true); PrefsAddBool("jitdebug", false); PrefsAddInt32("jitcachesize", 8192); @@ -107,4 +124,11 @@ void AddPrefsDefaults(void) #endif PrefsAddInt32("keyboardtype", 5); + +#ifdef __APPLE__ + PrefsAddBool("swap_opt_cmd", false); +#else + PrefsAddBool("swap_opt_cmd", true); +#endif + PrefsAddBool("ignoresegv", true); } diff --git a/BasiliskII/src/rom_patches.cpp b/BasiliskII/src/rom_patches.cpp index 874131c24..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 REAL_ADDRESSING || DIRECT_ADDRESSING - // Real and direct addressing modes require a 32-bit clean ROM +#if DIRECT_ADDRESSING + // 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 */ @@ -1008,178 +1004,6 @@ static bool patch_rom_classic(void) *wp++ = htons(M68K_EMUL_OP_IRQ); *wp++ = htons(0x4a80); // tst.l d0 *wp = htons(0x67f4); // beq 0x402be2 - - - // Patch the guest screen for an arbitary resolution - // We are going to steal the abandoned ROM space that runs RAM test - // for patching ROM. - - // a stateful variable to keep track of the stolen location - // of the patched code in guest memory. - uint32 patchCodeBaseMac; - // a stateful word pointer pointing to the patch code in host memory. - uint16* patchwp; - // a stateful long pointer pointing to the patch code in host memory. - uint32* patchlp; - // a statless long pointer - uint32* lp; - - // start to patch P_mInitVideoGlobal route - wp = (uint16 *)(ROMBaseHost + 0x5ca); - *wp++ = htons(0x4eb9); /* JSR */ - lp = (uint32 *)wp; - - // we steal P_mRamTest routine space - const uint32 patchCodeOffset = 0x1d3e; - patchCodeBaseMac = ROMBaseMac + patchCodeOffset; - uint8* patchCodeBaseHost = ROMBaseHost + patchCodeOffset; - // we JSR to this Mac address - *lp++ = htonl(patchCodeBaseMac); - wp = (uint16 *)lp; - - // the host address for the patch - patchwp = (uint16 *)(patchCodeBaseHost); - // MOVE.L $MacFrameBaseMac24Bit, ($ScrnBase) - *patchwp++ = htons(0x21fc); /* MOVE.L */ - patchCodeBaseMac += 2; - - patchlp = (uint32 *)patchwp; - *patchlp++ = htonl(MacFrameBaseMac24Bit); - patchCodeBaseMac += 4; - - patchwp = (uint16 *)patchlp; - *patchwp++ = htons(0x0824); /* (ScrnBase) */ - patchCodeBaseMac += 2; - - *patchwp++ = htons(0x4e75); /* RTS */ - patchCodeBaseMac += 2; - // keep in sync - patchlp = (uint32 *)patchwp; - - // continue to patch P_mInitVideoGlobal routine - wp = (uint16 *)(ROMBaseHost + 0x5d2); - *wp = htons(MacScreenWidth / 8); - wp = (uint16 *)(ROMBaseHost + 0x60a); - *wp = htons(MacScreenHeight); - wp = (uint16 *)(ROMBaseHost + 0x60e); - *wp = htons(MacScreenWidth); - - wp = (uint16 *)(ROMBaseHost + 0x8cc); - *wp = htons(MacScreenHeight); - wp = (uint16 *)(ROMBaseHost + 0x8ce); - *wp = htons(MacScreenWidth); - - // blink floppy, disk icon - lp = (uint32 *)(ROMBaseHost + 0xf4c); - *lp = htonl(MacFrameBaseMac24Bit + (((MacScreenHeight / 4) * 2 - 25) * MacScreenWidth + (MacScreenWidth / 2 - 16)) / 8); - // blink floppy, question mark - lp = (uint32 *)(ROMBaseHost + 0xf5e); - *lp = htonl(MacFrameBaseMac24Bit + (((MacScreenHeight / 4) * 2 - 10) * MacScreenWidth + (MacScreenWidth / 2 - 8)) / 8); - - lp = (uint32 *)(ROMBaseHost + 0x10a2); - *lp = htonl(MacFrameBaseMac24Bit); - wp = (uint16 *)(ROMBaseHost + 0x10a8); - *wp = htons(MacScreenHeight); - wp = (uint16 *)(ROMBaseHost + 0x10ac); - *wp = htons(MacScreenWidth); - wp = (uint16 *)(ROMBaseHost + 0x10b0); - *wp = htons(MacScreenWidth / 8); - lp = (uint32 *)(ROMBaseHost + 0x10b4); - // # of bytes in screen - *lp = htonl(MacScreenWidth * MacScreenHeight / 8); - - // sad mac, mac icon - lp = (uint32 *)(ROMBaseHost + 0x118a); - *lp = htonl(MacFrameBaseMac24Bit + (((MacScreenHeight / 4) * 2 - 25) * MacScreenWidth + (MacScreenWidth / 2 - 16)) / 8); - // sad mac, frown - lp = (uint32 *)(ROMBaseHost + 0x1198); - *lp = htonl(MacFrameBaseMac24Bit + (((MacScreenHeight / 4) * 2 - 19) * MacScreenWidth + (MacScreenWidth / 2 - 8)) / 8); - wp = (uint16 *)(ROMBaseHost + 0x11b0); - *wp = htons(MacScreenWidth / 8); - - // blink floppy and sadmac, position - wp = (uint16 *)(ROMBaseHost + 0x11d8); - *wp = htons(MacScreenWidth / 8); - wp = (uint16 *)(ROMBaseHost + 0x11ea); - *wp = htons(MacScreenWidth / 8); - - // cursor handling - if (MacScreenWidth >= 1024) { - // start to patch P_HideCursor routine - wp = (uint16 *)(ROMBaseHost + 0x18dfe); - *wp++ = htons(0x4eb9); /* JSR */ - lp = (uint32 *)wp; - *lp++ = htonl(patchCodeBaseMac); - wp = (uint16 *)lp; - - *patchwp++ = htons(0x41f8); /* Lea.L (CrsrSave),A0 */ - patchCodeBaseMac += 2; - *patchwp++ = htons(0x088c); - patchCodeBaseMac += 2; - - *patchwp++ = htons(0x203c); /* MOVE.L #$x,D0 */ - patchCodeBaseMac += 2; - patchlp = (uint32 *)patchwp; - *patchlp++ = htonl(MacScreenWidth / 8); - patchCodeBaseMac += 4; - patchwp = (uint16 *)patchlp; - - *patchwp++ = htons(0x4e75); /* RTS */ - patchCodeBaseMac += 2; - patchlp = (uint32 *)patchwp; // keep in sync - } else { - // P_HideCursor - wp = (uint16 *)(ROMBaseHost + 0x18e02); - *wp = htons(0x7000 + (MacScreenWidth / 8)); - } // end if (MacScreenWidth >= 1024) - - wp = (uint16 *)(ROMBaseHost + 0x18e7a); - *wp = htons(MacScreenWidth - 32); - wp = (uint16 *)(ROMBaseHost + 0x18e80); - *wp = htons(MacScreenWidth - 32); - wp = (uint16 *)(ROMBaseHost + 0x18ea0); - *wp = htons(MacScreenHeight - 16); - wp = (uint16 *)(ROMBaseHost + 0x18ea6); - *wp = htons(MacScreenHeight); - - if (MacScreenWidth >= 1024) { - // start to patch P_ShowCursor routine - wp = (uint16 *)(ROMBaseHost + 0x18ec4); - *wp++ = htons(0x4eb9); /* JSR */ - lp = (uint32 *)wp; - *lp++ = htonl(patchCodeBaseMac); - wp = (uint16 *)lp; - - *patchwp++ = htons(0x2a3c); /* MOVE.L #$x, D5 */ - patchCodeBaseMac += 2; - patchlp = (uint32 *)patchwp; - *patchlp++ = htonl(MacScreenWidth / 8); - patchCodeBaseMac += 4; - patchwp = (uint16 *)patchlp; - - *patchwp++ = htons(0xc2c5); /* MulU D5, D1 */ - patchCodeBaseMac += 2; - - *patchwp++ = htons(0xd3c1); /* AddA.L D1, A1 */ - patchCodeBaseMac += 2; - - *patchwp++ = htons(0x4e75); /* RTS */ - patchCodeBaseMac += 2; - // keep in sync - patchlp = (uint32 *)patchwp; - } else { - wp = (uint16 *)(ROMBaseHost + 0x18ec4); - *wp = htons(0x7A00 + (MacScreenWidth / 8)); - }// end if (MacScreenWidth >= 1024) - - // set up screen bitmap - wp = (uint16 *)(ROMBaseHost + 0x18f9a); - *wp = htons(MacScreenHeight); - wp = (uint16 *)(ROMBaseHost + 0x18fa0); - *wp = htons(MacScreenWidth); - wp = (uint16 *)(ROMBaseHost + 0x18fb4); - *wp = htons(MacScreenHeight); - return true; } @@ -1212,7 +1036,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); @@ -1220,7 +1044,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); @@ -1429,15 +1253,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) @@ -1452,20 +1267,6 @@ 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) - // 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/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/slirp/VERSION b/BasiliskII/src/slirp/VERSION_ similarity index 55% rename from BasiliskII/src/slirp/VERSION rename to BasiliskII/src/slirp/VERSION_ index 353ad940d..12adff9bb 100644 --- a/BasiliskII/src/slirp/VERSION +++ b/BasiliskII/src/slirp/VERSION_ @@ -1 +1,2 @@ qemu 0.9.0 (2007/02/05) +Plus 64 Bits Patchs \ No newline at end of file diff --git a/BasiliskII/src/slirp/bootp.c b/BasiliskII/src/slirp/bootp.c old mode 100644 new mode 100755 diff --git a/BasiliskII/src/slirp/bootp.h b/BasiliskII/src/slirp/bootp.h old mode 100644 new mode 100755 index 54a86ca22..5c2e62ab0 --- a/BasiliskII/src/slirp/bootp.h +++ b/BasiliskII/src/slirp/bootp.h @@ -115,7 +115,7 @@ struct bootp_t { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif void bootp_input(struct mbuf *m); diff --git a/BasiliskII/src/slirp/cksum.c b/BasiliskII/src/slirp/cksum.c old mode 100644 new mode 100755 diff --git a/BasiliskII/src/slirp/ctl.h b/BasiliskII/src/slirp/ctl.h old mode 100644 new mode 100755 diff --git a/BasiliskII/src/slirp/debug.c b/BasiliskII/src/slirp/debug.c old mode 100644 new mode 100755 index 916b9a8e0..d3d8c5796 --- a/BasiliskII/src/slirp/debug.c +++ b/BasiliskII/src/slirp/debug.c @@ -16,6 +16,8 @@ int dostats = 0; #endif int slirp_debug = 0; +extern char *strerror _P((int)); + /* Carry over one item from main.c so that the tty's restored. * Only done when the tty being used is /dev/tty --RedWolf */ extern struct termios slirp_tty_settings; @@ -292,7 +294,6 @@ mbufstats() void sockstats() { - char addr[INET_ADDRSTRLEN]; char buff[256]; int n; struct socket *so; @@ -310,11 +311,9 @@ sockstats() buff[17] = 0; lprint("%s %3d %15s %5d ", buff, so->s, - inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)), - ntohs(so->so_lport)); + inet_ntoa(so->so_laddr), ntohs(so->so_lport)); lprint("%15s %5d %5d %5d\r\n", - inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)), - ntohs(so->so_fport), + inet_ntoa(so->so_faddr), ntohs(so->so_fport), so->so_rcv.sb_cc, so->so_snd.sb_cc); } @@ -326,11 +325,9 @@ sockstats() buff[17] = 0; lprint("%s %3d %15s %5d ", buff, so->s, - inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)), - ntohs(so->so_lport)); + inet_ntoa(so->so_laddr), ntohs(so->so_lport)); lprint("%15s %5d %5d %5d\r\n", - inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)), - ntohs(so->so_fport), + inet_ntoa(so->so_faddr), ntohs(so->so_fport), so->so_rcv.sb_cc, so->so_snd.sb_cc); } } diff --git a/BasiliskII/src/slirp/debug.h b/BasiliskII/src/slirp/debug.h old mode 100644 new mode 100755 index c5d42195e..6e8444dab --- a/BasiliskII/src/slirp/debug.h +++ b/BasiliskII/src/slirp/debug.h @@ -36,15 +36,15 @@ extern int slirp_debug; #endif -void debug_init(char *, int); -//void ttystats(struct ttys *); -void allttystats(void); -void ipstats(void); -void vjstats(void); -void tcpstats(void); -void udpstats(void); -void icmpstats(void); -void mbufstats(void); -void sockstats(void); -void slirp_exit(int); +void debug_init _P((char *, int)); +//void ttystats _P((struct ttys *)); +void allttystats _P((void)); +void ipstats _P((void)); +void vjstats _P((void)); +void tcpstats _P((void)); +void udpstats _P((void)); +void icmpstats _P((void)); +void mbufstats _P((void)); +void sockstats _P((void)); +void slirp_exit _P((int)); diff --git a/BasiliskII/src/slirp/icmp_var.h b/BasiliskII/src/slirp/icmp_var.h old mode 100644 new mode 100755 diff --git a/BasiliskII/src/slirp/if.c b/BasiliskII/src/slirp/if.c old mode 100644 new mode 100755 index 9185dcf65..eab8a46ea --- a/BasiliskII/src/slirp/if.c +++ b/BasiliskII/src/slirp/if.c @@ -7,11 +7,11 @@ #include -size_t if_mtu, if_mru; +int if_mtu, if_mru; int if_comp; int if_maxlinkhdr; -int if_queued = 0; /* Number of packets queued so far */ -int if_thresh = 10; /* Number of packets queued before we start sending +int if_queued = 0; /* Number of packets queued so far */ +int if_thresh = 10; /* Number of packets queued before we start sending * (to prevent allocing too many mbufs) */ struct mbuf if_fastq; /* fast queue (for interactive data) */ @@ -116,8 +116,7 @@ if_input(ttyp) DEBUG_MISC((dfd, " read %d bytes\n", if_n)); if (if_n <= 0) { - int error = WSAGetLastError(); - if (if_n == 0 || (error != WSAEINTR && error != EAGAIN)) { + if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { if (ttyp->up) link_up--; tty_detached(ttyp, 0); diff --git a/BasiliskII/src/slirp/if.h b/BasiliskII/src/slirp/if.h old mode 100644 new mode 100755 index a2564ab1d..5d96a9034 --- a/BasiliskII/src/slirp/if.h +++ b/BasiliskII/src/slirp/if.h @@ -15,8 +15,8 @@ /* Needed for FreeBSD */ #undef if_mtu -extern size_t if_mtu; -extern size_t if_mru; /* MTU and MRU */ +extern int if_mtu; +extern int if_mru; /* MTU and MRU */ extern int if_comp; /* Flags for compression */ extern int if_maxlinkhdr; extern int if_queued; /* Number of packets queued so far */ diff --git a/BasiliskII/src/slirp/ip.h b/BasiliskII/src/slirp/ip.h old mode 100644 new mode 100755 index e0c7de967..94dcc6063 --- a/BasiliskII/src/slirp/ip.h +++ b/BasiliskII/src/slirp/ip.h @@ -98,7 +98,7 @@ struct ip { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif #define IP_MAXPACKET 65535 /* maximum packet size */ @@ -168,7 +168,7 @@ struct ip_timestamp { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif /* flag bits for ipt_flg */ @@ -195,23 +195,19 @@ struct ip_timestamp { #define IP_MSS 576 /* default maximum segment size */ -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ -#include -#else #if SIZEOF_CHAR_P == 4 -typedef caddr_t caddr32_t; + struct mbuf_ptr { + struct mbuf *mptr; + uint32_t dummy; + }; #else -typedef u_int32_t caddr32_t; -#endif -#endif - -#if SIZEOF_CHAR_P == 4 -typedef struct ipq *ipqp_32; -typedef struct ipasfrag *ipasfragp_32; -#else -typedef caddr32_t ipqp_32; -typedef caddr32_t ipasfragp_32; + struct mbuf_ptr { + struct mbuf *mptr; + }; #endif +struct qlink { + void *next, *prev; +}; /* * Overlay for ip header used by other protocols (tcp, udp). @@ -221,16 +217,16 @@ typedef caddr32_t ipasfragp_32; #endif struct ipovly { - caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ + struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ u_int8_t ih_x1; /* (unused) */ u_int8_t ih_pr; /* protocol */ u_int16_t ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ -} PACKED__; +} __attribute__((packed)); #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif /* @@ -241,12 +237,13 @@ struct ipovly { * size 28 bytes */ struct ipq { - ipqp_32 next,prev; /* to other reass headers */ + struct qlink frag_link; /* to ip headers of fragments */ + struct qlink ip_link; /* to other reass headers */ + u_int8_t ipq_ttl; /* time for reass q to live */ u_int8_t ipq_p; /* protocol of this fragment */ u_int16_t ipq_id; /* sequence id for reassembly */ - ipasfragp_32 ipq_next,ipq_prev; - /* to ip headers of fragments */ + struct in_addr ipq_src,ipq_dst; }; @@ -256,29 +253,16 @@ struct ipq { * Note: ipf_next must be at same offset as ipq_next above */ struct ipasfrag { -#ifdef WORDS_BIGENDIAN - u_char ip_v:4, - ip_hl:4; -#else - u_char ip_hl:4, - ip_v:4; -#endif - /* BUG : u_int changed to u_int8_t. - * sizeof(u_int)==4 on linux 2.0 - */ - u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit - * to avoid destroying tos (PPPDTRuu); - * copied from (ip_off&IP_MF) */ - u_int16_t ip_len; - u_int16_t ip_id; - u_int16_t ip_off; - u_int8_t ip_ttl; - u_int8_t ip_p; - u_int16_t ip_sum; - ipasfragp_32 ipf_next; /* next fragment */ - ipasfragp_32 ipf_prev; /* previous fragment */ + struct qlink ipf_link; + struct ip ipf_ip; }; +#define ipf_off ipf_ip.ip_off +#define ipf_tos ipf_ip.ip_tos +#define ipf_len ipf_ip.ip_len +#define ipf_next ipf_link.next +#define ipf_prev ipf_link.prev + /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. diff --git a/BasiliskII/src/slirp/ip_icmp.c b/BasiliskII/src/slirp/ip_icmp.c old mode 100644 new mode 100755 index 55376a8b1..7cbda7906 --- a/BasiliskII/src/slirp/ip_icmp.c +++ b/BasiliskII/src/slirp/ip_icmp.c @@ -77,7 +77,7 @@ icmp_input(m, hlen) DEBUG_CALL("icmp_input"); DEBUG_ARG("m = %lx", (long )m); - DEBUG_ARG("m_len = %zu", m->m_len); + DEBUG_ARG("m_len = %d", m->m_len); icmpstat.icps_received++; @@ -201,12 +201,12 @@ icmp_input(m, hlen) #define ICMP_MAXDATALEN (IP_MSS-28) void -icmp_error( - struct mbuf *msrc, - u_char type, - u_char code, - int minsize, - char *message) +icmp_error(msrc, type, code, minsize, message) + struct mbuf *msrc; + u_char type; + u_char code; + int minsize; + char *message; { unsigned hlen, shlen, s_ip_len; register struct ip *ip; @@ -215,7 +215,7 @@ icmp_error( DEBUG_CALL("icmp_error"); DEBUG_ARG("msrc = %lx", (long )msrc); - DEBUG_ARG("msrc_len = %zu", msrc->m_len); + DEBUG_ARG("msrc_len = %d", msrc->m_len); if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error; @@ -223,9 +223,9 @@ icmp_error( if(!msrc) goto end_error; ip = mtod(msrc, struct ip *); #if DEBUG - { char bufa[INET_ADDRSTRLEN], bufb[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &ip->ip_src, bufa, sizeof(bufa)); - inet_ntop(AF_INET, &ip->ip_dst, bufb, sizeof(bufb)); + { char bufa[20], bufb[20]; + strcpy(bufa, inet_ntoa(ip->ip_src)); + strcpy(bufb, inet_ntoa(ip->ip_dst)); DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb)); } #endif @@ -244,7 +244,7 @@ icmp_error( /* make a copy */ if(!(m=m_get())) goto end_error; /* get mbuf */ - { u_int new_m_size; + { int new_m_size; new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN; if(new_m_size>m->m_size) m_inc(m, new_m_size); } @@ -299,7 +299,7 @@ icmp_error( /* fill in ip */ ip->ip_hl = hlen >> 2; - ip->ip_len = (u_int16_t)m->m_len; + ip->ip_len = m->m_len; ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ diff --git a/BasiliskII/src/slirp/ip_icmp.h b/BasiliskII/src/slirp/ip_icmp.h old mode 100644 new mode 100755 index 683dc87f1..6968daa71 --- a/BasiliskII/src/slirp/ip_icmp.h +++ b/BasiliskII/src/slirp/ip_icmp.h @@ -95,7 +95,7 @@ struct icmp { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif /* @@ -161,8 +161,8 @@ struct icmp { (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) -void icmp_input(struct mbuf *, int); -void icmp_error(struct mbuf *, u_char, u_char, int, char *); -void icmp_reflect(struct mbuf *); +void icmp_input _P((struct mbuf *, int)); +void icmp_error _P((struct mbuf *, u_char, u_char, int, char *)); +void icmp_reflect _P((struct mbuf *)); #endif diff --git a/BasiliskII/src/slirp/ip_input.c b/BasiliskII/src/slirp/ip_input.c old mode 100644 new mode 100755 index cac8493ba..7c995c98d --- a/BasiliskII/src/slirp/ip_input.c +++ b/BasiliskII/src/slirp/ip_input.c @@ -38,6 +38,16 @@ * terms and conditions of the copyright. */ +#include +#include +#include +#include + +#define container_of(ptr, type, member) ({ \ + const typeof(((type *) 0)->member) *__mptr = (ptr); \ + (type *) ((char *) __mptr - offsetof(type, member));}) + + #include #include "ip_icmp.h" @@ -52,7 +62,7 @@ struct ipq ipq; void ip_init() { - ipq.next = ipq.prev = (ipqp_32)&ipq; + ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link; ip_id = tt.tv_sec & 0xffff; udp_init(); tcp_init(); @@ -68,11 +78,11 @@ ip_input(m) struct mbuf *m; { register struct ip *ip; - u_int hlen; + int hlen; DEBUG_CALL("ip_input"); DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m_len = %zu", m->m_len); + DEBUG_ARG("m_len = %d", m->m_len); ipstat.ips_total++; @@ -155,18 +165,20 @@ ip_input(m) */ if (ip->ip_off &~ IP_DF) { register struct ipq *fp; + struct qlink *l; /* * Look for queue of fragments * of this datagram. */ - for (fp = (struct ipq *) ipq.next; fp != &ipq; - fp = (struct ipq *) fp->next) - if (ip->ip_id == fp->ipq_id && - ip->ip_src.s_addr == fp->ipq_src.s_addr && - ip->ip_dst.s_addr == fp->ipq_dst.s_addr && - ip->ip_p == fp->ipq_p) + for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) { + fp = container_of(l, struct ipq, ip_link); + if (ip->ip_id == fp->ipq_id && + ip->ip_src.s_addr == fp->ipq_src.s_addr && + ip->ip_dst.s_addr == fp->ipq_dst.s_addr && + ip->ip_p == fp->ipq_p) goto found; - fp = 0; + } + fp = NULL; found: /* @@ -176,9 +188,9 @@ ip_input(m) */ ip->ip_len -= hlen; if (ip->ip_off & IP_MF) - ((struct ipasfrag *)ip)->ipf_mff |= 1; + ip->ip_tos |= 1; else - ((struct ipasfrag *)ip)->ipf_mff &= ~1; + ip->ip_tos &= ~1; ip->ip_off <<= 3; @@ -187,9 +199,9 @@ ip_input(m) * or if this is not the first fragment, * attempt reassembly; if it succeeds, proceed. */ - if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { + if (ip->ip_tos & 1 || ip->ip_off) { ipstat.ips_fragments++; - ip = ip_reass((struct ipasfrag *)ip, fp); + ip = ip_reass(ip, fp); if (ip == 0) return; ipstat.ips_reassembled++; @@ -225,21 +237,21 @@ ip_input(m) return; } +#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink))) +#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink))) /* * Take incoming datagram fragment and try to * reassemble it into whole datagram. If a chain for * reassembly of this datagram already exists, then it * is given as fp; otherwise have to make a chain. */ -struct ip * -ip_reass(ip, fp) - register struct ipasfrag *ip; - register struct ipq *fp; +static struct ip * +ip_reass(register struct ip *ip, register struct ipq *fp) { register struct mbuf *m = dtom(ip); register struct ipasfrag *q; int hlen = ip->ip_hl << 2; - int i, next; + u_int16_t i, next; DEBUG_CALL("ip_reass"); DEBUG_ARG("ip = %lx", (long)ip); @@ -261,13 +273,13 @@ ip_reass(ip, fp) struct mbuf *t; if ((t = m_get()) == NULL) goto dropfrag; fp = mtod(t, struct ipq *); - insque_32(fp, &ipq); + insque(&fp->ip_link, &ipq.ip_link); fp->ipq_ttl = IPFRAGTTL; fp->ipq_p = ip->ip_p; fp->ipq_id = ip->ip_id; - fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp; - fp->ipq_src = ((struct ip *)ip)->ip_src; - fp->ipq_dst = ((struct ip *)ip)->ip_dst; + fp->frag_link.next = fp->frag_link.prev = &fp->frag_link; + fp->ipq_src = ip->ip_src; + fp->ipq_dst = ip->ip_dst; q = (struct ipasfrag *)fp; goto insert; } @@ -275,9 +287,9 @@ ip_reass(ip, fp) /* * Find a segment which begins after this one does. */ - for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *)q->ipf_next) - if (q->ip_off > ip->ip_off) + for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; + q = q->ipf_next) + if (q->ipf_off > ip->ip_off) break; /* @@ -285,9 +297,9 @@ ip_reass(ip, fp) * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if (q->ipf_prev != (ipasfragp_32)fp) { - i = ((struct ipasfrag *)(q->ipf_prev))->ip_off + - ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; + if (q->ipf_prev != &fp->frag_link) { + struct ipasfrag *pq = q->ipf_prev; + i = pq->ipf_off + pq->ipf_len - ip->ip_off; if (i > 0) { if (i >= ip->ip_len) goto dropfrag; @@ -301,17 +313,18 @@ ip_reass(ip, fp) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { - i = (ip->ip_off + ip->ip_len) - q->ip_off; - if (i < q->ip_len) { - q->ip_len -= i; - q->ip_off += i; + while (q != (struct ipasfrag*)&fp->frag_link && + ip->ip_off + ip->ip_len > q->ipf_off) { + i = (ip->ip_off + ip->ip_len) - q->ipf_off; + if (i < q->ipf_len) { + q->ipf_len -= i; + q->ipf_off += i; m_adj(dtom(q), i); break; } - q = (struct ipasfrag *) q->ipf_next; - m_freem(dtom((struct ipasfrag *) q->ipf_prev)); - ip_deq((struct ipasfrag *) q->ipf_prev); + q = q->ipf_next; + m_freem(dtom(q->ipf_prev)); + ip_deq(q->ipf_prev); } insert: @@ -319,27 +332,26 @@ ip_reass(ip, fp) * Stick new segment in its place; * check for complete reassembly. */ - ip_enq(ip, (struct ipasfrag *) q->ipf_prev); + ip_enq(iptofrag(ip), q->ipf_prev); next = 0; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *) q->ipf_next) { - if (q->ip_off != next) + for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; + q = q->ipf_next) { + if (q->ipf_off != next) return (0); - next += q->ip_len; + next += q->ipf_len; } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) + if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1) return (0); /* * Reassembly is complete; concatenate fragments. */ - q = (struct ipasfrag *) fp->ipq_next; + q = fp->frag_link.next; m = dtom(q); q = (struct ipasfrag *) q->ipf_next; - while (q != (struct ipasfrag *)fp) { - struct mbuf *t; - t = dtom(q); + while (q != (struct ipasfrag*)&fp->frag_link) { + struct mbuf *t = dtom(q); q = (struct ipasfrag *) q->ipf_next; m_cat(m, t); } @@ -350,7 +362,7 @@ ip_reass(ip, fp) * dequeue and discard fragment reassembly header. * Make header visible. */ - ip = (struct ipasfrag *) fp->ipq_next; + q = fp->frag_link.next; /* * If the fragments concatenated to an mbuf that's @@ -361,24 +373,24 @@ ip_reass(ip, fp) */ if (m->m_flags & M_EXT) { int delta; - delta = (char *)ip - m->m_dat; - ip = (struct ipasfrag *)(m->m_ext + delta); + delta = (char *)q - m->m_dat; + q = (struct ipasfrag *)(m->m_ext + delta); } /* DEBUG_ARG("ip = %lx", (long)ip); * ip=(struct ipasfrag *)m->m_data; */ + ip = fragtoip(q); ip->ip_len = next; - ip->ipf_mff &= ~1; - ((struct ip *)ip)->ip_src = fp->ipq_src; - ((struct ip *)ip)->ip_dst = fp->ipq_dst; - remque_32(fp); + ip->ip_tos &= ~1; + ip->ip_src = fp->ipq_src; + ip->ip_dst = fp->ipq_dst; + remque(&fp->ip_link); (void) m_free(dtom(fp)); - m = dtom(ip); m->m_len += (ip->ip_hl << 2); m->m_data -= (ip->ip_hl << 2); - return ((struct ip *)ip); + return ip; dropfrag: ipstat.ips_fragdropped++; @@ -396,13 +408,12 @@ ip_freef(fp) { register struct ipasfrag *q, *p; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = p) { - p = (struct ipasfrag *) q->ipf_next; + for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) { + p = q->ipf_next; ip_deq(q); m_freem(dtom(q)); } - remque_32(fp); + remque(&fp->ip_link); (void) m_free(dtom(fp)); } @@ -416,10 +427,10 @@ ip_enq(p, prev) { DEBUG_CALL("ip_enq"); DEBUG_ARG("prev = %lx", (long)prev); - p->ipf_prev = (ipasfragp_32) prev; + p->ipf_prev = prev; p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p; - prev->ipf_next = (ipasfragp_32) p; + ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p; + prev->ipf_next = p; } /* @@ -441,20 +452,21 @@ ip_deq(p) void ip_slowtimo() { - register struct ipq *fp; + struct qlink *l; DEBUG_CALL("ip_slowtimo"); - fp = (struct ipq *) ipq.next; - if (fp == 0) + l = ipq.ip_link.next; + + if (l == 0) return; - while (fp != &ipq) { - --fp->ipq_ttl; - fp = (struct ipq *) fp->next; - if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { + while (l != &ipq.ip_link) { + struct ipq *fp = container_of(l, struct ipq, ip_link); + l = l->next; + if (--fp->ipq_ttl == 0) { ipstat.ips_fragtimeout++; - ip_freef((struct ipq *) fp->prev); + ip_freef(fp); } } } diff --git a/BasiliskII/src/slirp/ip_output.c b/BasiliskII/src/slirp/ip_output.c old mode 100644 new mode 100755 index fb9a94204..0d1ae1b2c --- a/BasiliskII/src/slirp/ip_output.c +++ b/BasiliskII/src/slirp/ip_output.c @@ -55,9 +55,8 @@ ip_output(so, m0) { register struct ip *ip; register struct mbuf *m = m0; - register u_int hlen = sizeof(struct ip); - u_int len, off; - int error = 0; + register int hlen = sizeof(struct ip ); + int len, off, error = 0; DEBUG_CALL("ip_output"); DEBUG_ARG("so = %lx", (long)so); @@ -129,7 +128,7 @@ ip_output(so, m0) */ m0 = m; mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { + for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) { register struct ip *mhip; m = m_get(); if (m == 0) { @@ -174,7 +173,7 @@ ip_output(so, m0) * and updating header, then send each fragment (in order). */ m = m0; - m_adj(m, hlen + firstlen - ip->ip_len); + m_adj(m, hlen + firstlen - (u_int16_t)ip->ip_len); ip->ip_len = htons((u_int16_t)m->m_len); ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF)); ip->ip_sum = 0; diff --git a/BasiliskII/src/slirp/libslirp.h b/BasiliskII/src/slirp/libslirp.h old mode 100644 new mode 100755 index 8a1aa31e6..c955a28c6 --- a/BasiliskII/src/slirp/libslirp.h +++ b/BasiliskII/src/slirp/libslirp.h @@ -2,7 +2,16 @@ #define _LIBSLIRP_H #ifdef _WIN32 +#ifdef __MINGW32__ +#if _WIN32_WINNT < 0x501 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif +#endif #include +#ifdef __MINGW32__ +#include +#endif int inet_aton(const char *cp, struct in_addr *ia); #else #include diff --git a/BasiliskII/src/slirp/main.h b/BasiliskII/src/slirp/main.h old mode 100644 new mode 100755 diff --git a/BasiliskII/src/slirp/mbuf.c b/BasiliskII/src/slirp/mbuf.c old mode 100644 new mode 100755 index 5a16fab8b..2b53bc3e9 --- a/BasiliskII/src/slirp/mbuf.c +++ b/BasiliskII/src/slirp/mbuf.c @@ -24,16 +24,18 @@ int mbuf_alloced = 0; struct mbuf m_freelist, m_usedlist; int mbuf_thresh = 30; int mbuf_max = 0; -size_t msize; +int msize; -void m_init() +void +m_init() { m_freelist.m_next = m_freelist.m_prev = &m_freelist; m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; msize_init(); } -void msize_init() +void +msize_init() { /* * Find a nice value for msize @@ -51,7 +53,8 @@ void msize_init() * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, * which tells m_free to actually free() it */ -struct mbuf *m_get() +struct mbuf * +m_get() { register struct mbuf *m; int flags = 0; @@ -86,7 +89,9 @@ struct mbuf *m_get() return m; } -void m_free(struct mbuf *m) +void +m_free(m) + struct mbuf *m; { DEBUG_CALL("m_free"); @@ -119,7 +124,9 @@ void m_free(struct mbuf *m) * the other.. if result is too big for one mbuf, malloc() * an M_EXT data segment */ -void m_cat(register struct mbuf *m, register struct mbuf *n) +void +m_cat(m, n) + register struct mbuf *m, *n; { /* * If there's no room, realloc @@ -135,7 +142,10 @@ void m_cat(register struct mbuf *m, register struct mbuf *n) /* make m size bytes large */ -void m_inc(struct mbuf *m, u_int size) +void +m_inc(m, size) + struct mbuf *m; + int size; { int datasize; @@ -169,7 +179,10 @@ void m_inc(struct mbuf *m, u_int size) -void m_adj(struct mbuf *m, int len) +void +m_adj(m, len) + struct mbuf *m; + int len; { if (m == NULL) return; @@ -189,7 +202,9 @@ void m_adj(struct mbuf *m, int len) * Copy len bytes from m, starting off bytes into n */ int -m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len) +m_copy(n, m, off, len) + struct mbuf *n, *m; + int off, len; { if (len > M_FREEROOM(n)) return -1; @@ -205,7 +220,9 @@ m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len) * XXX This is a kludge, I should eliminate the need for it * Fortunately, it's not used often */ -struct mbuf *dtom(void *dat) +struct mbuf * +dtom(dat) + void *dat; { struct mbuf *m; diff --git a/BasiliskII/src/slirp/mbuf.h b/BasiliskII/src/slirp/mbuf.h old mode 100644 new mode 100755 index 11b252bb6..183254a08 --- a/BasiliskII/src/slirp/mbuf.h +++ b/BasiliskII/src/slirp/mbuf.h @@ -63,11 +63,11 @@ struct m_hdr { struct mbuf *mh_prevpkt; /* Flags aren't used in the output queue */ int mh_flags; /* Misc flags */ - size_t mh_size; /* Size of data */ + int mh_size; /* Size of data */ struct socket *mh_so; caddr_t mh_data; /* Location of data */ - size_t mh_len; /* Amount of data in this mbuf */ + int mh_len; /* Amount of data in this mbuf */ }; /* @@ -130,14 +130,14 @@ extern int mbuf_alloced; extern struct mbuf m_freelist, m_usedlist; extern int mbuf_max; -void m_init(void); -void msize_init(void); -struct mbuf * m_get(void); -void m_free(struct mbuf *); -void m_cat(register struct mbuf *, register struct mbuf *); -void m_inc(struct mbuf *, u_int); -void m_adj(struct mbuf *, int); -int m_copy(struct mbuf *, struct mbuf *, u_int, u_int); -struct mbuf * dtom(void *); +void m_init _P((void)); +void msize_init _P((void)); +struct mbuf * m_get _P((void)); +void m_free _P((struct mbuf *)); +void m_cat _P((register struct mbuf *, register struct mbuf *)); +void m_inc _P((struct mbuf *, int)); +void m_adj _P((struct mbuf *, int)); +int m_copy _P((struct mbuf *, struct mbuf *, int, int)); +struct mbuf * dtom _P((void *)); #endif diff --git a/BasiliskII/src/slirp/misc.c b/BasiliskII/src/slirp/misc.c old mode 100644 new mode 100755 index b80caf662..9438af382 --- a/BasiliskII/src/slirp/misc.c +++ b/BasiliskII/src/slirp/misc.c @@ -17,7 +17,10 @@ int x_port = -1; int x_display = 0; int x_screen = 0; -int show_x(char *buff, struct socket *inso) +int +show_x(buff, inso) + char *buff; + struct socket *inso; { if (x_port < 0) { lprint("X Redir: X not being redirected.\r\n"); @@ -37,7 +40,12 @@ int show_x(char *buff, struct socket *inso) /* * XXX Allow more than one X redirection? */ -void redir_x(u_int32_t inaddr, int start_port, int display, int screen) +void +redir_x(inaddr, start_port, display, screen) + u_int32_t inaddr; + int start_port; + int display; + int screen; { int i; @@ -61,69 +69,44 @@ void redir_x(u_int32_t inaddr, int start_port, int display, int screen) #endif #ifndef HAVE_INET_ATON -int inet_aton(const char *cp, struct in_addr *ia) +int +inet_aton(cp, ia) + const char *cp; + struct in_addr *ia; { - return inet_pton(AF_INET, cp, &ia->s_addr); + u_int32_t addr = inet_addr(cp); + if (addr == 0xffffffff) + return 0; + ia->s_addr = addr; + return 1; } #endif /* * Get our IP address and put it in our_addr */ -void getouraddr() +void +getouraddr() { char buff[256]; - - if (gethostname(buff, sizeof(buff)) == 0) - { - struct addrinfo hints = { 0 }; - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET; - struct addrinfo* ai; - if (getaddrinfo(buff, NULL, &hints, &ai) == 0) - { - our_addr = *(struct in_addr *)ai->ai_addr->sa_data; - freeaddrinfo(ai); - } - } - if (our_addr.s_addr == 0) - our_addr.s_addr = loopback_addr.s_addr; + struct hostent *he = NULL; + + if (gethostname(buff,256) == 0) + he = gethostbyname(buff); + if (he) + our_addr = *(struct in_addr *)he->h_addr; + if (our_addr.s_addr == 0) + our_addr.s_addr = loopback_addr.s_addr; } -#if SIZEOF_CHAR_P == 8 - -struct quehead_32 { - u_int32_t qh_link; - u_int32_t qh_rlink; -}; - -inline void insque_32(void *a, void *b) -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - register struct quehead_32 *head = (struct quehead_32 *) b; - element->qh_link = head->qh_link; - head->qh_link = (u_int32_t)element; - element->qh_rlink = (u_int32_t)head; - ((struct quehead_32 *)(element->qh_link))->qh_rlink - = (u_int32_t)element; -} - -inline void remque_32(void *a) -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#endif /* SIZEOF_CHAR_P == 8 */ - struct quehead { struct quehead *qh_link; struct quehead *qh_rlink; }; -void insque(void *a, void *b) +void +insque(a, b) + void *a, *b; { register struct quehead *element = (struct quehead *) a; register struct quehead *head = (struct quehead *) b; @@ -134,7 +117,9 @@ void insque(void *a, void *b) = (struct quehead *)element; } -void remque(void *a) +void +remque(a) + void *a; { register struct quehead *element = (struct quehead *) a; ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; @@ -146,7 +131,13 @@ void remque(void *a) /* #endif */ -int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port) +int +add_exec(ex_ptr, do_pty, exec, addr, port) + struct ex_list **ex_ptr; + int do_pty; + char *exec; + int addr; + int port; { struct ex_list *tmp_ptr; @@ -175,7 +166,9 @@ int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port extern int sys_nerr; extern char *sys_errlist[]; -char *strerror(int error) +char * +strerror(error) + int error; { if (error < sys_nerr) return sys_errlist[error]; @@ -188,7 +181,11 @@ char *strerror(int error) #ifdef _WIN32 -int fork_exec(struct socket *so, char *ex, int do_pty) +int +fork_exec(so, ex, do_pty) + struct socket *so; + char *ex; + int do_pty; { /* not implemented */ return 0; @@ -196,7 +193,9 @@ int fork_exec(struct socket *so, char *ex, int do_pty) #else -int slirp_openpty(int *amaster, int *aslave) +int +slirp_openpty(amaster, aslave) + int *amaster, *aslave; { register int master, slave; @@ -270,7 +269,11 @@ int slirp_openpty(int *amaster, int *aslave) * do_pty = 1 Fork/exec using slirp.telnetd * do_ptr = 2 Fork/exec using pty */ -int fork_exec(struct socket *so, char *ex, int do_pty) +int +fork_exec(so, ex, do_pty) + struct socket *so; + char *ex; + int do_pty; { int s; struct sockaddr_in addr; @@ -426,7 +429,9 @@ int fork_exec(struct socket *so, char *ex, int do_pty) #endif #ifndef HAVE_STRDUP -char *strdup(const char *str) +char * +strdup(str) + const char *str; { char *bptr; @@ -438,7 +443,9 @@ char *strdup(const char *str) #endif #if 0 -void snooze_hup(int num) +void +snooze_hup(num) + int num; { int s, ret; #ifndef NO_UNIX_SOCKETS @@ -478,7 +485,8 @@ void snooze_hup(int num) } -void snooze() +void +snooze() { sigset_t s; int i; @@ -502,7 +510,9 @@ void snooze() exit(255); } -void relay(int s) +void +relay(s) + int s; { char buf[8192]; int n; @@ -562,14 +572,25 @@ void relay(int s) } #endif -int (*lprint_print)(void *, const char *, va_list); +int (*lprint_print) _P((void *, const char *, va_list)); char *lprint_ptr, *lprint_ptr2, **lprint_arg; -void lprint(const char *format, ...) +void +#ifdef __STDC__ +lprint(const char *format, ...) +#else +lprint(va_alist) va_dcl +#endif { va_list args; - va_start(args, format); +#ifdef __STDC__ + va_start(args, format); +#else + char *format; + va_start(args); + format = va_arg(args, char *); +#endif #if 0 /* If we're printing to an sbuf, make sure there's enough room */ /* XXX +100? */ @@ -618,7 +639,9 @@ void lprint(const char *format, ...) va_end(args); } -void add_emu(char *buff) +void +add_emu(buff) + char *buff; { u_int lport, fport; u_int8_t tos = 0, emu = 0; @@ -710,24 +733,42 @@ void add_emu(char *buff) * Some BSD-derived systems have a sprintf which returns char * */ -int vsprintf_len(char *string, const char *format, va_list args) +int +vsprintf_len(string, format, args) + char *string; + const char *format; + va_list args; { vsprintf(string, format, args); return strlen(string); } -int sprintf_len(char *string, const char *format, ...) +int +#ifdef __STDC__ +sprintf_len(char *string, const char *format, ...) +#else +sprintf_len(va_alist) va_dcl +#endif { va_list args; +#ifdef __STDC__ va_start(args, format); +#else + char *string; + char *format; + va_start(args); + string = va_arg(args, char *); + format = va_arg(args, char *); +#endif vsprintf(string, format, args); - va_end(args); return strlen(string); } #endif -void u_sleep(int usec) +void +u_sleep(usec) + int usec; { struct timeval t; fd_set fdset; @@ -744,7 +785,9 @@ void u_sleep(int usec) * Set fd blocking and non-blocking */ -void fd_nonblock(int fd) +void +fd_nonblock(fd) + int fd; { #if defined USE_FIONBIO && defined FIONBIO ioctlsockopt_t opt = 1; @@ -759,7 +802,9 @@ void fd_nonblock(int fd) #endif } -void fd_block(int fd) +void +fd_block(fd) + int fd; { #if defined USE_FIONBIO && defined FIONBIO ioctlsockopt_t opt = 0; @@ -779,8 +824,13 @@ void fd_block(int fd) /* * invoke RSH */ -int rsh_exec(struct socket *so, struct socket *ns, - char *user, char *host, char *args) +int +rsh_exec(so,ns, user, host, args) + struct socket *so; + struct socket *ns; + char *user; + char *host; + char *args; { int fd[2]; int fd0[2]; diff --git a/BasiliskII/src/slirp/misc.h b/BasiliskII/src/slirp/misc.h old mode 100644 new mode 100755 index 381f5f3e7..efea9ff8b --- a/BasiliskII/src/slirp/misc.h +++ b/BasiliskII/src/slirp/misc.h @@ -19,15 +19,15 @@ struct ex_list { extern struct ex_list *exec_list; extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait; -extern int (*lprint_print)(void *, const char *, va_list); +extern int (*lprint_print) _P((void *, const char *, va_list)); extern char *lprint_ptr, *lprint_ptr2, **lprint_arg; extern struct sbuf *lprint_sb; #ifndef HAVE_STRDUP -char *strdup(const char *); +char *strdup _P((const char *)); #endif -void do_wait(int); +void do_wait _P((int)); #define EMU_NONE 0x0 @@ -67,21 +67,21 @@ extern struct emu_t *tcpemu; extern int x_port, x_server, x_display; -int show_x(char *, struct socket *); -void redir_x(u_int32_t, int, int, int); -void getouraddr(void); -void slirp_insque(void *, void *); -void slirp_remque(void *); -int add_exec(struct ex_list **, int, char *, int, int); -int slirp_openpty(int *, int *); -int fork_exec(struct socket *, char *, int); -void snooze_hup(int); -void snooze(void); -void relay(int); -void add_emu(char *); -void u_sleep(int); -void fd_nonblock(int); -void fd_block(int); -int rsh_exec(struct socket *, struct socket *, char *, char *, char *); +int show_x _P((char *, struct socket *)); +void redir_x _P((u_int32_t, int, int, int)); +void getouraddr _P((void)); +void slirp_insque _P((void *, void *)); +void slirp_remque _P((void *)); +int add_exec _P((struct ex_list **, int, char *, int, int)); +int slirp_openpty _P((int *, int *)); +int fork_exec _P((struct socket *, char *, int)); +void snooze_hup _P((int)); +void snooze _P((void)); +void relay _P((int)); +void add_emu _P((char *)); +void u_sleep _P((int)); +void fd_nonblock _P((int)); +void fd_block _P((int)); +int rsh_exec _P((struct socket *, struct socket *, char *, char *, char *)); #endif diff --git a/BasiliskII/src/slirp/sbuf.c b/BasiliskII/src/slirp/sbuf.c old mode 100644 new mode 100755 index 278e36870..2d078f381 --- a/BasiliskII/src/slirp/sbuf.c +++ b/BasiliskII/src/slirp/sbuf.c @@ -16,12 +16,17 @@ * } */ -void sbfree(struct sbuf *sb) +void +sbfree(sb) + struct sbuf *sb; { free(sb->sb_data); } -void sbdrop(struct sbuf *sb, u_int num) +void +sbdrop(sb, num) + struct sbuf *sb; + int num; { /* * We can only drop how much we have @@ -36,7 +41,10 @@ void sbdrop(struct sbuf *sb, u_int num) } -void sbreserve(struct sbuf *sb, size_t size) +void +sbreserve(sb, size) + struct sbuf *sb; + int size; { if (sb->sb_data) { /* Already alloced, realloc if necessary */ @@ -64,14 +72,17 @@ void sbreserve(struct sbuf *sb, size_t size) * this prevents an unnecessary copy of the data * (the socket is non-blocking, so we won't hang) */ -void sbappend(struct socket *so, struct mbuf *m) +void +sbappend(so, m) + struct socket *so; + struct mbuf *m; { int ret = 0; DEBUG_CALL("sbappend"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m->m_len = %zu", m->m_len); + DEBUG_ARG("m->m_len = %d", m->m_len); /* Shouldn't happen, but... e.g. foreign host closes connection */ if (m->m_len <= 0) { @@ -123,7 +134,10 @@ void sbappend(struct socket *so, struct mbuf *m) * Copy the data from m into sb * The caller is responsible to make sure there's enough room */ -void sbappendsb(struct sbuf *sb, struct mbuf *m) +void +sbappendsb(sb, m) + struct sbuf *sb; + struct mbuf *m; { int len, n, nn; @@ -159,7 +173,12 @@ void sbappendsb(struct sbuf *sb, struct mbuf *m) * Don't update the sbuf rptr, this will be * done in sbdrop when the data is acked */ -void sbcopy(struct sbuf *sb, u_int off, u_int len, char *to) +void +sbcopy(sb, off, len, to) + struct sbuf *sb; + int off; + int len; + char *to; { char *from; diff --git a/BasiliskII/src/slirp/sbuf.h b/BasiliskII/src/slirp/sbuf.h old mode 100644 new mode 100755 index 04f7981c7..161e0bb76 --- a/BasiliskII/src/slirp/sbuf.h +++ b/BasiliskII/src/slirp/sbuf.h @@ -8,8 +8,6 @@ #ifndef _SBUF_H_ #define _SBUF_H_ -#include - #define sbflush(sb) sbdrop((sb),(sb)->sb_cc) #define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) @@ -23,11 +21,11 @@ struct sbuf { char *sb_data; /* Actual data */ }; -void sbfree(struct sbuf *); -void sbdrop(struct sbuf *, u_int); -void sbreserve(struct sbuf *, size_t); -void sbappend(struct socket *, struct mbuf *); -void sbappendsb(struct sbuf *, struct mbuf *); -void sbcopy(struct sbuf *, u_int, u_int, char *); +void sbfree _P((struct sbuf *)); +void sbdrop _P((struct sbuf *, int)); +void sbreserve _P((struct sbuf *, int)); +void sbappend _P((struct socket *, struct mbuf *)); +void sbappendsb _P((struct sbuf *, struct mbuf *)); +void sbcopy _P((struct sbuf *, int, int, char *)); #endif diff --git a/BasiliskII/src/slirp/slirp.c b/BasiliskII/src/slirp/slirp.c old mode 100644 new mode 100755 index dc2fdc658..45c97612c --- a/BasiliskII/src/slirp/slirp.c +++ b/BasiliskII/src/slirp/slirp.c @@ -1,4 +1,7 @@ #include "slirp.h" +#ifdef __MINGW32__ +#include +#endif /* host address */ struct in_addr our_addr; @@ -84,7 +87,7 @@ static int get_dns_addr(struct in_addr *pdns_addr) static int get_dns_addr(struct in_addr *pdns_addr) { char buff[512]; - char buff2[256+1]; + char buff2[257]; FILE *f; int found = 0; struct in_addr tmp_addr; @@ -124,12 +127,15 @@ static int get_dns_addr(struct in_addr *pdns_addr) void slirp_cleanup(void) { WSACleanup(); + unload_host_domains(); } #endif int slirp_init(void) { // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); + + load_host_domains(); #ifdef _WIN32 { @@ -211,8 +217,8 @@ int slirp_select_fill(int *pnfds, * in the fragment queue, or there are TCP connections active */ do_slowtimo = ((tcb.so_next != &tcb) || - ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); - + (&ipq.ip_link != ipq.ip_link.next)); + for (so = tcb.so_next; so != &tcb; so = so_next) { so_next = so->so_next; @@ -220,14 +226,14 @@ int slirp_select_fill(int *pnfds, * See if we need a tcp_fasttimo */ if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) - time_fasttimo = curtime; /* Flag when we want a fasttimo */ + time_fasttimo = curtime; /* Flag when we want a fasttimo */ /* * NOFDREF can include still connecting to local-host, * newly socreated() sockets etc. Don't want to select these. */ if (so->so_state & SS_NOFDREF || so->s == -1) - continue; + continue; /* * Set for reading sockets which are accepting @@ -346,18 +352,18 @@ int slirp_select_fill(int *pnfds, void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) { - struct socket *so, *so_next; - int ret; + struct socket *so, *so_next; + int ret; - global_readfds = readfds; - global_writefds = writefds; - global_xfds = xfds; + global_readfds = readfds; + global_writefds = writefds; + global_xfds = xfds; /* Update time */ updtime(); - + /* - * See if anything has timed out + * See if anything has timed out */ if (link_up) { if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) { @@ -370,7 +376,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) last_slowtimo = curtime; } } - + /* * Check sockets */ @@ -380,21 +386,21 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) */ for (so = tcb.so_next; so != &tcb; so = so_next) { so_next = so->so_next; - + /* * FD_ISSET is meaningless on these sockets * (and they can crash the program) */ if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - + continue; + /* * Check for URG data * This will soread as well, so no need to * test for readfds below if this succeeds */ if (FD_ISSET(so->s, xfds)) - sorecvoob(so); + sorecvoob(so); /* * Check sockets for reading */ @@ -407,92 +413,86 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) continue; } /* else */ ret = soread(so); - + /* Output it if we read something */ if (ret > 0) - tcp_output(sototcpcb(so)); + tcp_output(sototcpcb(so)); } - + /* * Check sockets for writing */ if (FD_ISSET(so->s, writefds)) { - /* - * Check for non-blocking, still-connecting sockets - */ - if (so->so_state & SS_ISFCONNECTING) { - /* Connected */ - so->so_state &= ~SS_ISFCONNECTING; - - ret = send(so->s, (char*)&ret, 0, 0); - if (ret < 0) { - /* XXXXX Must fix, zero bytes is a NOP */ - int error = WSAGetLastError(); - if (error == EAGAIN || error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS || error == WSAENOTCONN) - continue; - - /* else failed */ - so->so_state = SS_NOFDREF; - } - /* else so->so_state &= ~SS_ISFCONNECTING; */ - - /* - * Continue tcp_input - */ - tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); - /* continue; */ - } - else - ret = sowrite(so); - /* - * XXXXX If we wrote something (a lot), there - * could be a need for a window update. - * In the worst case, the remote will send - * a window probe to get things going again - */ + /* + * Check for non-blocking, still-connecting sockets + */ + if (so->so_state & SS_ISFCONNECTING) { + /* Connected */ + so->so_state &= ~SS_ISFCONNECTING; + + ret = send(so->s, NULL, 0, 0); + if (ret < 0) { + /* XXXXX Must fix, zero bytes is a NOP */ + if (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINPROGRESS || errno == ENOTCONN) + continue; + + /* else failed */ + so->so_state = SS_NOFDREF; + } + /* else so->so_state &= ~SS_ISFCONNECTING; */ + + /* + * Continue tcp_input + */ + tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); + /* continue; */ + } else + ret = sowrite(so); + /* + * XXXXX If we wrote something (a lot), there + * could be a need for a window update. + * In the worst case, the remote will send + * a window probe to get things going again + */ } - + /* * Probe a still-connecting, non-blocking socket * to check if it's still alive - */ + */ #ifdef PROBE_CONN if (so->so_state & SS_ISFCONNECTING) { - ret = recv(so->s, (char *)&ret, 0, 0); - - if (ret < 0) { - /* XXX */ - int error = WSAGetLastError(); - if (error == EAGAIN || error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS || error == WSAENOTCONN) - continue; /* Still connecting, continue */ - - /* else failed */ - so->so_state = SS_NOFDREF; - - /* tcp_input will take care of it */ - } - else { - ret = send(so->s, &ret, 0, 0); - if (ret < 0) { - /* XXX */ - int error = WSAGetLastError(); - if (error == EAGAIN || error == WSAEWOULDBLOCK || - error == WSAEINPROGRESS || error == WSAENOTCONN) - continue; - /* else failed */ - so->so_state = SS_NOFDREF; - } - else - so->so_state &= ~SS_ISFCONNECTING; - - } - tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); - } /* SS_ISFCONNECTING */ + ret = recv(so->s, (char *)&ret, 0,0); + + if (ret < 0) { + /* XXX */ + if (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINPROGRESS || errno == ENOTCONN) + continue; /* Still connecting, continue */ + + /* else failed */ + so->so_state = SS_NOFDREF; + + /* tcp_input will take care of it */ + } else { + ret = send(so->s, &ret, 0,0); + if (ret < 0) { + /* XXX */ + if (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINPROGRESS || errno == ENOTCONN) + continue; + /* else failed */ + so->so_state = SS_NOFDREF; + } else + so->so_state &= ~SS_ISFCONNECTING; + + } + tcp_input((struct mbuf *)NULL, sizeof(struct ip),so); + } /* SS_ISFCONNECTING */ #endif - } - + } + /* * Now UDP sockets. * Incoming packets are sent straight away, they're not buffered. @@ -500,27 +500,27 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) */ for (so = udb.so_next; so != &udb; so = so_next) { so_next = so->so_next; - + if (so->s != -1 && FD_ISSET(so->s, readfds)) { - sorecvfrom(so); - } + sorecvfrom(so); + } } -} - + } + /* * See if we can start outputting */ if (if_queued && link_up) - if_start(); + if_start(); /* clear global file descriptor sets. * these reside on the stack in vl.c * so they're unusable if we're not in * slirp_select_fill or slirp_select_poll. */ - global_readfds = NULL; - global_writefds = NULL; - global_xfds = NULL; + global_readfds = NULL; + global_writefds = NULL; + global_xfds = NULL; } #define ETH_ALEN 6 diff --git a/BasiliskII/src/slirp/slirp.h b/BasiliskII/src/slirp/slirp.h old mode 100644 new mode 100755 index b845caa77..235c4c0e5 --- a/BasiliskII/src/slirp/slirp.h +++ b/BasiliskII/src/slirp/slirp.h @@ -22,12 +22,26 @@ typedef char *caddr_t; typedef int socklen_t; typedef unsigned long ioctlsockopt_t; +#ifdef __MINGW32__ +#if _WIN32_WINNT < 0x501 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif +#endif +//# include # include # include + # include # include # define USE_FIONBIO 1 +# define EWOULDBLOCK WSAEWOULDBLOCK +# define EINPROGRESS WSAEINPROGRESS +# define ENOTCONN WSAENOTCONN +# define EHOSTUNREACH WSAEHOSTUNREACH +# define ENETUNREACH WSAENETUNREACH +# define ECONNREFUSED WSAECONNREFUSED /* Basilisk II Router defines those */ # define udp_read_completion slirp_udp_read_completion @@ -133,23 +147,32 @@ typedef u_int32_t uint32; #include #endif +#ifndef _P +#ifndef NO_PROTOTYPES +# define _P(x) x +#else +# define _P(x) () +#endif +#endif + + #ifdef GETTIMEOFDAY_ONE_ARG #define gettimeofday(x, y) gettimeofday(x) #endif /* Systems lacking strdup() definition in . */ #if defined(ultrix) -char *strdup(const char *); +char *strdup _P((const char *)); #endif /* Systems lacking malloc() definition in . */ #if defined(ultrix) || defined(hcx) -void *malloc(size_t arg); -void free(void *ptr); +void *malloc _P((size_t arg)); +void free _P((void *ptr)); #endif #ifndef HAVE_INET_ATON -int inet_aton(const char *cp, struct in_addr *ia); +int inet_aton _P((const char *cp, struct in_addr *ia)); #endif #include @@ -187,7 +210,11 @@ int inet_aton(const char *cp, struct in_addr *ia); #include #endif +#ifdef __STDC__ #include +#else +#include +#endif #include @@ -246,38 +273,38 @@ extern struct ttys *ttys_unit[MAX_INTERFACES]; #endif #ifndef FULL_BOLT -void if_start(void); +void if_start _P((void)); #else -void if_start(struct ttys *); +void if_start _P((struct ttys *)); #endif #ifdef BAD_SPRINTF # define vsprintf vsprintf_len # define sprintf sprintf_len - extern int vsprintf_len(char *, const char *, va_list); - extern int sprintf_len(char *, const char *, ...); + extern int vsprintf_len _P((char *, const char *, va_list)); + extern int sprintf_len _P((char *, const char *, ...)); #endif #ifdef DECLARE_SPRINTF # ifndef BAD_SPRINTF - extern int vsprintf(char *, const char *, va_list); + extern int vsprintf _P((char *, const char *, va_list)); # endif - extern int vfprintf(FILE *, const char *, va_list); + extern int vfprintf _P((FILE *, const char *, va_list)); #endif #ifndef HAVE_STRERROR - extern char *strerror(int error); + extern char *strerror _P((int error)); #endif #ifndef HAVE_INDEX - char *index(const char *, int); + char *index _P((const char *, int)); #endif #ifndef HAVE_GETHOSTID - long gethostid(void); + long gethostid _P((void)); #endif -void lprint(const char *, ...); +void lprint _P((const char *, ...)); extern int do_echo; @@ -299,49 +326,53 @@ extern int do_echo; int cksum(struct mbuf *m, int len); /* if.c */ -void if_init(void); -void if_output(struct socket *, struct mbuf *); +void if_init _P((void)); +void if_output _P((struct socket *, struct mbuf *)); /* ip_input.c */ -void ip_init(void); -void ip_input(struct mbuf *); -struct ip * ip_reass(register struct ipasfrag *, register struct ipq *); -void ip_freef(struct ipq *); -void ip_enq(register struct ipasfrag *, register struct ipasfrag *); -void ip_deq(register struct ipasfrag *); -void ip_slowtimo(void); -void ip_stripoptions(register struct mbuf *, struct mbuf *); +void ip_init _P((void)); +void ip_input _P((struct mbuf *)); +static struct ip * +ip_reass(register struct ip *ip, register struct ipq *); +void ip_freef _P((struct ipq *)); +void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *)); +void ip_deq _P((register struct ipasfrag *)); +void ip_slowtimo _P((void)); +void ip_stripoptions _P((register struct mbuf *, struct mbuf *)); /* ip_output.c */ -int ip_output(struct socket *, struct mbuf *); +int ip_output _P((struct socket *, struct mbuf *)); /* tcp_input.c */ -int tcp_reass(register struct tcpcb *, register struct tcpiphdr *, struct mbuf *); -void tcp_input(register struct mbuf *, int, struct socket *); -void tcp_dooptions(struct tcpcb *, u_char *, int, struct tcpiphdr *); -void tcp_xmit_timer(register struct tcpcb *, int); -u_int tcp_mss(register struct tcpcb *, u_int); +int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, struct mbuf *)); +void tcp_input _P((register struct mbuf *, int, struct socket *)); +void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *)); +void tcp_xmit_timer _P((register struct tcpcb *, int)); +int tcp_mss _P((register struct tcpcb *, u_int)); /* tcp_output.c */ -int tcp_output(register struct tcpcb *); -void tcp_setpersist(register struct tcpcb *); +int tcp_output _P((register struct tcpcb *)); +void tcp_setpersist _P((register struct tcpcb *)); /* tcp_subr.c */ -void tcp_init(void); -void tcp_template(struct tcpcb *); -void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int); -struct tcpcb * tcp_newtcpcb(struct socket *); -struct tcpcb * tcp_close(register struct tcpcb *); -void tcp_drain(void); -void tcp_sockclosed(struct tcpcb *); -int tcp_fconnect(struct socket *); -void tcp_connect(struct socket *); -int tcp_attach(struct socket *); -u_int8_t tcp_tos(struct socket *); -int tcp_emu(struct socket *, struct mbuf *); -int tcp_ctl(struct socket *); +void tcp_init _P((void)); +void tcp_template _P((struct tcpcb *)); +void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int)); +struct tcpcb * tcp_newtcpcb _P((struct socket *)); +struct tcpcb * tcp_close _P((register struct tcpcb *)); +void tcp_drain _P((void)); +void tcp_sockclosed _P((struct tcpcb *)); +int tcp_fconnect _P((struct socket *)); +void tcp_connect _P((struct socket *)); +int tcp_attach _P((struct socket *)); +u_int8_t tcp_tos _P((struct socket *)); +int tcp_emu _P((struct socket *, struct mbuf *)); +int tcp_ctl _P((struct socket *)); struct tcpcb *tcp_drop(struct tcpcb *tp, int err); +void load_host_domains(); +void unload_host_domains(); + #ifdef USE_PPP #define MIN_MRU MINMRU #define MAX_MRU MAXMRU @@ -355,4 +386,9 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err); #define max(x,y) ((x) > (y) ? (x) : (y)) #endif +#ifdef _WIN32 +#undef errno +#define errno (WSAGetLastError()) +#endif + #endif diff --git a/BasiliskII/src/slirp/slirp_config.h b/BasiliskII/src/slirp/slirp_config.h old mode 100644 new mode 100755 index 237268fa8..e583dcc80 --- a/BasiliskII/src/slirp/slirp_config.h +++ b/BasiliskII/src/slirp/slirp_config.h @@ -40,6 +40,11 @@ */ #undef USE_LOWCPU +/* Define this if your compiler doesn't like prototypes */ +#ifndef __STDC__ +#define NO_PROTOTYPES +#endif + /*********************************************************/ /* * Autoconf defined configuration options @@ -72,6 +77,9 @@ /* Define if you have sys/stropts.h */ #undef HAVE_SYS_STROPTS_H +/* Define if your compiler doesn't like prototypes */ +#undef NO_PROTOTYPES + /* Define if you don't have u_int32_t etc. typedef'd */ #undef NEED_TYPEDEFS #ifdef __sun__ diff --git a/BasiliskII/src/slirp/socket.c b/BasiliskII/src/slirp/socket.c old mode 100644 new mode 100755 index 42ba31b24..6968002ed --- a/BasiliskII/src/slirp/socket.c +++ b/BasiliskII/src/slirp/socket.c @@ -13,13 +13,107 @@ #ifdef __sun__ #include #endif +#include +#include +#include -#ifdef _WIN32 -#define IS_EAGAIN(e) ((e) == WSAEINTR || (e) == EAGAIN) +#define DEBUG_HOST_RESOLVED_DNS 0 + +/** + * DNS requests for these domain suffixes will be + * looked up on the host to allow for host-supported DNS alternatives + * (e.g. MDNS, hosts file, etc.) + **/ +static const char ** host_resolved_domain_suffixes = NULL; + +#define HOST_DOMAIN_TTL 60 // In seconds. + +#if DEBUG_HOST_RESOLVED_DNS +#define D(...) printf(__VA_ARGS__); fflush(stdout); #else -#define IS_EAGAIN(e) ((e) == EAGAIN) +#define D(...) #endif +const char *PrefsFindStringC(const char *name, int index); + +int prepare_host_domain_suffixes(char * buf) { + /** + * Set up the list of domain suffixes to match from the host_domain prefs. + * Call first with buf NULL to figure out the size of buffer needed. + **/ + int pos = 0; + const char ** host_resolved_domain_suffixes_pos = NULL; + + if (buf) { + D("Setting up slirp host domain suffixes for matching:\n"); + host_resolved_domain_suffixes_pos = (const char **) buf; + } + + // find out how many values there are + int host_domain_count = 0; + while (PrefsFindStringC("host_domain", host_domain_count) != NULL) { + host_domain_count ++; + } + + // leave space for the top array + pos += (host_domain_count + 1) * sizeof(const char *); + + const char *str; + int host_domain_num = 0; + while ((str = PrefsFindStringC("host_domain", host_domain_num++)) != NULL) { + if (str[0] == '\0') continue; + if (buf) { + const char * cur_entry = (const char *) (buf + pos); + *host_resolved_domain_suffixes_pos = cur_entry; + host_resolved_domain_suffixes_pos++; + } + + // this is a suffix to match so it must have a leading dot + if (str[0] != '.') { + if (buf) buf[pos] = '.'; + pos++; + } + const char * str_pos = str; + while (*str_pos != '\0') { + if (buf) buf[pos] = tolower(*str_pos); + ++pos; + ++str_pos; + } + // domain to be checked will be FQDN so suffix must have a trailing dot + if (str[strlen(str) - 1] != '.') { + if (buf) buf[pos] = '.'; + pos++; + } + if (buf) { + buf[pos] = '\0'; + D(" %d. %s\n", host_domain_num, *(host_resolved_domain_suffixes_pos-1)); + } + pos++; + } + + // end of list marker + if (buf) *host_resolved_domain_suffixes_pos = NULL; + + return pos; +} + +void load_host_domains() { + const int size = prepare_host_domain_suffixes(NULL); + char * buf = malloc(size); + if (buf) { + const int second_size = prepare_host_domain_suffixes(buf); + assert(size == second_size); + host_resolved_domain_suffixes = (const char **) buf; + } +} + +void unload_host_domains() { + if (host_resolved_domain_suffixes) { + free((char *) host_resolved_domain_suffixes); + host_resolved_domain_suffixes = NULL; + } +} + void so_init() { @@ -103,12 +197,11 @@ int soread(so) struct socket *so; { - int n, nn; - u_int lss, total; + int n, nn, lss, total; struct sbuf *sb = &so->so_snd; - u_int len = sb->sb_datalen - sb->sb_cc; + int len = sb->sb_datalen - sb->sb_cc; struct iovec iov[2]; - u_int mss = so->so_tcpcb->t_maxseg; + int mss = so->so_tcpcb->t_maxseg; DEBUG_CALL("soread"); DEBUG_ARG("so = %lx", (long )so); @@ -166,8 +259,7 @@ soread(so) nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif if (nn <= 0) { - int error = WSAGetLastError(); - if (nn < 0 && IS_EAGAIN(error)) + if (nn < 0 && (errno == EINTR || errno == EAGAIN)) return 0; else { DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); @@ -305,7 +397,7 @@ sowrite(so) { int n,nn; struct sbuf *sb = &so->so_rcv; - u_int len = sb->sb_cc; + int len = sb->sb_cc; struct iovec iov[2]; DEBUG_CALL("sowrite"); @@ -352,12 +444,9 @@ sowrite(so) nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif /* This should never happen, but people tell me it does *shrug* */ - if (nn < 0) { - int error = WSAGetLastError(); - if (IS_EAGAIN(error)) - return 0; - } - + if (nn < 0 && (errno == EAGAIN || errno == EINTR)) + return 0; + if (nn <= 0) { DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", so->so_state, errno)); @@ -416,9 +505,8 @@ sorecvfrom(so) if(len == -1 || len == 0) { u_char code=ICMP_UNREACH_PORT; - int error = WSAGetLastError(); - if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; + if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", errno,strerror(errno))); @@ -431,7 +519,7 @@ sorecvfrom(so) udp_detach(so); } else { /* A "normal" UDP packet */ struct mbuf *m; - u_int len; + int len; ioctlsockopt_t n; if (!(m = m_get())) return; @@ -454,14 +542,13 @@ sorecvfrom(so) m->m_len = recvfrom(so->s, m->m_data, len, 0, (struct sockaddr *)&addr, &addrlen); - DEBUG_MISC((dfd, " did recvfrom %zu, errno = %d-%s\n", + DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", m->m_len, errno,strerror(errno))); if(m->m_len<0) { u_char code=ICMP_UNREACH_PORT; - int error = WSAGetLastError(); - if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; + if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); @@ -495,6 +582,300 @@ sorecvfrom(so) } /* if ping packet */ } +// Commented structs from silv3rm00n's example code +// https://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/ + +struct DNS_HEADER +{ + unsigned short id; // identification number + + unsigned char rd :1; // recursion desired + unsigned char tc :1; // truncated message + unsigned char aa :1; // authoritive answer + unsigned char opcode :4; // purpose of message + unsigned char qr :1; // query/response flag + + unsigned char rcode :4; // response code + unsigned char cd :1; // checking disabled + unsigned char ad :1; // authenticated data + unsigned char z :1; // its z! reserved + unsigned char ra :1; // recursion available + + unsigned short q_count; // number of question entries + unsigned short ans_count; // number of answer entries + unsigned short auth_count; // number of authority entries + unsigned short add_count; // number of resource entries +}; + +struct QUESTION +{ + unsigned short qtype; + unsigned short qclass; +}; + +#pragma pack(push, 1) +struct R_DATA +{ + unsigned short type; + unsigned short _class; + unsigned int ttl; + unsigned short data_len; +}; +#pragma pack(pop) + +/** Create local variable varname of type vartype, + * fill it from the buffer data, observing its length len, + * and adjust data and len to reflect the remaining data */ +#define POP_DATA(vartype, varname, data, len) \ + assert(len >= sizeof(vartype)); \ + vartype varname; \ + memcpy(&varname, data, sizeof(vartype)); \ + data += sizeof(vartype); \ + len -= sizeof(vartype) + + +/** Create local const char * varname pointing + * to the C string in the buffer data, observing its length len, + * and adjust data and len to reflect the remaining data */ +#define POP_STR(varname, data, len) \ + const char * varname; \ + { \ + int pop_str_len = strnlen(data, len); \ + if (pop_str_len == len) { \ + varname = NULL; \ + } else { \ + varname = data; \ + } \ + data += pop_str_len + 1; \ + len -= pop_str_len + 1; \ + } + + +static void inject_udp_packet_to_guest(struct socket * so, struct sockaddr_in addr, caddr_t packet_data, int packet_len) { + struct mbuf *m; + int len; + + /** This is like sorecvfrom(), but just adds a packet with the + * supplied data instead of reading the packet to add from the socket */ + + if (!(m = m_get())) return; + m->m_data += if_maxlinkhdr; + + len = M_FREEROOM(m); + + if (packet_len > len) { + packet_len = (m->m_data - m->m_dat) + m->m_len + packet_len + 1; + m_inc(m, packet_len); + len = M_FREEROOM(m); + } + + assert(len >= packet_len); + m->m_len = packet_len; + memcpy(m->m_data, packet_data, packet_len); + + udp_output(so, m, &addr); +} + +/* Decode hostname from the format used in DNS + e.g. "\009something\004else\003com" for "something.else.com." */ +static char * decode_dns_name(const char * data) { + + int query_str_len = strlen(data); + char * decoded_name_str = malloc(query_str_len + 1); + if (decoded_name_str == NULL) { + D("decode_dns_name(): out of memory\n"); + return NULL; // oom + } + + char * decoded_name_str_pos = decoded_name_str; + while (*data != '\0') { + int part_len = *data++; + query_str_len--; + if (query_str_len < part_len) { + D("decode_dns_name(): part went off the end of the string\n"); + free(decoded_name_str); + return NULL; + } + memcpy(decoded_name_str_pos, data, part_len); + decoded_name_str_pos[part_len] = '.'; + decoded_name_str_pos += part_len + 1; + query_str_len -= part_len; + data += part_len; + } + *decoded_name_str_pos = '\0'; + return decoded_name_str; +} + +/** Take a look at a UDP DNS request the client has made and see if we want to resolve it internally. + * Returns true if the request has been internally and can be dropped, + * false otherwise + **/ +static bool resolve_dns_request(struct socket * so, struct sockaddr_in addr, caddr_t data, int len) { + bool drop_dns_request = false; + + D("Checking outgoing DNS UDP packet\n"); + + if (len < sizeof(struct DNS_HEADER)) { + D("Packet too short for DNS header\n"); + return false; + } + + const caddr_t packet = data; + const int packet_len = len; + + POP_DATA(struct DNS_HEADER, h, data, len); + + if (h.qr != 0) { + D("DNS packet is not a request\n"); + return false; + } + + if (ntohs(h.q_count) == 0) { + D("DNS request has no queries\n"); + return false; + } + + if (ntohs(h.q_count) > 1) { + D("DNS request has multiple queries (not supported)\n"); + return false; + } + + if (ntohs(h.ans_count != 0) || ntohs(h.auth_count != 0) || ntohs(h.add_count != 0)) { + D("DNS request has unsupported extra contents\n"); + return false; + } + + if (len == 0) { + D("Packet too short for DNS query string\n"); + return false; + } + + POP_STR(original_query_str, data, len); + if (original_query_str == NULL) { + // went off end of packet + D("Unterminated DNS query string\n"); + return false; + } + + char * decoded_name_str = decode_dns_name(original_query_str); + if (decoded_name_str == NULL) { + D("Error while decoding DNS query string"); + return false; + } + + D("DNS host query for %s\n", decoded_name_str); + + POP_DATA(struct QUESTION, qinfo, data, len); + + if (ntohs(qinfo.qtype) != 1 /* type A */ || ntohs(qinfo.qclass) != 1 /* class IN */ ) { + D("DNS host query for %s: Request isn't the supported type (INET A query)\n", decoded_name_str); + free(decoded_name_str); + return false; + } + + D("DNS host query for %s: Request is eligible to check for host resolution suffix\n", decoded_name_str); + + const char * matched_suffix = NULL; + + for (const char ** suffix_ptr = host_resolved_domain_suffixes; *suffix_ptr != NULL; suffix_ptr++) { + const char * suffix = *suffix_ptr; + + // ends with suffix? + int suffix_pos = strlen(decoded_name_str) - strlen(suffix); + if (suffix_pos > 0 && strcmp(decoded_name_str + suffix_pos, suffix) == 0) { + matched_suffix = suffix; + break; + } + + // also check if the domain exactly matched the one the suffix is for + if (strcmp(decoded_name_str, suffix + 1) == 0) { + matched_suffix = suffix; + break; + } + } + + if (matched_suffix == NULL) { + D("DNS host query for %s: No suffix matched\n", decoded_name_str); + } else { + + D("DNS host query for %s: Matched for suffix: %s\n", decoded_name_str, matched_suffix); + + // we are going to take this request and resolve it on the host + drop_dns_request = true; + + D("DNS host query for %s: Doing lookup on host\n", decoded_name_str); + + int results_count = 0; + struct hostent * host_lookup_result = gethostbyname(decoded_name_str); + + if (host_lookup_result && host_lookup_result->h_addrtype == AF_INET) { + + D("DNS host query for %s: Host response has results for AF_INET\n", decoded_name_str); + + for (char ** addr_entry = host_lookup_result->h_addr_list; *addr_entry != NULL; addr_entry++) { + ++results_count; + } + } + + D("DNS host query for %s: result count %d\n", decoded_name_str, results_count); + + int original_query_str_size = strlen(original_query_str) + 1; + int response_size = packet_len + results_count * (original_query_str_size + sizeof(struct R_DATA) + sizeof(struct in_addr)); + + caddr_t response_packet = malloc(response_size); + if (response_packet == NULL) { + D("DNS host query for %s: Out of memory while allocating DNS response packet\n", decoded_name_str); + } else { + D("DNS host query for %s: Preparing DNS response\n", decoded_name_str); + + // use the request DNS header as our starting point for the response + h.qr = 1; + h.ans_count = htons(results_count); + memcpy(response_packet, &h, sizeof(struct DNS_HEADER)); + + // other sections verbatim out of the request + memcpy(response_packet + sizeof(struct DNS_HEADER), packet + sizeof(struct DNS_HEADER), packet_len - sizeof(struct DNS_HEADER)); + + int response_pos = packet_len; + + if (results_count > 0) { + for (char ** addr_entry = host_lookup_result->h_addr_list; *addr_entry != NULL; addr_entry++) { + // answer string is verbatim from question + memcpy(response_packet + response_pos, original_query_str, original_query_str_size); + + response_pos += original_query_str_size; + + struct R_DATA resource; + resource.type = htons(1); + resource._class = htons(1); + resource.ttl = htonl(HOST_DOMAIN_TTL); + resource.data_len = htons(sizeof(struct in_addr)); + + memcpy(response_packet + response_pos, &resource, sizeof(struct R_DATA)); + response_pos += sizeof(struct R_DATA); + + struct in_addr * cur_addr = (struct in_addr *)*addr_entry; + memcpy(response_packet + response_pos, cur_addr, sizeof(struct in_addr)); + response_pos += sizeof(struct in_addr); + } + } + + assert(response_pos == response_size); + + D("DNS host query for %s: Injecting DNS response directly to guest\n", decoded_name_str); + inject_udp_packet_to_guest(so, addr, response_packet, response_size); + + free(response_packet); + } + + } + + free(decoded_name_str); + + D("DNS host request drop: %s\n", drop_dns_request? "yes" : "no"); + return drop_dns_request; +} + /* * sendto() a socket */ @@ -516,6 +897,10 @@ sosendto(so, m) switch(ntohl(so->so_faddr.s_addr) & 0xff) { case CTL_DNS: addr.sin_addr = dns_addr; + if (host_resolved_domain_suffixes != NULL) { + if (resolve_dns_request(so, addr, m->m_data, m->m_len)) + return 0; + } break; case CTL_ALIAS: default: @@ -526,9 +911,7 @@ sosendto(so, m) addr.sin_addr = so->so_faddr; addr.sin_port = so->so_fport; - char addrstr[INET_ADDRSTRLEN]; - DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, addrstr, sizeof(addrstr)))); + DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); /* Don't care what port we get */ ret = sendto(so->s, m->m_data, m->m_len, 0, @@ -599,12 +982,16 @@ solisten(port, laddr, lport, flags) (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || (listen(s,1) < 0)) { - int error = WSAGetLastError(); /* Don't clobber the real reason we failed */ + int tmperrno = errno; /* Don't clobber the real reason we failed */ close(s); sofree(so); /* Restore the real errno */ - WSASetLastError(error); +#ifdef _WIN32 + WSASetLastError(tmperrno); +#else + errno = tmperrno; +#endif return NULL; } setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); diff --git a/BasiliskII/src/slirp/socket.h b/BasiliskII/src/slirp/socket.h old mode 100644 new mode 100755 index 3b0fee169..d05354c8c --- a/BasiliskII/src/slirp/socket.h +++ b/BasiliskII/src/slirp/socket.h @@ -81,24 +81,24 @@ struct iovec { }; #endif -void so_init(void); -struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int); -struct socket * socreate(void); -void sofree(struct socket *); -int soread(struct socket *); -void sorecvoob(struct socket *); -int sosendoob(struct socket *); -int sowrite(struct socket *); -void sorecvfrom(struct socket *); -int sosendto(struct socket *, struct mbuf *); -struct socket * solisten(u_int, u_int32_t, u_int, int); -void sorwakeup(struct socket *); -void sowwakeup(struct socket *); -void soisfconnecting(register struct socket *); -void soisfconnected(register struct socket *); -void sofcantrcvmore(struct socket *); -void sofcantsendmore(struct socket *); -void soisfdisconnected(struct socket *); -void sofwdrain(struct socket *); +void so_init _P((void)); +struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int)); +struct socket * socreate _P((void)); +void sofree _P((struct socket *)); +int soread _P((struct socket *)); +void sorecvoob _P((struct socket *)); +int sosendoob _P((struct socket *)); +int sowrite _P((struct socket *)); +void sorecvfrom _P((struct socket *)); +int sosendto _P((struct socket *, struct mbuf *)); +struct socket * solisten _P((u_int, u_int32_t, u_int, int)); +void sorwakeup _P((struct socket *)); +void sowwakeup _P((struct socket *)); +void soisfconnecting _P((register struct socket *)); +void soisfconnected _P((register struct socket *)); +void sofcantrcvmore _P((struct socket *)); +void sofcantsendmore _P((struct socket *)); +void soisfdisconnected _P((struct socket *)); +void sofwdrain _P((struct socket *)); #endif /* _SOCKET_H_ */ diff --git a/BasiliskII/src/slirp/tcp.h b/BasiliskII/src/slirp/tcp.h old mode 100644 new mode 100755 index 24e7914ab..5f03f9e17 --- a/BasiliskII/src/slirp/tcp.h +++ b/BasiliskII/src/slirp/tcp.h @@ -38,8 +38,8 @@ typedef u_int32_t tcp_seq; #define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ #define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ -extern size_t tcp_rcvspace; -extern size_t tcp_sndspace; +extern int tcp_rcvspace; +extern int tcp_sndspace; extern struct socket *tcp_last_so; #define TCP_SNDSPACE 8192 @@ -78,7 +78,7 @@ struct tcphdr { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif #include "tcp_var.h" diff --git a/BasiliskII/src/slirp/tcp_input.c b/BasiliskII/src/slirp/tcp_input.c old mode 100644 new mode 100755 index 032e5378e..fc7c0bc01 --- a/BasiliskII/src/slirp/tcp_input.c +++ b/BasiliskII/src/slirp/tcp_input.c @@ -68,7 +68,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #ifdef TCP_ACK_HACK #define TCP_REASS(tp, ti, m, so, flags) {\ if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + tcpfrag_list_empty(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) {\ if (ti->ti_flags & TH_PUSH) \ tp->t_flags |= TF_ACKNOW; \ @@ -91,7 +91,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #else #define TCP_REASS(tp, ti, m, so, flags) { \ if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + tcpfrag_list_empty(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) { \ tp->t_flags |= TF_DELACK; \ (tp)->rcv_nxt += (ti)->ti_len; \ @@ -111,7 +111,10 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #endif int -tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *m) +tcp_reass(tp, ti, m) + register struct tcpcb *tp; + register struct tcpiphdr *ti; + struct mbuf *m; { register struct tcpiphdr *q; struct socket *so = tp->t_socket; @@ -127,8 +130,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf * /* * Find a segment which begins after this one does. */ - for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp; - q = (struct tcpiphdr *)q->ti_next) + for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); + q = tcpiphdr_next(q)) if (SEQ_GT(q->ti_seq, ti->ti_seq)) break; @@ -137,9 +140,9 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf * * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { + if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { register int i; - q = (struct tcpiphdr *)q->ti_prev; + q = tcpiphdr_prev(q); /* conversion to int (in i) handles seq wraparound */ i = q->ti_seq + q->ti_len - ti->ti_seq; if (i > 0) { @@ -159,37 +162,36 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf * ti->ti_len -= i; ti->ti_seq += i; } - q = (struct tcpiphdr *)(q->ti_next); + q = tcpiphdr_next(q); } tcpstat.tcps_rcvoopack++; tcpstat.tcps_rcvoobyte += ti->ti_len; - REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ + ti->ti_mbuf = m; /* * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (q != (struct tcpiphdr *)tp) { + while (!tcpfrag_list_end(q, tp)) { register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; if (i <= 0) break; if (i < q->ti_len) { q->ti_seq += i; q->ti_len -= i; - m_adj((struct mbuf *) REASS_MBUF(q), i); + m_adj(q->ti_mbuf, i); break; } - q = (struct tcpiphdr *)q->ti_next; - m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev); - remque_32((void *)(q->ti_prev)); + q = tcpiphdr_next(q); + m = tcpiphdr_prev(q)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(q))); m_freem(m); } /* * Stick new segment in its place. */ - insque_32(ti, (void *)(q->ti_prev)); - + insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); present: /* * Present data to user, advancing rcv_nxt through @@ -197,17 +199,17 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf * */ if (!TCPS_HAVEESTABLISHED(tp->t_state)) return (0); - ti = (struct tcpiphdr *) tp->seg_next; - if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) + ti = tcpfrag_list_first(tp); + if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt) return (0); if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) return (0); do { tp->rcv_nxt += ti->ti_len; flags = ti->ti_flags & TH_FIN; - remque_32(ti); - m = (struct mbuf *) REASS_MBUF(ti); /* XXX */ - ti = (struct tcpiphdr *)ti->ti_next; + remque(tcpiphdr2qlink(ti)); + m = ti->ti_mbuf; + ti = tcpiphdr_next(ti); /* if (so->so_state & SS_FCANTRCVMORE) */ if (so->so_state & SS_FCANTSENDMORE) m_freem(m); @@ -226,9 +228,13 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf * * TCP input routine, follows pages 65-76 of the * protocol specification dated September, 1981 very closely. */ -void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) +void +tcp_input(m, iphlen, inso) + register struct mbuf *m; + int iphlen; + struct socket *inso; { - struct ip save_ip, *ip; + struct ip save_ip, *ip; register struct tcpiphdr *ti; caddr_t optp = NULL; int optlen = 0; @@ -236,25 +242,23 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) register struct tcpcb *tp = 0; register int tiflags; struct socket *so = 0; - int todrop; - u_int acked; - int ourfinisacked, needoutput = 0; - /* int dropsocket = 0; */ + int todrop, acked, ourfinisacked, needoutput = 0; +/* int dropsocket = 0; */ int iss = 0; u_long tiwin; int ret; - /* int ts_present = 0; */ +/* int ts_present = 0; */ DEBUG_CALL("tcp_input"); - DEBUG_ARGS((dfd, " m = %8lx iphlen = %2d inso = %lx\n", - (long)m, iphlen, (long)inso)); - + DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", + (long )m, iphlen, (long )inso )); + /* * If called with m == 0, then we're continuing the connect */ if (m == NULL) { so = inso; - + /* Re-set a few variables */ tp = sototcpcb(so); m = so->so_m; @@ -262,46 +266,47 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) ti = so->so_ti; tiwin = ti->ti_win; tiflags = ti->ti_flags; - + goto cont_conn; } - - + + tcpstat.tcps_rcvtotal++; /* * Get IP and TCP header together in first mbuf. * Note: IP leaves IP header in first mbuf. */ ti = mtod(m, struct tcpiphdr *); - if (iphlen > sizeof(struct ip)) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen = sizeof(struct ip); + if (iphlen > sizeof(struct ip )) { + ip_stripoptions(m, (struct mbuf *)0); + iphlen=sizeof(struct ip ); } /* XXX Check if too short */ - + /* * Save a copy of the IP header in case we want restore it * for sending an ICMP error message in response. */ - ip = mtod(m, struct ip *); - save_ip = *ip; - save_ip.ip_len += iphlen; + ip=mtod(m, struct ip *); + save_ip = *ip; + save_ip.ip_len+= iphlen; /* * Checksum extended TCP header and data. */ tlen = ((struct ip *)ti)->ip_len; - ti->ti_next = ti->ti_prev = 0; + tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0; + memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); ti->ti_x1 = 0; ti->ti_len = htons((u_int16_t)tlen); - len = sizeof(struct ip) + tlen; + len = sizeof(struct ip ) + tlen; /* keep checksum for ICMP reply - * ti->ti_sum = cksum(m, len); + * ti->ti_sum = cksum(m, len); * if (ti->ti_sum) { */ - if (cksum(m, len)) { - tcpstat.tcps_rcvbadsum++; - goto drop; + if(cksum(m, len)) { + tcpstat.tcps_rcvbadsum++; + goto drop; } /* @@ -309,37 +314,37 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) * pull out TCP options and adjust length. XXX */ off = ti->ti_off << 2; - if (off < sizeof(struct tcphdr) || off > tlen) { - tcpstat.tcps_rcvbadoff++; - goto drop; + if (off < sizeof (struct tcphdr) || off > tlen) { + tcpstat.tcps_rcvbadoff++; + goto drop; } tlen -= off; ti->ti_len = tlen; - if (off > sizeof(struct tcphdr)) { - optlen = off - sizeof(struct tcphdr); - optp = mtod(m, caddr_t) + sizeof(struct tcpiphdr); + if (off > sizeof (struct tcphdr)) { + optlen = off - sizeof (struct tcphdr); + optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr); - /* + /* * Do quick retrieval of timestamp options ("options * prediction?"). If timestamp is the only option and it's * formatted as recommended in RFC 1323 appendix A, we * quickly get the values now and not bother calling * tcp_dooptions(), etc. */ - /* if ((optlen == TCPOLEN_TSTAMP_APPA || - * (optlen > TCPOLEN_TSTAMP_APPA && - * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && - * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && - * (ti->ti_flags & TH_SYN) == 0) { - * ts_present = 1; - * ts_val = ntohl(*(u_int32_t *)(optp + 4)); - * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); - * optp = NULL; / * we've parsed the options * / - * } - */ +/* if ((optlen == TCPOLEN_TSTAMP_APPA || + * (optlen > TCPOLEN_TSTAMP_APPA && + * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && + * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && + * (ti->ti_flags & TH_SYN) == 0) { + * ts_present = 1; + * ts_val = ntohl(*(u_int32_t *)(optp + 4)); + * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); + * optp = NULL; / * we've parsed the options * / + * } + */ } tiflags = ti->ti_flags; - + /* * Convert TCP protocol specific fields to host format. */ @@ -351,20 +356,20 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) /* * Drop TCP, IP headers and TCP options. */ - m->m_data += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - m->m_len -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - + m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + /* * Locate pcb for segment. */ findso: so = tcp_last_so; if (so->so_fport != ti->ti_dport || - so->so_lport != ti->ti_sport || - so->so_laddr.s_addr != ti->ti_src.s_addr || - so->so_faddr.s_addr != ti->ti_dst.s_addr) { + so->so_lport != ti->ti_sport || + so->so_laddr.s_addr != ti->ti_src.s_addr || + so->so_faddr.s_addr != ti->ti_dst.s_addr) { so = solookup(&tcb, ti->ti_src, ti->ti_sport, - ti->ti_dst, ti->ti_dport); + ti->ti_dst, ti->ti_dport); if (so) tcp_last_so = so; ++tcpstat.tcps_socachemiss; @@ -377,63 +382,63 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) * but should either do a listen or a connect soon. * * state == CLOSED means we've done socreate() but haven't - * attached it to a protocol yet... - * + * attached it to a protocol yet... + * * XXX If a TCB does not exist, and the TH_SYN flag is * the only flag set, then create a session, mark it * as if it was LISTENING, and continue... */ if (so == 0) { - if ((tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) != TH_SYN) - goto dropwithreset; - - if ((so = socreate()) == NULL) - goto dropwithreset; - if (tcp_attach(so) < 0) { - free(so); /* Not sofree (if it failed, it's not insqued) */ - goto dropwithreset; - } - - sbreserve(&so->so_snd, tcp_sndspace); - sbreserve(&so->so_rcv, tcp_rcvspace); - - /* tcp_last_so = so; */ /* XXX ? */ - /* tp = sototcpcb(so); */ - - so->so_laddr = ti->ti_src; - so->so_lport = ti->ti_sport; - so->so_faddr = ti->ti_dst; - so->so_fport = ti->ti_dport; - - if ((so->so_iptos = tcp_tos(so)) == 0) - so->so_iptos = ((struct ip *)ti)->ip_tos; - - tp = sototcpcb(so); - tp->t_state = TCPS_LISTEN; + if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN) + goto dropwithreset; + + if ((so = socreate()) == NULL) + goto dropwithreset; + if (tcp_attach(so) < 0) { + free(so); /* Not sofree (if it failed, it's not insqued) */ + goto dropwithreset; + } + + sbreserve(&so->so_snd, tcp_sndspace); + sbreserve(&so->so_rcv, tcp_rcvspace); + + /* tcp_last_so = so; */ /* XXX ? */ + /* tp = sototcpcb(so); */ + + so->so_laddr = ti->ti_src; + so->so_lport = ti->ti_sport; + so->so_faddr = ti->ti_dst; + so->so_fport = ti->ti_dport; + + if ((so->so_iptos = tcp_tos(so)) == 0) + so->so_iptos = ((struct ip *)ti)->ip_tos; + + tp = sototcpcb(so); + tp->t_state = TCPS_LISTEN; } - - /* - * If this is a still-connecting socket, this probably - * a retransmit of the SYN. Whether it's a retransmit SYN - * or something else, we nuke it. - */ - if (so->so_state & SS_ISFCONNECTING) - goto drop; + + /* + * If this is a still-connecting socket, this probably + * a retransmit of the SYN. Whether it's a retransmit SYN + * or something else, we nuke it. + */ + if (so->so_state & SS_ISFCONNECTING) + goto drop; tp = sototcpcb(so); - + /* XXX Should never fail */ if (tp == 0) goto dropwithreset; if (tp->t_state == TCPS_CLOSED) goto drop; - + /* Unscale the window into a 32-bit value. */ /* if ((tiflags & TH_SYN) == 0) * tiwin = ti->ti_win << tp->snd_scale; * else */ - tiwin = ti->ti_win; + tiwin = ti->ti_win; /* * Segment received on connection. @@ -441,66 +446,66 @@ void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) */ tp->t_idle = 0; if (so_options) - tp->t_timer[TCPT_KEEP] = tcp_keepintvl; + tp->t_timer[TCPT_KEEP] = tcp_keepintvl; else - tp->t_timer[TCPT_KEEP] = tcp_keepidle; + tp->t_timer[TCPT_KEEP] = tcp_keepidle; /* * Process options if not in LISTEN state, * else do it below (after getting remote address). */ if (optp && tp->t_state != TCPS_LISTEN) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); - /* , */ - /* &ts_present, &ts_val, &ts_ecr); */ - - /* - * Header prediction: check for the two common cases - * of a uni-directional data xfer. If the packet has - * no control flags, is in-sequence, the window didn't - * change and we're not retransmitting, it's a - * candidate. If the length is zero and the ack moved - * forward, we're the sender side of the xfer. Just - * free the data acked & wake any higher level process - * that was blocked waiting for space. If the length - * is non-zero and the ack didn't move, we're the - * receiver side. If we're getting packets in-order - * (the reassembly queue is empty), add the data to - * the socket buffer and note that we need a delayed ack. - * - * XXX Some of these tests are not needed - * eg: the tiwin == tp->snd_wnd prevents many more - * predictions.. with no *real* advantage.. - */ + tcp_dooptions(tp, (u_char *)optp, optlen, ti); +/* , */ +/* &ts_present, &ts_val, &ts_ecr); */ + + /* + * Header prediction: check for the two common cases + * of a uni-directional data xfer. If the packet has + * no control flags, is in-sequence, the window didn't + * change and we're not retransmitting, it's a + * candidate. If the length is zero and the ack moved + * forward, we're the sender side of the xfer. Just + * free the data acked & wake any higher level process + * that was blocked waiting for space. If the length + * is non-zero and the ack didn't move, we're the + * receiver side. If we're getting packets in-order + * (the reassembly queue is empty), add the data to + * the socket buffer and note that we need a delayed ack. + * + * XXX Some of these tests are not needed + * eg: the tiwin == tp->snd_wnd prevents many more + * predictions.. with no *real* advantage.. + */ if (tp->t_state == TCPS_ESTABLISHED && - (tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK && - /* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ - ti->ti_seq == tp->rcv_nxt && - tiwin && tiwin == tp->snd_wnd && - tp->snd_nxt == tp->snd_max) { - /* + (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && +/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ + ti->ti_seq == tp->rcv_nxt && + tiwin && tiwin == tp->snd_wnd && + tp->snd_nxt == tp->snd_max) { + /* * If last ACK falls within this segment's sequence numbers, * record the timestamp. */ - /* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ +/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && + * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { + * tp->ts_recent_age = tcp_now; + * tp->ts_recent = ts_val; + * } + */ if (ti->ti_len == 0) { if (SEQ_GT(ti->ti_ack, tp->snd_una) && - SEQ_LEQ(ti->ti_ack, tp->snd_max) && - tp->snd_cwnd >= tp->snd_wnd) { + SEQ_LEQ(ti->ti_ack, tp->snd_max) && + tp->snd_cwnd >= tp->snd_wnd) { /* * this is a pure ack for outstanding data. */ ++tcpstat.tcps_predack; - /* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ if (tp->t_rtt && -SEQ_GT(ti->ti_ack, tp->t_rtseq)) +/* if (ts_present) + * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); + * else + */ if (tp->t_rtt && + SEQ_GT(ti->ti_ack, tp->t_rtseq)) tcp_xmit_timer(tp, tp->t_rtt); acked = ti->ti_ack - tp->snd_una; tcpstat.tcps_rcvackpack++; @@ -523,27 +528,26 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) else if (tp->t_timer[TCPT_PERSIST] == 0) tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; - /* + /* * There's room in so_snd, sowwakup will read() * from the socket if we can */ - /* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ - /* - * This is called because sowwakeup might have - * put data into so_snd. Since we don't so sowwakeup, - * we don't need this.. XXX??? - */ +/* if (so->so_snd.sb_flags & SB_NOTIFY) + * sowwakeup(so); + */ + /* + * This is called because sowwakeup might have + * put data into so_snd. Since we don't so sowwakeup, + * we don't need this.. XXX??? + */ if (so->so_snd.sb_cc) (void) tcp_output(tp); return; } - } - else if (ti->ti_ack == tp->snd_una && - tp->seg_next == (tcpiphdrp_32)tp && - ti->ti_len <= sbspace(&so->so_rcv)) { + } else if (ti->ti_ack == tp->snd_una && + tcpfrag_list_empty(tp) && + ti->ti_len <= sbspace(&so->so_rcv)) { /* * this is a pure, in-sequence data packet * with nothing on the reassembly queue and @@ -557,26 +561,25 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * Add data to socket buffer. */ if (so->so_emu) { - if (tcp_emu(so, m)) sbappend(so, m); - } - else + if (tcp_emu(so,m)) sbappend(so, m); + } else sbappend(so, m); - - /* + + /* * XXX This is called when data arrives. Later, check * if we can actually write() to the socket * XXX Need to check? It's be NON_BLOCKING */ - /* sorwakeup(so); */ - - /* - * If this is a short packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * It is better to not delay acks at all to maximize - * TCP throughput. See RFC 2581. - */ +/* sorwakeup(so); */ + + /* + * If this is a short packet, then ACK now - with Nagel + * congestion avoidance sender won't send more until + * he gets an ACK. + * + * It is better to not delay acks at all to maximize + * TCP throughput. See RFC 2581. + */ tp->t_flags |= TF_ACKNOW; tcp_output(tp); return; @@ -589,147 +592,141 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * but not less than advertised window. */ { int win; - win = sbspace(&so->so_rcv); - if (win < 0) - win = 0; - tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); + win = sbspace(&so->so_rcv); + if (win < 0) + win = 0; + tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); } switch (tp->t_state) { - /* - * If the state is LISTEN then ignore segment if it contains an RST. - * If the segment contains an ACK then it is bad and send a RST. - * If it does not contain a SYN then it is not interesting; drop it. - * Don't bother responding if the destination was a broadcast. - * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial - * tp->iss, and send a segment: - * - * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. - * Fill in remote peer address fields if not previously specified. - * Enter SYN_RECEIVED state, and process any other fields of this - * segment in this state. - */ + /* + * If the state is LISTEN then ignore segment if it contains an RST. + * If the segment contains an ACK then it is bad and send a RST. + * If it does not contain a SYN then it is not interesting; drop it. + * Don't bother responding if the destination was a broadcast. + * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial + * tp->iss, and send a segment: + * + * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. + * Fill in remote peer address fields if not previously specified. + * Enter SYN_RECEIVED state, and process any other fields of this + * segment in this state. + */ case TCPS_LISTEN: { - if (tiflags & TH_RST) - goto drop; - if (tiflags & TH_ACK) - goto dropwithreset; - if ((tiflags & TH_SYN) == 0) - goto drop; - - /* - * This has way too many gotos... - * But a bit of spaghetti code never hurt anybody :) - */ - - /* - * If this is destined for the control address, then flag to - * tcp_ctl once connected, otherwise connect - */ - if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { - int lastbyte = ntohl(so->so_faddr.s_addr) & 0xff; - if (lastbyte != CTL_ALIAS && lastbyte != CTL_DNS) { + if (tiflags & TH_RST) + goto drop; + if (tiflags & TH_ACK) + goto dropwithreset; + if ((tiflags & TH_SYN) == 0) + goto drop; + + /* + * This has way too many gotos... + * But a bit of spaghetti code never hurt anybody :) + */ + + /* + * If this is destined for the control address, then flag to + * tcp_ctl once connected, otherwise connect + */ + if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { + int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff; + if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) { #if 0 - if (lastbyte == CTL_CMD || lastbyte == CTL_EXEC) { - /* Command or exec adress */ - so->so_state |= SS_CTL; - } - else + if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { + /* Command or exec adress */ + so->so_state |= SS_CTL; + } else #endif - { - /* May be an add exec */ - struct ex_list *ex_ptr; - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_fport == so->so_fport && - lastbyte == ex_ptr->ex_addr) { - so->so_state |= SS_CTL; - break; - } - } - } - if (so->so_state & SS_CTL) goto cont_input; - } - /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ - } - - if (so->so_emu & EMU_NOCONNECT) { - so->so_emu &= ~EMU_NOCONNECT; - goto cont_input; - } - - if (tcp_fconnect(so) == -1) { - int error = WSAGetLastError(); - if ((error != WSAEINPROGRESS) && (error != WSAEWOULDBLOCK)) { - u_char code = ICMP_UNREACH_NET; - DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n", - errno, strerror(errno))); - if (error == WSAECONNREFUSED) { - /* ACK the SYN, send RST to refuse the connection */ - tcp_respond(tp, ti, m, ti->ti_seq + 1, (tcp_seq)0, - TH_RST | TH_ACK); - } - else { - if (error == WSAEHOSTUNREACH) code = ICMP_UNREACH_HOST; - HTONL(ti->ti_seq); /* restore tcp header */ - HTONL(ti->ti_ack); - HTONS(ti->ti_win); - HTONS(ti->ti_urp); - m->m_data -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - m->m_len += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); - *ip = save_ip; - icmp_error(m, ICMP_UNREACH, code, 0, strerror(errno)); - } - tp = tcp_close(tp); - m_free(m); - return; - } - } - - /* - * Haven't connected yet, save the current mbuf - * and ti, and return - * XXX Some OS's don't tell us whether the connect() - * succeeded or not. So we must time it out. - */ - so->so_m = m; - so->so_ti = ti; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->t_state = TCPS_SYN_RECEIVED; - return; - - cont_conn: - /* m==NULL - * Check if the connect succeeded - */ - if (so->so_state & SS_NOFDREF) { - tp = tcp_close(tp); - goto dropwithreset; + { + /* May be an add exec */ + struct ex_list *ex_ptr; + for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { + if(ex_ptr->ex_fport == so->so_fport && + lastbyte == ex_ptr->ex_addr) { + so->so_state |= SS_CTL; + break; + } } - cont_input: - tcp_template(tp); - - if (optp) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); - /* , */ - /* &ts_present, &ts_val, &ts_ecr); */ - - if (iss) - tp->iss = iss; - else - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR / 2; - tp->irs = ti->ti_seq; - tcp_sendseqinit(tp); - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - tp->t_state = TCPS_SYN_RECEIVED; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tcpstat.tcps_accepts++; - goto trimthenstep6; + } + if(so->so_state & SS_CTL) goto cont_input; + } + /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ + } + + if (so->so_emu & EMU_NOCONNECT) { + so->so_emu &= ~EMU_NOCONNECT; + goto cont_input; + } + + if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { + u_char code=ICMP_UNREACH_NET; + DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", + errno,strerror(errno))); + if(errno == ECONNREFUSED) { + /* ACK the SYN, send RST to refuse the connection */ + tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0, + TH_RST|TH_ACK); + } else { + if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; + HTONL(ti->ti_seq); /* restore tcp header */ + HTONL(ti->ti_ack); + HTONS(ti->ti_win); + HTONS(ti->ti_urp); + m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + *ip=save_ip; + icmp_error(m, ICMP_UNREACH,code, 0,strerror(errno)); + } + tp = tcp_close(tp); + m_free(m); + } else { + /* + * Haven't connected yet, save the current mbuf + * and ti, and return + * XXX Some OS's don't tell us whether the connect() + * succeeded or not. So we must time it out. + */ + so->so_m = m; + so->so_ti = ti; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tp->t_state = TCPS_SYN_RECEIVED; + } + return; + + cont_conn: + /* m==NULL + * Check if the connect succeeded + */ + if (so->so_state & SS_NOFDREF) { + tp = tcp_close(tp); + goto dropwithreset; + } + cont_input: + tcp_template(tp); + + if (optp) + tcp_dooptions(tp, (u_char *)optp, optlen, ti); + /* , */ + /* &ts_present, &ts_val, &ts_ecr); */ + + if (iss) + tp->iss = iss; + else + tp->iss = tcp_iss; + tcp_iss += TCP_ISSINCR/2; + tp->irs = ti->ti_seq; + tcp_sendseqinit(tp); + tcp_rcvseqinit(tp); + tp->t_flags |= TF_ACKNOW; + tp->t_state = TCPS_SYN_RECEIVED; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tcpstat.tcps_accepts++; + goto trimthenstep6; } /* case TCPS_LISTEN */ - + /* * If the state is SYN_SENT: * if seg contains an ACK, but not for our SYN, drop the input. @@ -744,13 +741,13 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) */ case TCPS_SYN_SENT: if ((tiflags & TH_ACK) && - (SEQ_LEQ(ti->ti_ack, tp->iss) || - SEQ_GT(ti->ti_ack, tp->snd_max))) + (SEQ_LEQ(ti->ti_ack, tp->iss) || + SEQ_GT(ti->ti_ack, tp->snd_max))) goto dropwithreset; if (tiflags & TH_RST) { if (tiflags & TH_ACK) - tp = tcp_drop(tp, 0); /* XXX Check t_softerror! */ + tp = tcp_drop(tp,0); /* XXX Check t_softerror! */ goto drop; } @@ -770,7 +767,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) tcpstat.tcps_connects++; soisfconnected(so); tp->t_state = TCPS_ESTABLISHED; - + /* Do window scaling on this connection? */ /* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == * (TF_RCVD_SCALE|TF_REQ_SCALE)) { @@ -778,7 +775,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * tp->rcv_scale = tp->request_r_scale; * } */ - (void)tcp_reass(tp, (struct tcpiphdr *)0, + (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); /* * if we didn't have to retransmit the SYN, @@ -786,11 +783,10 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) */ if (tp->t_rtt) tcp_xmit_timer(tp, tp->t_rtt); - } - else + } else tp->t_state = TCPS_SYN_RECEIVED; - trimthenstep6: +trimthenstep6: /* * Advance ti->ti_seq to correspond to first data byte. * If data, trim to stay within window, @@ -812,45 +808,45 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) /* * States other than LISTEN or SYN_SENT. * First check timestamp, if present. - * Then check that at least some bytes of segment are within + * Then check that at least some bytes of segment are within * receive window. If segment begins before rcv_nxt, * drop leading data (and SYN); if nothing left, just ack. - * + * * RFC 1323 PAWS: If we have a timestamp reply on this segment * and it's less than ts_recent, drop it. */ - /* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && - * TSTMP_LT(ts_val, tp->ts_recent)) { - * - */ /* Check to see if ts_recent is over 24 days old. */ - /* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { - */ /* - * * Invalidate ts_recent. If this segment updates - * * ts_recent, the age will be reset later and ts_recent - * * will get a valid value. If it does not, setting - * * ts_recent to zero will at least satisfy the - * * requirement that zero be placed in the timestamp - * * echo reply when ts_recent isn't valid. The - * * age isn't reset until we get a valid ts_recent - * * because we don't want out-of-order segments to be - * * dropped when ts_recent is old. - * */ - /* tp->ts_recent = 0; - * } else { - * tcpstat.tcps_rcvduppack++; - * tcpstat.tcps_rcvdupbyte += ti->ti_len; - * tcpstat.tcps_pawsdrop++; - * goto dropafterack; - * } - * } - */ +/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && + * TSTMP_LT(ts_val, tp->ts_recent)) { + * + */ /* Check to see if ts_recent is over 24 days old. */ +/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { + */ /* + * * Invalidate ts_recent. If this segment updates + * * ts_recent, the age will be reset later and ts_recent + * * will get a valid value. If it does not, setting + * * ts_recent to zero will at least satisfy the + * * requirement that zero be placed in the timestamp + * * echo reply when ts_recent isn't valid. The + * * age isn't reset until we get a valid ts_recent + * * because we don't want out-of-order segments to be + * * dropped when ts_recent is old. + * */ +/* tp->ts_recent = 0; + * } else { + * tcpstat.tcps_rcvduppack++; + * tcpstat.tcps_rcvdupbyte += ti->ti_len; + * tcpstat.tcps_pawsdrop++; + * goto dropafterack; + * } + * } + */ todrop = tp->rcv_nxt - ti->ti_seq; if (todrop > 0) { if (tiflags & TH_SYN) { tiflags &= ~TH_SYN; ti->ti_seq++; - if (ti->ti_urp > 1) + if (ti->ti_urp > 1) ti->ti_urp--; else tiflags &= ~TH_URG; @@ -860,14 +856,14 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * Following if statement from Stevens, vol. 2, p. 960. */ if (todrop > ti->ti_len - || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { + || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { /* * Any valid FIN must be to the left of the window. * At this point the FIN must be a duplicate or out * of sequence; drop it. */ tiflags &= ~TH_FIN; - + /* * Send an ACK to resynchronize and drop any data. * But keep on processing for RST or ACK. @@ -876,8 +872,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) todrop = ti->ti_len; tcpstat.tcps_rcvduppack++; tcpstat.tcps_rcvdupbyte += todrop; - } - else { + } else { tcpstat.tcps_rcvpartduppack++; tcpstat.tcps_rcvpartdupbyte += todrop; } @@ -896,7 +891,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * user processes are gone, then RST the other end. */ if ((so->so_state & SS_NOFDREF) && - tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { + tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { tp = tcp_close(tp); tcpstat.tcps_rcvafterclose++; goto dropwithreset; @@ -906,7 +901,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * If segment ends after window, drop trailing data * (and PUSH and FIN); if nothing left, just ACK. */ - todrop = (ti->ti_seq + ti->ti_len) - (tp->rcv_nxt + tp->rcv_wnd); + todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); if (todrop > 0) { tcpstat.tcps_rcvpackafterwin++; if (todrop >= ti->ti_len) { @@ -918,8 +913,8 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * are above the previous ones. */ if (tiflags & TH_SYN && - tp->t_state == TCPS_TIME_WAIT && - SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { + tp->t_state == TCPS_TIME_WAIT && + SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { iss = tp->rcv_nxt + TCP_ISSINCR; tp = tcp_close(tp); goto findso; @@ -934,55 +929,53 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { tp->t_flags |= TF_ACKNOW; tcpstat.tcps_rcvwinprobe++; - } - else + } else goto dropafterack; - } - else + } else tcpstat.tcps_rcvbyteafterwin += todrop; m_adj(m, -todrop); ti->ti_len -= todrop; - tiflags &= ~(TH_PUSH | TH_FIN); + tiflags &= ~(TH_PUSH|TH_FIN); } /* * If last ACK falls within this segment's sequence numbers, * record its timestamp. */ - /* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + - * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ +/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && + * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + + * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { + * tp->ts_recent_age = tcp_now; + * tp->ts_recent = ts_val; + * } + */ - /* - * If the RST bit is set examine the state: - * SYN_RECEIVED STATE: - * If passive open, return to LISTEN state. - * If active open, inform user that connection was refused. - * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: - * Inform user that connection was reset, and close tcb. - * CLOSING, LAST_ACK, TIME_WAIT STATES - * Close the tcb. - */ + /* + * If the RST bit is set examine the state: + * SYN_RECEIVED STATE: + * If passive open, return to LISTEN state. + * If active open, inform user that connection was refused. + * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: + * Inform user that connection was reset, and close tcb. + * CLOSING, LAST_ACK, TIME_WAIT STATES + * Close the tcb. + */ if (tiflags&TH_RST) switch (tp->t_state) { case TCPS_SYN_RECEIVED: - /* so->so_error = ECONNREFUSED; */ +/* so->so_error = ECONNREFUSED; */ goto close; case TCPS_ESTABLISHED: case TCPS_FIN_WAIT_1: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: - /* so->so_error = ECONNRESET; */ - close: - tp->t_state = TCPS_CLOSED; - tcpstat.tcps_drops++; - tp = tcp_close(tp); - goto drop; +/* so->so_error = ECONNRESET; */ + close: + tp->t_state = TCPS_CLOSED; + tcpstat.tcps_drops++; + tp = tcp_close(tp); + goto drop; case TCPS_CLOSING: case TCPS_LAST_ACK: @@ -996,7 +989,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * error and we send an RST and drop the connection. */ if (tiflags & TH_SYN) { - tp = tcp_drop(tp, 0); + tp = tcp_drop(tp,0); goto dropwithreset; } @@ -1009,45 +1002,42 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * Ack processing. */ switch (tp->t_state) { - /* - * In SYN_RECEIVED state if the ack ACKs our SYN then enter - * ESTABLISHED state and continue processing, otherwise - * send an RST. una<=ack<=max - */ + /* + * In SYN_RECEIVED state if the ack ACKs our SYN then enter + * ESTABLISHED state and continue processing, otherwise + * send an RST. una<=ack<=max + */ case TCPS_SYN_RECEIVED: if (SEQ_GT(tp->snd_una, ti->ti_ack) || - SEQ_GT(ti->ti_ack, tp->snd_max)) + SEQ_GT(ti->ti_ack, tp->snd_max)) goto dropwithreset; tcpstat.tcps_connects++; tp->t_state = TCPS_ESTABLISHED; - /* - * The sent SYN is ack'ed with our sequence number +1 - * The first data byte already in the buffer will get + /* + * The sent SYN is ack'ed with our sequence number +1 + * The first data byte already in the buffer will get * lost if no correction is made. This is only needed for * SS_CTL since the buffer is empty otherwise. - * tp->snd_una++; or: + * tp->snd_una++; or: */ - tp->snd_una = ti->ti_ack; + tp->snd_una=ti->ti_ack; if (so->so_state & SS_CTL) { - /* So tcp_ctl reports the right state */ - ret = tcp_ctl(so); - if (ret == 1) { - soisfconnected(so); - so->so_state &= ~SS_CTL; /* success XXX */ - } - else if (ret == 2) { - so->so_state = SS_NOFDREF; /* CTL_CMD */ - } - else { - needoutput = 1; - tp->t_state = TCPS_FIN_WAIT_1; - } - } - else { - soisfconnected(so); + /* So tcp_ctl reports the right state */ + ret = tcp_ctl(so); + if (ret == 1) { + soisfconnected(so); + so->so_state &= ~SS_CTL; /* success XXX */ + } else if (ret == 2) { + so->so_state = SS_NOFDREF; /* CTL_CMD */ + } else { + needoutput = 1; + tp->t_state = TCPS_FIN_WAIT_1; + } + } else { + soisfconnected(so); } - + /* Do window scaling? */ /* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == * (TF_RCVD_SCALE|TF_REQ_SCALE)) { @@ -1055,7 +1045,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * tp->rcv_scale = tp->request_r_scale; * } */ - (void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); + (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); tp->snd_wl1 = ti->ti_seq - 1; /* Avoid ack processing; snd_una==ti_ack => dup ack */ goto synrx_to_est; @@ -1079,9 +1069,9 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - tcpstat.tcps_rcvdupack++; - DEBUG_MISC((dfd, " dup ack m = %lx so = %lx \n", - (long)m, (long)so)); + tcpstat.tcps_rcvdupack++; + DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", + (long )m, (long )so)); /* * If we have outstanding data (other than * a window probe), this is a completely @@ -1101,18 +1091,18 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * the new ssthresh). * * Dup acks mean that packets have left the - * network (they're now cached at the receiver) + * network (they're now cached at the receiver) * so bump cwnd by the amount in the receiver * to keep a constant cwnd packets in the * network. */ if (tp->t_timer[TCPT_REXMT] == 0 || - ti->ti_ack != tp->snd_una) + ti->ti_ack != tp->snd_una) tp->t_dupacks = 0; else if (++tp->t_dupacks == tcprexmtthresh) { tcp_seq onxt = tp->snd_nxt; u_int win = - min(tp->snd_wnd, tp->snd_cwnd) / 2 / + min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; if (win < 2) @@ -1122,20 +1112,18 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) tp->t_rtt = 0; tp->snd_nxt = ti->ti_ack; tp->snd_cwnd = tp->t_maxseg; - (void)tcp_output(tp); + (void) tcp_output(tp); tp->snd_cwnd = tp->snd_ssthresh + - tp->t_maxseg * tp->t_dupacks; + tp->t_maxseg * tp->t_dupacks; if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; - } - else if (tp->t_dupacks > tcprexmtthresh) { + } else if (tp->t_dupacks > tcprexmtthresh) { tp->snd_cwnd += tp->t_maxseg; - (void)tcp_output(tp); + (void) tcp_output(tp); goto drop; } - } - else + } else tp->t_dupacks = 0; break; } @@ -1145,7 +1133,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * for the other side's cached packets, retract it. */ if (tp->t_dupacks > tcprexmtthresh && - tp->snd_cwnd > tp->snd_ssthresh) + tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; tp->t_dupacks = 0; if (SEQ_GT(ti->ti_ack, tp->snd_max)) { @@ -1165,12 +1153,12 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * timer backoff (cf., Phil Karn's retransmit alg.). * Recompute the initial retransmit timer. */ - /* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ - if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp, tp->t_rtt); +/* if (ts_present) + * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); + * else + */ + if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) + tcp_xmit_timer(tp,tp->t_rtt); /* * If all outstanding data is acked, stop retransmit @@ -1181,8 +1169,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) if (ti->ti_ack == tp->snd_max) { tp->t_timer[TCPT_REXMT] = 0; needoutput = 1; - } - else if (tp->t_timer[TCPT_PERSIST] == 0) + } else if (tp->t_timer[TCPT_PERSIST] == 0) tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; /* * When new data is acked, open the congestion window. @@ -1192,41 +1179,40 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * (maxseg^2 / cwnd per packet). */ { - register u_int cw = tp->snd_cwnd; - register u_int incr = tp->t_maxseg; + register u_int cw = tp->snd_cwnd; + register u_int incr = tp->t_maxseg; - if (cw > tp->snd_ssthresh) - incr = incr * incr / cw; - tp->snd_cwnd = min(cw + incr, (u_int32_t) (TCP_MAXWIN << tp->snd_scale)); + if (cw > tp->snd_ssthresh) + incr = incr * incr / cw; + tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<snd_scale); } if (acked > so->so_snd.sb_cc) { tp->snd_wnd -= so->so_snd.sb_cc; - sbdrop(&so->so_snd, so->so_snd.sb_cc); + sbdrop(&so->so_snd, (int )so->so_snd.sb_cc); ourfinisacked = 1; - } - else { + } else { sbdrop(&so->so_snd, acked); tp->snd_wnd -= acked; ourfinisacked = 0; } /* * XXX sowwakup is called when data is acked and there's room for - * for more data... it should read() the socket + * for more data... it should read() the socket */ - /* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ +/* if (so->so_snd.sb_flags & SB_NOTIFY) + * sowwakeup(so); + */ tp->snd_una = ti->ti_ack; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; switch (tp->t_state) { - /* - * In FIN_WAIT_1 STATE in addition to the processing - * for the ESTABLISHED state if our FIN is now acknowledged - * then enter FIN_WAIT_2. - */ + /* + * In FIN_WAIT_1 STATE in addition to the processing + * for the ESTABLISHED state if our FIN is now acknowledged + * then enter FIN_WAIT_2. + */ case TCPS_FIN_WAIT_1: if (ourfinisacked) { /* @@ -1244,12 +1230,12 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) } break; - /* - * In CLOSING STATE in addition to the processing for - * the ESTABLISHED state if the ACK acknowledges our FIN - * then enter the TIME-WAIT state, otherwise ignore - * the segment. - */ + /* + * In CLOSING STATE in addition to the processing for + * the ESTABLISHED state if the ACK acknowledges our FIN + * then enter the TIME-WAIT state, otherwise ignore + * the segment. + */ case TCPS_CLOSING: if (ourfinisacked) { tp->t_state = TCPS_TIME_WAIT; @@ -1259,12 +1245,12 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) } break; - /* - * In LAST_ACK, we may still be waiting for data to drain - * and/or to be acked, as well as for the ack of our FIN. - * If our FIN is now acknowledged, delete the TCB, - * enter the closed state and return. - */ + /* + * In LAST_ACK, we may still be waiting for data to drain + * and/or to be acked, as well as for the ack of our FIN. + * If our FIN is now acknowledged, delete the TCB, + * enter the closed state and return. + */ case TCPS_LAST_ACK: if (ourfinisacked) { tp = tcp_close(tp); @@ -1272,11 +1258,11 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) } break; - /* - * In TIME_WAIT state the only thing that should arrive - * is a retransmission of the remote FIN. Acknowledge - * it and restart the finack timer. - */ + /* + * In TIME_WAIT state the only thing that should arrive + * is a retransmission of the remote FIN. Acknowledge + * it and restart the finack timer. + */ case TCPS_TIME_WAIT: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; goto dropafterack; @@ -1289,12 +1275,12 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * Don't look at window if no ACK: TAC's send garbage on first SYN. */ if ((tiflags & TH_ACK) && - (SEQ_LT(tp->snd_wl1, ti->ti_seq) || - (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || - (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { + (SEQ_LT(tp->snd_wl1, ti->ti_seq) || + (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || + (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ if (ti->ti_len == 0 && - tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) + tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) tcpstat.tcps_rcvwinupd++; tp->snd_wnd = tiwin; tp->snd_wl1 = ti->ti_seq; @@ -1308,7 +1294,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * Process segments with URG. */ if ((tiflags & TH_URG) && ti->ti_urp && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { + TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* * This is a kludge, but if we receive and accept * random urgent pointers, we'll crash in @@ -1324,32 +1310,31 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * If this segment advances the known urgent pointer, * then mark the data stream. This should not happen * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since - * a FIN has been received from the remote side. + * a FIN has been received from the remote side. * In these states we ignore the URG. * * According to RFC961 (Assigned Protocols), * the urgent pointer points to the last octet * of urgent data. We continue, however, * to consider it to indicate the first octet - * of data past the urgent section as the original + * of data past the urgent section as the original * spec states (in one of two places). */ - if (SEQ_GT(ti->ti_seq + ti->ti_urp, tp->rcv_up)) { + if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { tp->rcv_up = ti->ti_seq + ti->ti_urp; - so->so_urgc = so->so_rcv.sb_cc + + so->so_urgc = so->so_rcv.sb_cc + (tp->rcv_up - tp->rcv_nxt); /* -1; */ tp->rcv_up = ti->ti_seq + ti->ti_urp; - + } - } - else + } else /* * If no out of band data is expected, * pull receive urgent pointer along * with the receive window. */ if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) - tp->rcv_up = tp->rcv_nxt; + tp->rcv_up = tp->rcv_nxt; dodata: /* @@ -1361,7 +1346,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * connection then we just ignore the text. */ if ((ti->ti_len || (tiflags&TH_FIN)) && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { + TCPS_HAVERCVDFIN(tp->t_state) == 0) { TCP_REASS(tp, ti, m, so, tiflags); /* * Note the amount of data that peer has sent into @@ -1369,8 +1354,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * buffer size. */ len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt); - } - else { + } else { m_free(m); tiflags &= ~TH_FIN; } @@ -1384,45 +1368,45 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) /* * If we receive a FIN we can't send more data, * set it SS_FDRAIN - * Shutdown the socket if there is no rx data in the + * Shutdown the socket if there is no rx data in the * buffer. * soread() is called on completion of shutdown() and * will got to TCPS_LAST_ACK, and use tcp_output() * to send the FIN. */ - /* sofcantrcvmore(so); */ +/* sofcantrcvmore(so); */ sofwdrain(so); - + tp->t_flags |= TF_ACKNOW; tp->rcv_nxt++; } switch (tp->t_state) { - /* - * In SYN_RECEIVED and ESTABLISHED STATES - * enter the CLOSE_WAIT state. - */ + /* + * In SYN_RECEIVED and ESTABLISHED STATES + * enter the CLOSE_WAIT state. + */ case TCPS_SYN_RECEIVED: case TCPS_ESTABLISHED: - if (so->so_emu == EMU_CTL) /* no shutdown on socket */ - tp->t_state = TCPS_LAST_ACK; - else - tp->t_state = TCPS_CLOSE_WAIT; - break; - - /* - * If still in FIN_WAIT_1 STATE FIN has not been acked so - * enter the CLOSING state. - */ + if(so->so_emu == EMU_CTL) /* no shutdown on socket */ + tp->t_state = TCPS_LAST_ACK; + else + tp->t_state = TCPS_CLOSE_WAIT; + break; + + /* + * If still in FIN_WAIT_1 STATE FIN has not been acked so + * enter the CLOSING state. + */ case TCPS_FIN_WAIT_1: tp->t_state = TCPS_CLOSING; break; - /* - * In FIN_WAIT_2 state enter the TIME_WAIT state, - * starting the time-wait timer, turning off the other - * standard timers. - */ + /* + * In FIN_WAIT_2 state enter the TIME_WAIT state, + * starting the time-wait timer, turning off the other + * standard timers. + */ case TCPS_FIN_WAIT_2: tp->t_state = TCPS_TIME_WAIT; tcp_canceltimers(tp); @@ -1430,9 +1414,9 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) soisfdisconnected(so); break; - /* - * In TIME_WAIT state restart the 2 MSL time_wait timer. - */ + /* + * In TIME_WAIT state restart the 2 MSL time_wait timer. + */ case TCPS_TIME_WAIT: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; break; @@ -1443,18 +1427,18 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * If this is a small packet, then ACK now - with Nagel * congestion avoidance sender won't send more until * he gets an ACK. - * + * * See above. */ - /* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { - */ - /* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && - * (so->so_iptos & IPTOS_LOWDELAY) == 0) || - * ((so->so_iptos & IPTOS_LOWDELAY) && - * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { - */ +/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { + */ +/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && + * (so->so_iptos & IPTOS_LOWDELAY) == 0) || + * ((so->so_iptos & IPTOS_LOWDELAY) && + * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { + */ if (ti->ti_len && (unsigned)ti->ti_len <= 5 && - ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { + ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { tp->t_flags |= TF_ACKNOW; } @@ -1462,7 +1446,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * Return any desired output. */ if (needoutput || (tp->t_flags & TF_ACKNOW)) { - (void)tcp_output(tp); + (void) tcp_output(tp); } return; @@ -1475,7 +1459,7 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) goto drop; m_freem(m); tp->t_flags |= TF_ACKNOW; - (void)tcp_output(tp); + (void) tcp_output(tp); return; dropwithreset: @@ -1484,8 +1468,8 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); else { if (tiflags & TH_SYN) ti->ti_len++; - tcp_respond(tp, ti, m, ti->ti_seq + ti->ti_len, (tcp_seq)0, - TH_RST | TH_ACK); + tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0, + TH_RST|TH_ACK); } return; @@ -1504,7 +1488,11 @@ SEQ_GT(ti->ti_ack, tp->t_rtseq)) * u_int32_t *ts_val, *ts_ecr; */ void -tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) +tcp_dooptions(tp, cp, cnt, ti) + struct tcpcb *tp; + u_char *cp; + int cnt; + struct tcpiphdr *ti; { u_int16_t mss; int opt, optlen; @@ -1535,7 +1523,7 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) continue; memcpy((char *) &mss, (char *) cp + 2, sizeof(mss)); NTOHS(mss); - tcp_mss(tp, mss); /* sets t_maxseg */ + (void) tcp_mss(tp, mss); /* sets t_maxseg */ break; /* case TCPOPT_WINDOW: @@ -1580,7 +1568,11 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) #ifdef notdef -void tcp_pulloutofband(struct socket *so, struct tcpiphdr *ti, register struct mbuf *m) +void +tcp_pulloutofband(so, ti, m) + struct socket *so; + struct tcpiphdr *ti; + register struct mbuf *m; { int cnt = ti->ti_urp - 1; @@ -1610,7 +1602,10 @@ void tcp_pulloutofband(struct socket *so, struct tcpiphdr *ti, register struct m * and update averages and current timeout. */ -void tcp_xmit_timer(register struct tcpcb *tp, int rtt) +void +tcp_xmit_timer(tp, rtt) + register struct tcpcb *tp; + int rtt; { register short delta; @@ -1697,10 +1692,13 @@ void tcp_xmit_timer(register struct tcpcb *tp, int rtt) * parameters from pre-set or cached values in the routing entry. */ -u_int tcp_mss(register struct tcpcb *tp, u_int offer) +int +tcp_mss(tp, offer) + register struct tcpcb *tp; + u_int offer; { struct socket *so = tp->t_socket; - u_int mss; + int mss; DEBUG_CALL("tcp_mss"); DEBUG_ARG("tp = %lx", (long)tp); diff --git a/BasiliskII/src/slirp/tcp_output.c b/BasiliskII/src/slirp/tcp_output.c old mode 100644 new mode 100755 index 01df0118f..5cb1a61e3 --- a/BasiliskII/src/slirp/tcp_output.c +++ b/BasiliskII/src/slirp/tcp_output.c @@ -63,7 +63,9 @@ u_char tcp_outflags[TCP_NSTATES] = { /* * Tcp output routine: figure out what should be sent and send it. */ -int tcp_output(register struct tcpcb *tp) +int +tcp_output(tp) + register struct tcpcb *tp; { register struct socket *so = tp->t_socket; register long len, win; @@ -124,7 +126,7 @@ int tcp_output(register struct tcpcb *tp) * to send then the probe will be the FIN * itself. */ - if (off < (int)so->so_snd.sb_cc) + if (off < so->so_snd.sb_cc) flags &= ~TH_FIN; win = 1; } else { @@ -199,12 +201,12 @@ int tcp_output(register struct tcpcb *tp) * taking into account that we are limited by * TCP_MAXWIN << tp->rcv_scale. */ - long adv = min(win, TCP_MAXWIN << tp->rcv_scale) - + long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - (tp->rcv_adv - tp->rcv_nxt); - if (adv >= (long)(2 * tp->t_maxseg)) + if (adv >= (long) (2 * tp->t_maxseg)) goto send; - if (2 * adv >= (long)so->so_rcv.sb_datalen) + if (2 * adv >= (long) so->so_rcv.sb_datalen) goto send; } @@ -357,7 +359,7 @@ int tcp_output(register struct tcpcb *tp) */ /* if (len <= MHLEN - hdrlen - max_linkhdr) { */ - sbcopy(&so->so_snd, off, len, mtod(m, caddr_t) + hdrlen); + sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen); m->m_len += len; /* } else { @@ -433,12 +435,12 @@ int tcp_output(register struct tcpcb *tp) * Calculate receive window. Don't shrink window, * but avoid silly window syndrome. */ - if (win < (so->so_rcv.sb_datalen / 4) && win < tp->t_maxseg) + if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) win = 0; - if (win > (u_long) (TCP_MAXWIN << tp->rcv_scale)) - win = (u_long) (TCP_MAXWIN << tp->rcv_scale); - if (win < (tp->rcv_adv - tp->rcv_nxt)) - win = (tp->rcv_adv - tp->rcv_nxt); + if (win > (long)TCP_MAXWIN << tp->rcv_scale) + win = (long)TCP_MAXWIN << tp->rcv_scale; + if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) + win = (long)(tp->rcv_adv - tp->rcv_nxt); ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); if (SEQ_GT(tp->snd_up, tp->snd_una)) { @@ -528,7 +530,7 @@ int tcp_output(register struct tcpcb *tp) { - ((struct ip *)ti)->ip_len = (u_int16_t) m->m_len; + ((struct ip *)ti)->ip_len = m->m_len; ((struct ip *)ti)->ip_ttl = ip_defttl; ((struct ip *)ti)->ip_tos = so->so_iptos; @@ -579,7 +581,9 @@ int tcp_output(register struct tcpcb *tp) return (0); } -void tcp_setpersist(register struct tcpcb *tp) +void +tcp_setpersist(tp) + register struct tcpcb *tp; { int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; diff --git a/BasiliskII/src/slirp/tcp_subr.c b/BasiliskII/src/slirp/tcp_subr.c old mode 100644 new mode 100755 index 70e04b5ee..391350802 --- a/BasiliskII/src/slirp/tcp_subr.c +++ b/BasiliskII/src/slirp/tcp_subr.c @@ -46,13 +46,14 @@ int tcp_mssdflt = TCP_MSS; int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ -size_t tcp_rcvspace; /* You may want to change this */ -size_t tcp_sndspace; /* Keep small if you have an error prone link */ +int tcp_rcvspace; /* You may want to change this */ +int tcp_sndspace; /* Keep small if you have an error prone link */ /* * Tcp initialization */ -void tcp_init() +void +tcp_init() { tcp_iss = 1; /* wrong */ tcb.so_next = tcb.so_prev = &tcb; @@ -73,12 +74,14 @@ void tcp_init() * necessary when the connection is used. */ /* struct tcpiphdr * */ -void tcp_template(struct tcpcb *tp) +void +tcp_template(tp) + struct tcpcb *tp; { struct socket *so = tp->t_socket; register struct tcpiphdr *n = &tp->t_template; - n->ti_next = n->ti_prev = 0; + n->ti_mbuf = NULL; n->ti_x1 = 0; n->ti_pr = IPPROTO_TCP; n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); @@ -110,8 +113,13 @@ void tcp_template(struct tcpcb *tp) * In any case the ack and sequence number of the transmitted * segment are as specified by the parameters. */ -void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti, - register struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags) +void +tcp_respond(tp, ti, m, ack, seq, flags) + struct tcpcb *tp; + register struct tcpiphdr *ti; + register struct mbuf *m; + tcp_seq ack, seq; + int flags; { register int tlen; int win = 0; @@ -156,7 +164,7 @@ void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti, tlen += sizeof (struct tcpiphdr); m->m_len = tlen; - ti->ti_next = ti->ti_prev = 0; + ti->ti_mbuf = 0; ti->ti_x1 = 0; ti->ti_seq = htonl(seq); ti->ti_ack = htonl(ack); @@ -185,7 +193,9 @@ void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti, * empty reassembly queue and hooking it to the argument * protocol control block. */ -struct tcpcb *tcp_newtcpcb(struct socket *so) +struct tcpcb * +tcp_newtcpcb(so) + struct socket *so; { register struct tcpcb *tp; @@ -194,7 +204,7 @@ struct tcpcb *tcp_newtcpcb(struct socket *so) return ((struct tcpcb *)0); memset((char *) tp, 0, sizeof(struct tcpcb)); - tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; + tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; tp->t_maxseg = tcp_mssdflt; tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; @@ -258,7 +268,9 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err) * discard internet protocol block * wake up any sleepers */ -struct tcpcb *tcp_close(register struct tcpcb *tp) +struct tcpcb * +tcp_close(tp) + register struct tcpcb *tp; { register struct tcpiphdr *t; struct socket *so = tp->t_socket; @@ -268,11 +280,11 @@ struct tcpcb *tcp_close(register struct tcpcb *tp) DEBUG_ARG("tp = %lx", (long )tp); /* free the reassembly queue, if any */ - t = (struct tcpiphdr *) tp->seg_next; - while (t != (struct tcpiphdr *)tp) { - t = (struct tcpiphdr *)t->ti_next; - m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev); - remque_32((struct tcpiphdr *) t->ti_prev); + t = tcpfrag_list_first(tp); + while (!tcpfrag_list_end(t, tp)) { + t = tcpiphdr_next(t); + m = tcpiphdr_prev(t)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(t))); m_freem(m); } /* It's static */ @@ -294,7 +306,8 @@ struct tcpcb *tcp_close(register struct tcpcb *tp) return ((struct tcpcb *)0); } -void tcp_drain() +void +tcp_drain() { /* XXX */ } @@ -306,7 +319,10 @@ void tcp_drain() #ifdef notdef -void tcp_quench(int i, int errno) +void +tcp_quench(i, errno) + + int errno; { struct tcpcb *tp = intotcpcb(inp); @@ -330,7 +346,9 @@ void tcp_quench(int i, int errno) * for peer to send FIN or not respond to keep-alives, etc. * We can let the user exit from the close as soon as the FIN is acked. */ -void tcp_sockclosed(struct tcpcb *tp) +void +tcp_sockclosed(tp) + struct tcpcb *tp; { DEBUG_CALL("tcp_sockclosed"); @@ -371,7 +389,8 @@ void tcp_sockclosed(struct tcpcb *tp) * nonblocking. Connect returns after the SYN is sent, and does * not wait for ACK+SYN. */ -int tcp_fconnect(struct socket *so) +int tcp_fconnect(so) + struct socket *so; { int ret=0; @@ -404,12 +423,10 @@ int tcp_fconnect(struct socket *so) } else addr.sin_addr = so->so_faddr; addr.sin_port = so->so_fport; - - char addrstr[INET_ADDRSTRLEN]; + DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " "addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, - addrstr, sizeof(addrstr)))); + ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); /* We don't care what port we get */ ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); @@ -435,7 +452,9 @@ int tcp_fconnect(struct socket *so) * the time it gets to accept(), so... We simply accept * here and SYN the local-host. */ -void tcp_connect(struct socket *inso) +void +tcp_connect(inso) + struct socket *inso; { struct socket *so; struct sockaddr_in addr; @@ -467,7 +486,7 @@ void tcp_connect(struct socket *inso) so->so_lport = inso->so_lport; } - tcp_mss(sototcpcb(so), 0); + (void) tcp_mss(sototcpcb(so), 0); if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { tcp_close(sototcpcb(so)); /* This will sofree() as well */ @@ -520,7 +539,9 @@ void tcp_connect(struct socket *inso) /* * Attach a TCPCB to a socket. */ -int tcp_attach(struct socket *so) +int +tcp_attach(so) + struct socket *so; { if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) return -1; @@ -554,7 +575,9 @@ struct emu_t *tcpemu = 0; /* * Return TOS according to the above table */ -u_int8_t tcp_tos(struct socket *so) +u_int8_t +tcp_tos(so) + struct socket *so; { int i = 0; struct emu_t *emup; @@ -606,7 +629,10 @@ int do_echo = -1; * * NOTE: if you return 0 you MUST m_free() the mbuf! */ -int tcp_emu(struct socket *so, struct mbuf *m) +int +tcp_emu(so, m) + struct socket *so; + struct mbuf *m; { u_int n1, n2, n3, n4, n5, n6; char buff[256]; @@ -807,7 +833,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) ns->so_laddr=so->so_laddr; ns->so_lport=htons(port); - tcp_mss(sototcpcb(ns), 0); + (void) tcp_mss(sototcpcb(ns), 0); ns->so_faddr=so->so_faddr; ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ @@ -1034,7 +1060,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) * of the connection as a NUL-terminated decimal ASCII string. */ so->so_emu = 0; - for (lport = 0, i = 0; i < (int) (m->m_len-1); ++i) { + for (lport = 0, i = 0; i < m->m_len-1; ++i) { if (m->m_data[i] < '0' || m->m_data[i] > '9') return 1; /* invalid number */ lport *= 10; @@ -1219,7 +1245,9 @@ int tcp_emu(struct socket *so, struct mbuf *m) * Return 0 if this connections is to be closed, 1 otherwise, * return 2 if this is a command-line connection */ -int tcp_ctl(struct socket *so) +int +tcp_ctl(so) + struct socket *so; { struct sbuf *sb = &so->so_snd; int command; diff --git a/BasiliskII/src/slirp/tcp_timer.c b/BasiliskII/src/slirp/tcp_timer.c old mode 100644 new mode 100755 diff --git a/BasiliskII/src/slirp/tcp_timer.h b/BasiliskII/src/slirp/tcp_timer.h old mode 100644 new mode 100755 index 73fe20894..0bc438c76 --- a/BasiliskII/src/slirp/tcp_timer.h +++ b/BasiliskII/src/slirp/tcp_timer.h @@ -130,9 +130,9 @@ extern int tcp_backoff[]; struct tcpcb; -void tcp_fasttimo(void); -void tcp_slowtimo(void); -void tcp_canceltimers(struct tcpcb *); -struct tcpcb * tcp_timers(register struct tcpcb *, int); +void tcp_fasttimo _P((void)); +void tcp_slowtimo _P((void)); +void tcp_canceltimers _P((struct tcpcb *)); +struct tcpcb * tcp_timers _P((register struct tcpcb *, int)); #endif diff --git a/BasiliskII/src/slirp/tcp_var.h b/BasiliskII/src/slirp/tcp_var.h old mode 100644 new mode 100755 index c8e99ae03..064ac69a1 --- a/BasiliskII/src/slirp/tcp_var.h +++ b/BasiliskII/src/slirp/tcp_var.h @@ -36,18 +36,12 @@ #include "tcpip.h" #include "tcp_timer.h" -#if SIZEOF_CHAR_P == 4 - typedef struct tcpiphdr *tcpiphdrp_32; -#else - typedef u_int32_t tcpiphdrp_32; -#endif - /* * Tcp control block, one per tcp; fields: */ struct tcpcb { - tcpiphdrp_32 seg_next; /* sequencing queue */ - tcpiphdrp_32 seg_prev; + struct tcpiphdr *seg_next; /* sequencing queue */ + struct tcpiphdr *seg_prev; short t_state; /* state of this connection */ short t_timer[TCPT_NTIMERS]; /* tcp timers */ short t_rxtshift; /* log(2) of rexmt exp. backoff */ @@ -166,21 +160,6 @@ struct tcpcb { #define TCP_REXMTVAL(tp) \ (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) -/* XXX - * We want to avoid doing m_pullup on incoming packets but that - * means avoiding dtom on the tcp reassembly code. That in turn means - * keeping an mbuf pointer in the reassembly queue (since we might - * have a cluster). As a quick hack, the source & destination - * port numbers (which are no longer needed once we've located the - * tcpcb) are overlayed with an mbuf pointer. - */ -#if SIZEOF_CHAR_P == 4 -typedef struct mbuf *mbufp_32; -#else -typedef u_int32_t mbufp_32; -#endif -#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) - /* * TCP statistics. * Many of these should be kept per connection, diff --git a/BasiliskII/src/slirp/tcpip.h b/BasiliskII/src/slirp/tcpip.h old mode 100644 new mode 100755 index dff5a3c96..7974ce3d5 --- a/BasiliskII/src/slirp/tcpip.h +++ b/BasiliskII/src/slirp/tcpip.h @@ -40,8 +40,7 @@ struct tcpiphdr { struct ipovly ti_i; /* overlaid ip structure */ struct tcphdr ti_t; /* tcp header */ }; -#define ti_next ti_i.ih_next -#define ti_prev ti_i.ih_prev +#define ti_mbuf ti_i.ih_mbuf.mptr #define ti_x1 ti_i.ih_x1 #define ti_pr ti_i.ih_pr #define ti_len ti_i.ih_len @@ -58,6 +57,14 @@ struct tcpiphdr { #define ti_sum ti_t.th_sum #define ti_urp ti_t.th_urp +#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink))) +#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink))) +#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next) +#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev) +#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next) +#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T)) +#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T)) + /* * Just a clean way to get to the first byte * of the packet diff --git a/BasiliskII/src/slirp/tftp.c b/BasiliskII/src/slirp/tftp.c old mode 100644 new mode 100755 index 3ba2971c3..e656c4f06 --- a/BasiliskII/src/slirp/tftp.c +++ b/BasiliskII/src/slirp/tftp.c @@ -127,6 +127,7 @@ static int tftp_send_error(struct tftp_session *spt, struct sockaddr_in saddr, daddr; struct mbuf *m; struct tftp_t *tp; + int nobytes; m = m_get(); @@ -151,6 +152,8 @@ static int tftp_send_error(struct tftp_session *spt, daddr.sin_addr = spt->client_ip; daddr.sin_port = spt->client_port; + nobytes = 2; + m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - sizeof(struct ip) - sizeof(struct udphdr); diff --git a/BasiliskII/src/slirp/tftp.h b/BasiliskII/src/slirp/tftp.h old mode 100644 new mode 100755 index b150a0490..f89e03932 --- a/BasiliskII/src/slirp/tftp.h +++ b/BasiliskII/src/slirp/tftp.h @@ -34,7 +34,7 @@ struct tftp_t { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif void tftp_input(struct mbuf *m); diff --git a/BasiliskII/src/slirp/udp.c b/BasiliskII/src/slirp/udp.c old mode 100644 new mode 100755 index deedb1e75..7917aaa47 --- a/BasiliskII/src/slirp/udp.c +++ b/BasiliskII/src/slirp/udp.c @@ -128,8 +128,7 @@ udp_input(m, iphlen) * Checksum extended UDP header and data. */ if (udpcksum && uh->uh_sum) { - ((struct ipovly *)ip)->ih_next = 0; - ((struct ipovly *)ip)->ih_prev = 0; + memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr)); ((struct ipovly *)ip)->ih_x1 = 0; ((struct ipovly *)ip)->ih_len = uh->uh_ulen; /* keep uh_sum for ICMP reply @@ -272,10 +271,10 @@ int udp_output2(struct socket *so, struct mbuf *m, * and addresses and length put into network format. */ ui = mtod(m, struct udpiphdr *); - ui->ui_next = ui->ui_prev = 0; + memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; - ui->ui_len = htons((u_short) (m->m_len - sizeof(struct ip))); /* + sizeof (struct udphdr)); */ + ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ ui->ui_src = saddr->sin_addr; ui->ui_dst = daddr->sin_addr; @@ -291,7 +290,7 @@ int udp_output2(struct socket *so, struct mbuf *m, if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) ui->ui_sum = 0xffff; } - ((struct ip *)ui)->ip_len = (u_int16_t) m->m_len; + ((struct ip *)ui)->ip_len = m->m_len; ((struct ip *)ui)->ip_ttl = ip_defttl; ((struct ip *)ui)->ip_tos = iptos; @@ -338,10 +337,14 @@ udp_attach(so) addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) { - int error = WSAGetLastError(); + int lasterrno=errno; closesocket(so->s); so->s=-1; - WSASetLastError(error); +#ifdef _WIN32 + WSASetLastError(lasterrno); +#else + errno=lasterrno; +#endif } else { /* success, insert in queue */ so->so_expire = curtime + SO_EXPIRE; diff --git a/BasiliskII/src/slirp/udp.h b/BasiliskII/src/slirp/udp.h old mode 100644 new mode 100755 index 7d844efe2..639a2f2c7 --- a/BasiliskII/src/slirp/udp.h +++ b/BasiliskII/src/slirp/udp.h @@ -54,7 +54,7 @@ struct udphdr { } PACKED__; #ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_RESET) +#pragma pack(0) #endif /* @@ -64,8 +64,7 @@ struct udpiphdr { struct ipovly ui_i; /* overlaid ip structure */ struct udphdr ui_u; /* udp header */ }; -#define ui_next ui_i.ih_next -#define ui_prev ui_i.ih_prev +#define ui_mbuf ui_i.ih_mbuf.mptr #define ui_x1 ui_i.ih_x1 #define ui_pr ui_i.ih_pr #define ui_len ui_i.ih_len @@ -100,14 +99,14 @@ extern struct udpstat udpstat; extern struct socket udb; struct mbuf; -void udp_init(void); -void udp_input(register struct mbuf *, int); -int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *); -int udp_attach(struct socket *); -void udp_detach(struct socket *); -u_int8_t udp_tos(struct socket *); -void udp_emu(struct socket *, struct mbuf *); -struct socket * udp_listen(u_int, u_int32_t, u_int, int); +void udp_init _P((void)); +void udp_input _P((register struct mbuf *, int)); +int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *)); +int udp_attach _P((struct socket *)); +void udp_detach _P((struct socket *)); +u_int8_t udp_tos _P((struct socket *)); +void udp_emu _P((struct socket *, struct mbuf *)); +struct socket * udp_listen _P((u_int, u_int32_t, u_int, int)); int udp_output2(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, struct sockaddr_in *daddr, int iptos); 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/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/timer.cpp b/BasiliskII/src/timer.cpp index 1383d8eeb..316d8d38a 100644 --- a/BasiliskII/src/timer.cpp +++ b/BasiliskII/src/timer.cpp @@ -173,7 +173,7 @@ void TimerReset(void) int16 InsTime(uint32 tm, uint16 trap) { D(bug("InsTime %08lx, trap %04x\n", tm, trap)); - WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x1fff | (trap << 4) & 0x6000); + WriteMacInt16(tm + qType, (ReadMacInt16(tm + qType) & 0x1fff) | ((trap << 4) & 0x6000)); if (find_desc(tm) >= 0) printf("WARNING: InsTime(): Task re-inserted\n"); else { diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index b29c77026..b39e7dbde 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -31,53 +31,160 @@ #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 +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; + +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 DIRECT_ADDRESSING -uintptr MEMBaseDiff; // Global offset between a Mac address and its Host equivalent +// 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 + + // 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 = 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 -bool UseJIT = false; + // 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; -// From newcpu.cpp -extern bool quit_program; +#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"); -/* - * Initialize 680x0 emulation, CheckROM() must have been called first - */ + // 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); -bool Init680x0(void) -{ -#if REAL_ADDRESSING - // Mac address space = host address space - RAMBaseMac = (uintptr)RAMBaseHost; - ROMBaseMac = (uintptr)ROMBaseHost; -#elif DIRECT_ADDRESSING + 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; + MEMBaseDiff = (size_t)RAMBaseHost; ROMBaseMac = Host2MacAddr(ROMBaseHost); #else // Initialize UAE memory banks - RAMBaseMac = 0; switch (ROMVersion) { case ROM_VERSION_64K: case ROM_VERSION_PLUS: @@ -95,58 +202,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 */ @@ -264,3 +375,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 9a612fb21..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_fpp.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_fpp.cpp index bb536634f..cadecf98e 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu_fpp.cpp +++ b/BasiliskII/src/uae_cpu/compiler/compemu_fpp.cpp @@ -34,6 +34,8 @@ #include "sysdeps.h" +#if USE_JIT + #include #include @@ -1635,3 +1637,5 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) m68k_setpc (m68k_getpc () - 4); fpuop_illg (opcode,extra); } + +#endif //USE_JIT diff --git a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp index c55ae3b5b..ae8f7ab47 100644 --- a/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp +++ b/BasiliskII/src/uae_cpu/compiler/compemu_support.cpp @@ -25,8 +25,10 @@ #include "sysdeps.h" -#if !REAL_ADDRESSING && !DIRECT_ADDRESSING -#error "Only Real or Direct Addressing is supported with the JIT Compiler" +#if USE_JIT + +#if !DIRECT_ADDRESSING +#error "Only Direct Addressing is supported with the JIT Compiler" #endif #if X86_ASSEMBLY && !SAHF_SETO_PROFITABLE @@ -72,27 +74,25 @@ #include "fpu/fpu.h" #include "fpu/flags.h" -#define DEBUG 1 +#define DEBUG 0 #include "debug.h" #ifdef ENABLE_MON #include "mon.h" #endif -#ifndef WIN32 -#define PROFILE_COMPILE_TIME 1 -#define PROFILE_UNTRANSLATED_INSNS 1 -#endif +#define PROFILE_COMPILE_TIME 0 +#define PROFILE_UNTRANSLATED_INSNS 0 #if defined(__x86_64__) && 0 #define RECORD_REGISTER_USAGE 1 #endif -#ifdef WIN32 +//#ifdef WIN32 #undef write_log #define write_log dummy_write_log static void dummy_write_log(const char *, ...) { } -#endif +//#endif #if JIT_DEBUG #undef abort @@ -5003,12 +5003,14 @@ static inline const char *str_on_off(bool b) return b ? "on" : "off"; } -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; + #if JIT_DEBUG // JIT debug mode ? JITDebug = PrefsFindBool("jitdebug"); @@ -5024,10 +5026,6 @@ void compiler_init(void) #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(); @@ -5065,24 +5063,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); @@ -5135,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) @@ -5565,9 +5554,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); @@ -5649,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) @@ -5672,94 +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 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); - /* allocated code must fit in 32-bit boundaries */ - assert((uintptr)ptr <= 0xffffffff); - return ptr; -} - -void alloc_cache(void) -{ - if (compiled_code) { - flush_icache_hard(6); - vm_release(compiled_code, cache_size * 1024); - compiled_code = 0; - } - - if (cache_size == 0) - return; +void alloc_cache(void){ + assert(compiled_code); + assert(cache_size); - 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) { - 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) @@ -5999,14 +5907,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; @@ -6322,8 +6226,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;ismode, "srcreg", curi->size, "src", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); start_brace(); @@ -1541,7 +1541,7 @@ gen_opcode (unsigned long int opcode) failure; break; case i_RTD: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); /* offs is constant */ comprintf("\tadd_l_ri(offs,4);\n"); @@ -1557,7 +1557,7 @@ gen_opcode (unsigned long int opcode) isjump; break; case i_LINK: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); comprintf("\tsub_l_ri(15,4);\n" @@ -1569,7 +1569,7 @@ gen_opcode (unsigned long int opcode) genastore ("src", curi->smode, "srcreg", sz_long, "src"); break; case i_UNLK: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); comprintf("\tmov_l_rr(15,src);\n" "\treadlong(15,src,scratchie);\n" @@ -1790,7 +1790,7 @@ gen_opcode (unsigned long int opcode) break; case i_Scc: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); start_brace (); comprintf ("\tint val = scratchie++;\n"); @@ -1837,7 +1837,7 @@ gen_opcode (unsigned long int opcode) failure; break; case i_MULU: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ comprintf("\tdont_care_flags();\n"); genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); @@ -1852,7 +1852,7 @@ gen_opcode (unsigned long int opcode) genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); break; case i_MULS: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ comprintf("\tdont_care_flags();\n"); genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); @@ -1886,7 +1886,7 @@ gen_opcode (unsigned long int opcode) genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); if (curi->smode!=immi) { -/* failure; /* UNTESTED: NEW: from "Ipswitch Town" release */ +/* failure; UNTESTED: NEW: from "Ipswitch Town" release */ if (!noflags) { uses_cmov; start_brace(); @@ -2039,7 +2039,7 @@ gen_opcode (unsigned long int opcode) break; case i_ASL: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ mayfail; if (curi->smode==Dreg) { comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" @@ -2186,7 +2186,7 @@ gen_opcode (unsigned long int opcode) break; case i_LSR: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ mayfail; if (curi->smode==Dreg) { comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" @@ -2337,7 +2337,7 @@ gen_opcode (unsigned long int opcode) genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); if (curi->smode!=immi) { -/* failure; /* UNTESTED: NEW: from "Ipswitch Town" release */ +/* failure; UNTESTED: NEW: from "Ipswitch Town" release */ if (!noflags) { uses_cmov; start_brace(); @@ -2609,7 +2609,7 @@ gen_opcode (unsigned long int opcode) failure; break; case i_MULL: -/* failure; /* NEW: from "Ipswitch Town" release */ +/* failure; NEW: from "Ipswitch Town" release */ if (!noflags) { failure; break; @@ -3038,6 +3038,9 @@ main (int argc, char **argv) stblfile = fopen ("compstbl.cpp", "wb"); freopen ("compemu.cpp", "wb", stdout); + fprintf(stblfile, "#if USE_JIT\n"); + printf("#if USE_JIT\n"); + generate_includes (stdout); generate_includes (stblfile); @@ -3059,6 +3062,9 @@ main (int argc, char **argv) noflags=1; generate_func (noflags); + fprintf(stblfile, "#endif //USE_JIT\n"); + printf("#endif //USE_JIT\n"); + free(opcode_map); free(opcode_last_postfix); free(opcode_next_clev); diff --git a/BasiliskII/src/uae_cpu/cpu_emulation.h b/BasiliskII/src/uae_cpu/cpu_emulation.h index 669402a14..b1713d45c 100644 --- a/BasiliskII/src/uae_cpu/cpu_emulation.h +++ b/BasiliskII/src/uae_cpu/cpu_emulation.h @@ -23,30 +23,26 @@ #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 -// For 24 Bit ROM, we maps the guest OS frame buffer address above 4MiB RAM -// and ROM but less than 16 MiB. -const uint32 MacFrameBaseMac24Bit = 0x00500000; - -#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; -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) @@ -82,6 +78,8 @@ static inline void *Mac2Mac_memcpy(uint32 dest, uint32 src, size_t n) {return me */ // Initialization +extern bool InitMacMem(void); +extern void MacMemExit(void); extern bool Init680x0(void); // This routine may want to look at CPUType/FPUType to set up the apropriate emulation extern void Exit680x0(void); extern void InitFrameBufferMapping(void); diff --git a/BasiliskII/src/uae_cpu/gencpu.c b/BasiliskII/src/uae_cpu/gencpu.c index 1653adab9..5045dffd4 100644 --- a/BasiliskII/src/uae_cpu/gencpu.c +++ b/BasiliskII/src/uae_cpu/gencpu.c @@ -2189,14 +2189,14 @@ static void gen_opcode (unsigned long int opcode) case i_CINVA: /* gb-- srcreg now contains the cache field */ printf ("\tif (srcreg&0x2)\n"); - printf ("\t\tflush_icache(%d);\n", 30 + ((opcode >> 3) & 3)); + printf ("\t\tflush_icache(%d);\n", (int)(30 + ((opcode >> 3) & 3))); break; case i_CPUSHL: case i_CPUSHP: case i_CPUSHA: /* gb-- srcreg now contains the cache field */ printf ("\tif (srcreg&0x2)\n"); - printf ("\t\tflush_icache(%d);\n", 40 + ((opcode >> 3) & 3)); + printf ("\t\tflush_icache(%d);\n", (int)(40 + ((opcode >> 3) & 3))); break; case i_MOVE16: if ((opcode & 0xfff8) == 0xf620) { diff --git a/BasiliskII/src/uae_cpu/memory.cpp b/BasiliskII/src/uae_cpu/memory.cpp index fbca3d6e0..5863ab4da 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; @@ -53,27 +53,27 @@ addrbank mem_banks[65536]; #ifdef NO_INLINE_MEMORY_ACCESS uae_u32 longget (uaecptr addr) { - return call_mem_get_func (get_mem_bank (addr).lget, addr); + return call_mem_get_func (get_mem_bank (addr).lget, addr); } uae_u32 wordget (uaecptr addr) { - return call_mem_get_func (get_mem_bank (addr).wget, addr); + return call_mem_get_func (get_mem_bank (addr).wget, addr); } uae_u32 byteget (uaecptr addr) { - return call_mem_get_func (get_mem_bank (addr).bget, addr); + return call_mem_get_func (get_mem_bank (addr).bget, addr); } void longput (uaecptr addr, uae_u32 l) { - call_mem_put_func (get_mem_bank (addr).lput, addr, l); + call_mem_put_func (get_mem_bank (addr).lput, addr, l); } void wordput (uaecptr addr, uae_u32 w) { - call_mem_put_func (get_mem_bank (addr).wput, addr, w); + call_mem_put_func (get_mem_bank (addr).wput, addr, w); } void byteput (uaecptr addr, uae_u32 b) { - call_mem_put_func (get_mem_bank (addr).bput, addr, b); + call_mem_put_func (get_mem_bank (addr).bput, addr, b); } #endif @@ -88,42 +88,42 @@ static void REGPARAM2 dummy_bput (uaecptr, uae_u32) REGPARAM; uae_u32 REGPARAM2 dummy_lget (uaecptr addr) { - if (illegal_mem) - write_log ("Illegal lget at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal lget at %08x\n", addr); - return 0; + return 0; } uae_u32 REGPARAM2 dummy_wget (uaecptr addr) { - if (illegal_mem) - write_log ("Illegal wget at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal wget at %08x\n", addr); - return 0; + return 0; } uae_u32 REGPARAM2 dummy_bget (uaecptr addr) { - if (illegal_mem) - write_log ("Illegal bget at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal bget at %08x\n", addr); - return 0; + return 0; } void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) { - if (illegal_mem) - write_log ("Illegal lput at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal lput at %08x\n", addr); } void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w) { - if (illegal_mem) - write_log ("Illegal wput at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal wput at %08x\n", addr); } void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b) { - if (illegal_mem) - write_log ("Illegal bput at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal bput at %08x\n", addr); } /* Mac RAM (32 bit addressing) */ @@ -136,39 +136,39 @@ 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) { - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + addr); - return do_get_mem_long(m); + uae_u32 *m; + m = (uae_u32 *)(RAMBaseDiff + addr); + return do_get_mem_long(m); } uae_u32 REGPARAM2 ram_wget(uaecptr addr) { - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + addr); - return do_get_mem_word(m); + uae_u16 *m; + m = (uae_u16 *)(RAMBaseDiff + addr); + return do_get_mem_word(m); } uae_u32 REGPARAM2 ram_bget(uaecptr addr) { - return (uae_u32)*(uae_u8 *)(RAMBaseDiff + addr); + return (uae_u32)*(uae_u8 *)(RAMBaseDiff + addr); } void REGPARAM2 ram_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + addr); - do_put_mem_long(m, l); + uae_u32 *m; + m = (uae_u32 *)(RAMBaseDiff + addr); + do_put_mem_long(m, l); } void REGPARAM2 ram_wput(uaecptr addr, uae_u32 w) { - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + addr); - do_put_mem_word(m, w); + uae_u16 *m; + m = (uae_u16 *)(RAMBaseDiff + addr); + do_put_mem_word(m, w); } void REGPARAM2 ram_bput(uaecptr addr, uae_u32 b) @@ -178,7 +178,7 @@ void REGPARAM2 ram_bput(uaecptr addr, uae_u32 b) uae_u8 *REGPARAM2 ram_xlate(uaecptr addr) { - return (uae_u8 *)(RAMBaseDiff + addr); + return (uae_u8 *)(RAMBaseDiff + addr); } /* Mac RAM (24 bit addressing) */ @@ -193,35 +193,35 @@ static uae_u8 *REGPARAM2 ram24_xlate(uaecptr addr) REGPARAM; uae_u32 REGPARAM2 ram24_lget(uaecptr addr) { - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); - return do_get_mem_long(m); + uae_u32 *m; + m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); + return do_get_mem_long(m); } uae_u32 REGPARAM2 ram24_wget(uaecptr addr) { - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); - return do_get_mem_word(m); + uae_u16 *m; + m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); + return do_get_mem_word(m); } uae_u32 REGPARAM2 ram24_bget(uaecptr addr) { - return (uae_u32)*(uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)); + return (uae_u32)*(uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)); } void REGPARAM2 ram24_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); - do_put_mem_long(m, l); + uae_u32 *m; + m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); + do_put_mem_long(m, l); } void REGPARAM2 ram24_wput(uaecptr addr, uae_u32 w) { - uae_u16 *m; - m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); - do_put_mem_word(m, w); + uae_u16 *m; + m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); + do_put_mem_word(m, w); } void REGPARAM2 ram24_bput(uaecptr addr, uae_u32 b) @@ -231,7 +231,7 @@ void REGPARAM2 ram24_bput(uaecptr addr, uae_u32 b) uae_u8 *REGPARAM2 ram24_xlate(uaecptr addr) { - return (uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)); + return (uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)); } /* Mac ROM (32 bit addressing) */ @@ -244,48 +244,48 @@ 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) { - uae_u32 *m; - m = (uae_u32 *)(ROMBaseDiff + addr); - return do_get_mem_long(m); + uae_u32 *m; + m = (uae_u32 *)(ROMBaseDiff + addr); + return do_get_mem_long(m); } uae_u32 REGPARAM2 rom_wget(uaecptr addr) { - uae_u16 *m; - m = (uae_u16 *)(ROMBaseDiff + addr); - return do_get_mem_word(m); + uae_u16 *m; + m = (uae_u16 *)(ROMBaseDiff + addr); + return do_get_mem_word(m); } uae_u32 REGPARAM2 rom_bget(uaecptr addr) { - return (uae_u32)*(uae_u8 *)(ROMBaseDiff + addr); + return (uae_u32)*(uae_u8 *)(ROMBaseDiff + addr); } void REGPARAM2 rom_lput(uaecptr addr, uae_u32 b) { - if (illegal_mem) - write_log ("Illegal ROM lput at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal ROM lput at %08x\n", addr); } void REGPARAM2 rom_wput(uaecptr addr, uae_u32 b) { - if (illegal_mem) - write_log ("Illegal ROM wput at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal ROM wput at %08x\n", addr); } void REGPARAM2 rom_bput(uaecptr addr, uae_u32 b) { - if (illegal_mem) - write_log ("Illegal ROM bput at %08x\n", addr); + if (illegal_mem) + write_log ("Illegal ROM bput at %08x\n", addr); } uae_u8 *REGPARAM2 rom_xlate(uaecptr addr) { - return (uae_u8 *)(ROMBaseDiff + addr); + return (uae_u8 *)(ROMBaseDiff + addr); } /* Mac ROM (24 bit addressing) */ @@ -297,26 +297,26 @@ static uae_u8 *REGPARAM2 rom24_xlate(uaecptr addr) REGPARAM; uae_u32 REGPARAM2 rom24_lget(uaecptr addr) { - uae_u32 *m; - m = (uae_u32 *)(ROMBaseDiff + (addr & 0xffffff)); - return do_get_mem_long(m); + uae_u32 *m; + m = (uae_u32 *)(ROMBaseDiff + (addr & 0xffffff)); + return do_get_mem_long(m); } uae_u32 REGPARAM2 rom24_wget(uaecptr addr) { - uae_u16 *m; - m = (uae_u16 *)(ROMBaseDiff + (addr & 0xffffff)); - return do_get_mem_word(m); + uae_u16 *m; + m = (uae_u16 *)(ROMBaseDiff + (addr & 0xffffff)); + return do_get_mem_word(m); } uae_u32 REGPARAM2 rom24_bget(uaecptr addr) { - return (uae_u32)*(uae_u8 *)(ROMBaseDiff + (addr & 0xffffff)); + return (uae_u32)*(uae_u8 *)(ROMBaseDiff + (addr & 0xffffff)); } uae_u8 *REGPARAM2 rom24_xlate(uaecptr addr) { - return (uae_u8 *)(ROMBaseDiff + (addr & 0xffffff)); + return (uae_u8 *)(ROMBaseDiff + (addr & 0xffffff)); } /* Frame buffer */ @@ -343,329 +343,299 @@ 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) { - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - return do_get_mem_long(m); + uae_u32 *m; + m = (uae_u32 *)(FrameBaseDiff + addr); + return do_get_mem_long(m); } uae_u32 REGPARAM2 frame_direct_wget(uaecptr addr) { - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - return do_get_mem_word(m); + uae_u16 *m; + m = (uae_u16 *)(FrameBaseDiff + addr); + return do_get_mem_word(m); } uae_u32 REGPARAM2 frame_direct_bget(uaecptr addr) { - return (uae_u32)*(uae_u8 *)(FrameBaseDiff + addr); + return (uae_u32)*(uae_u8 *)(FrameBaseDiff + addr); } void REGPARAM2 frame_direct_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - do_put_mem_long(m, l); + uae_u32 *m; + m = (uae_u32 *)(FrameBaseDiff + addr); + do_put_mem_long(m, l); } void REGPARAM2 frame_direct_wput(uaecptr addr, uae_u32 w) { - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - do_put_mem_word(m, w); + uae_u16 *m; + m = (uae_u16 *)(FrameBaseDiff + addr); + do_put_mem_word(m, w); } void REGPARAM2 frame_direct_bput(uaecptr addr, uae_u32 b) { - *(uae_u8 *)(FrameBaseDiff + addr) = b; + *(uae_u8 *)(FrameBaseDiff + addr) = b; } uae_u32 REGPARAM2 frame_host_555_lget(uaecptr addr) { - uae_u32 *m, l; - m = (uae_u32 *)(FrameBaseDiff + addr); - l = *m; + uae_u32 *m, l; + m = (uae_u32 *)(FrameBaseDiff + addr); + l = *m; return swap_words(l); } uae_u32 REGPARAM2 frame_host_555_wget(uaecptr addr) { - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - return *m; + uae_u16 *m; + m = (uae_u16 *)(FrameBaseDiff + addr); + return *m; } void REGPARAM2 frame_host_555_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - *m = swap_words(l); + uae_u32 *m; + m = (uae_u32 *)(FrameBaseDiff + addr); + *m = swap_words(l); } void REGPARAM2 frame_host_555_wput(uaecptr addr, uae_u32 w) { - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - *m = w; + uae_u16 *m; + m = (uae_u16 *)(FrameBaseDiff + addr); + *m = w; } uae_u32 REGPARAM2 frame_host_565_lget(uaecptr addr) { - uae_u32 *m, l; - m = (uae_u32 *)(FrameBaseDiff + addr); - l = *m; - l = (l & 0x001f001f) | ((l >> 1) & 0x7fe07fe0); - return swap_words(l); + uae_u32 *m, l; + m = (uae_u32 *)(FrameBaseDiff + addr); + l = *m; + l = (l & 0x001f001f) | ((l >> 1) & 0x7fe07fe0); + return swap_words(l); } uae_u32 REGPARAM2 frame_host_565_wget(uaecptr addr) { - uae_u16 *m, w; - m = (uae_u16 *)(FrameBaseDiff + addr); - w = *m; - return (w & 0x1f) | ((w >> 1) & 0x7fe0); + uae_u16 *m, w; + m = (uae_u16 *)(FrameBaseDiff + addr); + w = *m; + return (w & 0x1f) | ((w >> 1) & 0x7fe0); } void REGPARAM2 frame_host_565_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + addr); - l = (l & 0x001f001f) | ((l << 1) & 0xffc0ffc0); - *m = swap_words(l); + uae_u32 *m; + m = (uae_u32 *)(FrameBaseDiff + addr); + l = (l & 0x001f001f) | ((l << 1) & 0xffc0ffc0); + *m = swap_words(l); } void REGPARAM2 frame_host_565_wput(uaecptr addr, uae_u32 w) { - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + addr); - *m = (w & 0x1f) | ((w << 1) & 0xffc0); + uae_u16 *m; + m = (uae_u16 *)(FrameBaseDiff + addr); + *m = (w & 0x1f) | ((w << 1) & 0xffc0); } uae_u32 REGPARAM2 frame_host_888_lget(uaecptr addr) { - uae_u32 *m, l; - m = (uae_u32 *)(FrameBaseDiff + addr); - return *m; + uae_u32 *m, l; + m = (uae_u32 *)(FrameBaseDiff + addr); + return *m; } void REGPARAM2 frame_host_888_lput(uaecptr addr, uae_u32 l) { - uae_u32 *m; - m = (uae_u32 *)(MacFrameBaseHost + addr - MacFrameBaseMac); - *m = l; + uae_u32 *m; + m = (uae_u32 *)(MacFrameBaseHost + addr - MacFrameBaseMac); + *m = l; } uae_u8 *REGPARAM2 frame_xlate(uaecptr addr) { - return (uae_u8 *)(FrameBaseDiff + addr); + return (uae_u8 *)(FrameBaseDiff + addr); } -/* Mac framebuffer RAM (24 bit addressing) */ -static uae_u32 REGPARAM2 frame24_lget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 frame24_wget(uaecptr) REGPARAM; -static uae_u32 REGPARAM2 frame24_bget(uaecptr) REGPARAM; -static void REGPARAM2 frame24_lput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 frame24_wput(uaecptr, uae_u32) REGPARAM; -static void REGPARAM2 frame24_bput(uaecptr, uae_u32) REGPARAM; - -/* - * Q: Why the magic number 0xa700 and 0xfc80? - * - * A: The M68K CPU used by the earlier Macintosh models such as - * Macintosh 128K or Macintosh SE, its address space is limited - * to 2^24 = 16MiB. The RAM limits to 4MiB. - * - * With 512x342 1 bit per pixel screen, the size of the frame buffer - * is 0x5580 bytes. - * - * In Macintosh 128K [1], the frame buffer address is mapped from - * 0x1A700 to 0x1FC7F. - * - * In Macintosh SE [2], the frame buffer address is mapped from - * 0x3FA700 to 0x3FFC7F. - * - * The frame24_xxx memory banks mapping used the magic number to - * retrieve the offset. The memory write operation does twice: - * one for the guest OS and another for the host OS (the write operation - * above MacFrameBaseHost). - * - * - * See: - * [1] The Apple Macintosh Computer. http://www.1000bit.it/support/articoli/apple/mac128.pdf - * [2] Capturing Mac SE's video from PDS. http://synack.net/~bbraun/sevideo/ +/* Mac framebuffer RAM (24 bit addressing) * + * This works by duplicating appropriate writes to the 32-bit + * address-space framebuffer. */ -uae_u32 REGPARAM2 frame24_lget(uaecptr addr) -{ - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + (addr & 0xffffff)); - return do_get_mem_long(m); -} +static void REGPARAM2 fram24_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM2 fram24_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM2 fram24_bput(uaecptr, uae_u32) REGPARAM; -uae_u32 REGPARAM2 frame24_wget(uaecptr addr) +void REGPARAM2 fram24_lput(uaecptr addr, uae_u32 l) { - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + (addr & 0xffffff)); - return do_get_mem_word(m); -} + uaecptr page_off = addr & 0xffff; + if (0xa700 <= page_off && page_off < 0xfc80) { + uae_u32 *fm; + fm = (uae_u32 *)(MacFrameBaseHost + page_off - 0xa700); + do_put_mem_long(fm, l); + } -uae_u32 REGPARAM2 frame24_bget(uaecptr addr) -{ - return (uae_u32)*(uae_u8 *)(FrameBaseDiff + (addr & 0xffffff)); + uae_u32 *m; + m = (uae_u32 *)(RAMBaseDiff + (addr & 0xffffff)); + do_put_mem_long(m, l); } -void REGPARAM2 frame24_lput(uaecptr addr, uae_u32 l) +void REGPARAM2 fram24_wput(uaecptr addr, uae_u32 w) { - uae_u32 *m; - m = (uae_u32 *)(FrameBaseDiff + (addr & 0xffffffff)); - do_put_mem_long(m, l); -} + uaecptr page_off = addr & 0xffff; + if (0xa700 <= page_off && page_off < 0xfc80) { + uae_u16 *fm; + fm = (uae_u16 *)(MacFrameBaseHost + page_off - 0xa700); + do_put_mem_word(fm, w); + } -void REGPARAM2 frame24_wput(uaecptr addr, uae_u32 w) -{ - uae_u16 *m; - m = (uae_u16 *)(FrameBaseDiff + (addr & 0xffffffff)); - do_put_mem_word(m, w); + uae_u16 *m; + m = (uae_u16 *)(RAMBaseDiff + (addr & 0xffffff)); + do_put_mem_word(m, w); } -void REGPARAM2 frame24_bput(uaecptr addr, uae_u32 b) +void REGPARAM2 fram24_bput(uaecptr addr, uae_u32 b) { - *(uae_u8 *)(FrameBaseDiff + (addr & 0xffffffff)) = b; + uaecptr page_off = addr & 0xffff; + if (0xa700 <= page_off && page_off < 0xfc80) { + *(uae_u8 *)(MacFrameBaseHost + page_off - 0xa700) = b; + } + + *(uae_u8 *)(RAMBaseDiff + (addr & 0xffffff)) = b; } /* Default memory access functions */ uae_u8 *REGPARAM2 default_xlate (uaecptr a) { - write_log("Your Mac program just did something terribly stupid\n"); - return NULL; + write_log("Your Mac program just did something terribly stupid\n"); + return NULL; } /* Address banks */ addrbank dummy_bank = { - dummy_lget, dummy_wget, dummy_bget, - dummy_lput, dummy_wput, dummy_bput, - default_xlate + dummy_lget, dummy_wget, dummy_bget, + dummy_lput, dummy_wput, dummy_bput, + default_xlate }; addrbank ram_bank = { - ram_lget, ram_wget, ram_bget, - ram_lput, ram_wput, ram_bput, - ram_xlate + ram_lget, ram_wget, ram_bget, + ram_lput, ram_wput, ram_bput, + ram_xlate }; addrbank ram24_bank = { - ram24_lget, ram24_wget, ram24_bget, - ram24_lput, ram24_wput, ram24_bput, - ram24_xlate + ram24_lget, ram24_wget, ram24_bget, + ram24_lput, ram24_wput, ram24_bput, + ram24_xlate }; addrbank rom_bank = { - rom_lget, rom_wget, rom_bget, - rom_lput, rom_wput, rom_bput, - rom_xlate + rom_lget, rom_wget, rom_bget, + rom_lput, rom_wput, rom_bput, + rom_xlate }; addrbank rom24_bank = { - rom24_lget, rom24_wget, rom24_bget, - rom_lput, rom_wput, rom_bput, - rom24_xlate + rom24_lget, rom24_wget, rom24_bget, + rom_lput, rom_wput, rom_bput, + rom24_xlate }; addrbank frame_direct_bank = { - frame_direct_lget, frame_direct_wget, frame_direct_bget, - frame_direct_lput, frame_direct_wput, frame_direct_bput, - frame_xlate + frame_direct_lget, frame_direct_wget, frame_direct_bget, + frame_direct_lput, frame_direct_wput, frame_direct_bput, + frame_xlate }; addrbank frame_host_555_bank = { - frame_host_555_lget, frame_host_555_wget, frame_direct_bget, - frame_host_555_lput, frame_host_555_wput, frame_direct_bput, - frame_xlate + frame_host_555_lget, frame_host_555_wget, frame_direct_bget, + frame_host_555_lput, frame_host_555_wput, frame_direct_bput, + frame_xlate }; addrbank frame_host_565_bank = { - frame_host_565_lget, frame_host_565_wget, frame_direct_bget, - frame_host_565_lput, frame_host_565_wput, frame_direct_bput, - frame_xlate + frame_host_565_lget, frame_host_565_wget, frame_direct_bget, + frame_host_565_lput, frame_host_565_wput, frame_direct_bput, + frame_xlate }; addrbank frame_host_888_bank = { - frame_host_888_lget, frame_direct_wget, frame_direct_bget, - frame_host_888_lput, frame_direct_wput, frame_direct_bput, - frame_xlate + frame_host_888_lget, frame_direct_wget, frame_direct_bget, + frame_host_888_lput, frame_direct_wput, frame_direct_bput, + frame_xlate }; -addrbank frame24_bank = { - frame24_lget, frame24_wget, frame24_bget, - frame24_lput, frame24_wput, frame24_bput, - default_xlate +addrbank fram24_bank = { + ram24_lget, ram24_wget, ram24_bget, + fram24_lput, fram24_wput, fram24_bput, + ram24_xlate }; -void memory_init(void) -{ +void memory_init(void){ for(long i=0; i<65536; i++) put_mem_bank(i<<16, &dummy_bank); // Limit RAM size to not overlap ROM uint32 ram_size = RAMSize > ROMBaseMac ? ROMBaseMac : RAMSize; - RAMBaseDiff = (uintptr)RAMBaseHost - (uintptr)RAMBaseMac; - ROMBaseDiff = (uintptr)ROMBaseHost - (uintptr)ROMBaseMac; - if (TwentyFourBitAddressing) - FrameBaseDiff = (uintptr)MacFrameBaseHost - (uintptr)MacFrameBaseMac24Bit; - else - 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) { - map_banks(&ram24_bank, RAMBaseMac >> 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(&frame24_bank, MacFrameBaseMac24Bit >> 16, (MacFrameSize >> 16) + 1); + 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 + // Map frame buffer switch (MacFrameLayout) { - case FLAYOUT_DIRECT: - map_banks(&frame_direct_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - case FLAYOUT_HOST_555: - map_banks(&frame_host_555_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - case FLAYOUT_HOST_565: - map_banks(&frame_host_565_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; - case FLAYOUT_HOST_888: - map_banks(&frame_host_888_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); - break; + case FLAYOUT_DIRECT: + map_banks(&frame_direct_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); + break; + case FLAYOUT_HOST_555: + map_banks(&frame_host_555_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); + break; + case FLAYOUT_HOST_565: + map_banks(&frame_host_565_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); + break; + case FLAYOUT_HOST_888: + map_banks(&frame_host_888_bank, MacFrameBaseMac >> 16, (MacFrameSize >> 16) + 1); + break; } } } void map_banks(addrbank *bank, int start, int size) { - int bnr; - unsigned long int hioffs = 0, endhioffs = 0x100; + int bnr; + unsigned long int hioffs = 0, endhioffs = 0x100; - if (start >= 0x100) { - for (bnr = start; bnr < start + size; bnr++) - put_mem_bank (bnr << 16, bank); - return; - } - if (TwentyFourBitAddressing) endhioffs = 0x10000; - for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) - for (bnr = start; bnr < start+size; bnr++) - put_mem_bank((bnr + hioffs) << 16, bank); + if (start >= 0x100) { + for (bnr = start; bnr < start + size; bnr++) + put_mem_bank (bnr << 16, bank); + return; + } + if (TwentyFourBitAddressing) endhioffs = 0x10000; + for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) + for (bnr = start; bnr < start+size; bnr++) + 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..8a3da5f32 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,22 +115,18 @@ 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 -extern uintptr MEMBaseDiff; -#endif +#if DIRECT_ADDRESSING +extern size_t MEMBaseDiff; -#if REAL_ADDRESSING || DIRECT_ADDRESSING static __inline__ uae_u8 *do_get_real_address(uaecptr addr) { return (uae_u8 *)MEMBaseDiff + 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) { @@ -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); diff --git a/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp b/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp new file mode 100644 index 000000000..9a794b487 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/basilisk_glue.cpp @@ -0,0 +1,285 @@ +/* + * basilisk_glue.cpp - Glue UAE CPU to Basilisk II CPU engine interface + * + * 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 "cpu_emulation.h" +#include "main.h" +#include "prefs.h" +#include "emul_op.h" +#include "rom_patches.h" +#include "timer.h" +#include "m68k.h" +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#include "compiler/compemu.h" + + +// 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 +// 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 +#endif + +#if USE_JIT +bool UseJIT = false; +#endif + +// #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) +B2_mutex *spcflags_lock = NULL; +// #endif + +// From newcpu.cpp +extern int quit_program; + + +/* + * Initialize 680x0 emulation, CheckROM() must have been called first + */ + +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 + // 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: + case ROM_VERSION_CLASSIC: + ROMBaseMac = 0x00400000; + break; + case ROM_VERSION_II: + ROMBaseMac = 0x00a00000; + break; + case ROM_VERSION_32: + ROMBaseMac = 0x40800000; + break; + default: + return false; + } + memory_init(); +#endif + + init_m68k(); +#if USE_JIT + UseJIT = compiler_use_jit(); + if (UseJIT) + compiler_init(); +#endif + return true; +} + + +/* + * Deinitialize 680x0 emulation + */ + +void Exit680x0(void) +{ +#if USE_JIT + if (UseJIT) + compiler_exit(); +#endif + exit_m68k(); +} + + +/* + * Initialize memory mapping of frame buffer (called upon video mode change) + */ + +void InitFrameBufferMapping(void) +{ +#if !REAL_ADDRESSING && !DIRECT_ADDRESSING + memory_init(); +#endif +} + +/* + * Reset and start 680x0 emulation (doesn't return) + */ + +void Start680x0(void) +{ + m68k_reset(); +#if USE_JIT + if (UseJIT) + m68k_compile_execute(); + else +#endif + m68k_execute(); +} + + +/* + * Trigger interrupt + */ + +void TriggerInterrupt(void) +{ + idle_resume(); + SPCFLAGS_SET( SPCFLAG_INT ); +} + +void TriggerNMI(void) +{ + //!! not implemented yet + // SPCFLAGS_SET( SPCFLAG_BRK ); // use _BRK for NMI +} + + +/* + * Get 68k interrupt level + */ + +int intlev(void) +{ + return InterruptFlags ? 1 : 0; +} + + +/* + * Execute MacOS 68k trap + * r->a[7] and r->sr are unused! + */ + +void Execute68kTrap(uint16 trap, struct M68kRegisters *r) +{ + int i; + + // Save old PC + uaecptr oldpc = m68k_getpc(); + + // Set registers + for (i=0; i<8; i++) + m68k_dreg(regs, i) = r->d[i]; + for (i=0; i<7; i++) + m68k_areg(regs, i) = r->a[i]; + + // Push trap and EXEC_RETURN on stack + m68k_areg(regs, 7) -= 2; + put_word(m68k_areg(regs, 7), M68K_EXEC_RETURN); + m68k_areg(regs, 7) -= 2; + put_word(m68k_areg(regs, 7), trap); + + // Execute trap + m68k_setpc(m68k_areg(regs, 7)); + fill_prefetch_0(); + quit_program = 0; + m68k_execute(); + + // Clean up stack + m68k_areg(regs, 7) += 4; + + // Restore old PC + m68k_setpc(oldpc); + fill_prefetch_0(); + + // Get registers + for (i=0; i<8; i++) + r->d[i] = m68k_dreg(regs, i); + for (i=0; i<7; i++) + r->a[i] = m68k_areg(regs, i); + quit_program = 0; +} + + +/* + * Execute 68k subroutine + * The executed routine must reside in UAE memory! + * r->a[7] and r->sr are unused! + */ + +void Execute68k(uint32 addr, struct M68kRegisters *r) +{ + int i; + + // Save old PC + uaecptr oldpc = m68k_getpc(); + + // Set registers + for (i=0; i<8; i++) + m68k_dreg(regs, i) = r->d[i]; + for (i=0; i<7; i++) + m68k_areg(regs, i) = r->a[i]; + + // Push EXEC_RETURN and faked return address (points to EXEC_RETURN) on stack + m68k_areg(regs, 7) -= 2; + put_word(m68k_areg(regs, 7), M68K_EXEC_RETURN); + m68k_areg(regs, 7) -= 4; + put_long(m68k_areg(regs, 7), m68k_areg(regs, 7) + 4); + + // Execute routine + m68k_setpc(addr); + fill_prefetch_0(); + quit_program = 0; + m68k_execute(); + + // Clean up stack + m68k_areg(regs, 7) += 2; + + // Restore old PC + m68k_setpc(oldpc); + fill_prefetch_0(); + + // Get registers + for (i=0; i<8; i++) + r->d[i] = m68k_dreg(regs, i); + for (i=0; i<7; i++) + r->a[i] = m68k_areg(regs, i); + quit_program = 0; +} + +void report_double_bus_error() +{ +#if 0 + panicbug("CPU: Double bus fault detected !"); + /* would be cool to open SDL dialog here: */ + /* [Double bus fault detected. The emulated system crashed badly. + Do you want to reset ARAnyM or quit ?] [Reset] [Quit]" + */ + panicbug(CPU_MSG); + CPU_ACTION; +#endif +} diff --git a/BasiliskII/src/uae_cpu_2021/build68k.c b/BasiliskII/src/uae_cpu_2021/build68k.c new file mode 100644 index 000000000..e996758d0 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/build68k.c @@ -0,0 +1,292 @@ +/* + * build68k.c - m68k CPU builder + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * UAE - The Un*x Amiga Emulator + * + * Read 68000 CPU specs from file "table68k" and build table68k.c + * + * Copyright 1995,1996 Bernd Schmidt + */ + +#include "readcpu.h" + +#include +#include +#include +#include +#include +#undef abort + +static FILE *tablef; +static int nextch = 0; + +static void getnextch(void) +{ + do { + nextch = fgetc(tablef); + if (nextch == '%') { + do { + nextch = fgetc(tablef); + } while (nextch != EOF && nextch != '\n'); + } + } while (nextch != EOF && isspace(nextch)); +} + +static int nextchtohex(void) +{ + switch (isupper (nextch) ? tolower (nextch) : nextch) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'a': return 10; + case 'b': return 11; + case 'c': return 12; + case 'd': return 13; + case 'e': return 14; + case 'f': return 15; + default: abort(); + } +} + +int main() +{ + int no_insns = 0; + + printf ("#include \"sysdeps.h\"\n"); + printf ("#include \"readcpu.h\"\n"); + printf ("struct instr_def defs68k[] = {\n"); +#if 0 + tablef = fopen("table68k","r"); + if (tablef == NULL) { + fprintf(stderr, "table68k not found\n"); + exit(1); + } +#else + tablef = stdin; +#endif + getnextch(); + while (nextch != EOF) { + int cpulevel, plevel, sduse; + int i; + + char patbits[16]; + char opcstr[256]; + int bitpos[16]; + int flagset[5], flaguse[5]; + char cflow; + + unsigned int bitmask,bitpattern; + int n_variable; + + n_variable = 0; + bitmask = bitpattern = 0; + memset (bitpos, 0, sizeof(bitpos)); + for(i=0; i<16; i++) { + int currbit; + bitmask <<= 1; + bitpattern <<= 1; + + switch (nextch) { + case '0': currbit = bit0; bitmask |= 1; break; + case '1': currbit = bit1; bitmask |= 1; bitpattern |= 1; break; + case 'c': currbit = bitc; break; + case 'C': currbit = bitC; break; + case 'f': currbit = bitf; break; + case 'i': currbit = biti; break; + case 'I': currbit = bitI; break; + case 'j': currbit = bitj; break; + case 'J': currbit = bitJ; break; + case 'k': currbit = bitk; break; + case 'K': currbit = bitK; break; + case 's': currbit = bits; break; + case 'S': currbit = bitS; break; + case 'd': currbit = bitd; break; + case 'D': currbit = bitD; break; + case 'r': currbit = bitr; break; + case 'R': currbit = bitR; break; + case 'z': currbit = bitz; break; + case 'E': currbit = bitE; break; + case 'p': currbit = bitp; break; + default: abort(); + } + if (!(bitmask & 1)) { + bitpos[n_variable] = currbit; + n_variable++; + } + + if (nextch == '0' || nextch == '1') + bitmask |= 1; + if (nextch == '1') + bitpattern |= 1; + patbits[i] = nextch; + getnextch(); + } + (void) patbits; + + while (isspace(nextch) || nextch == ':') /* Get CPU and privilege level */ + getnextch(); + + switch (nextch) { + case '0': cpulevel = 0; break; + case '1': cpulevel = 1; break; + case '2': cpulevel = 2; break; + case '3': cpulevel = 3; break; + case '4': cpulevel = 4; break; + case '5': cpulevel = 5; break; + default: abort(); + } + getnextch(); + + switch (nextch) { + case '0': plevel = 0; break; + case '1': plevel = 1; break; + case '2': plevel = 2; break; + case '3': plevel = 3; break; + default: abort(); + } + getnextch(); + + while (isspace(nextch)) /* Get flag set information */ + getnextch(); + + if (nextch != ':') + abort(); + + for(i = 0; i < 5; i++) { + getnextch(); + switch(nextch){ + case '-': flagset[i] = fa_unset; break; + case '/': flagset[i] = fa_isjmp; break; + case '+': flagset[i] = fa_isbranch; break; + case '0': flagset[i] = fa_zero; break; + case '1': flagset[i] = fa_one; break; + case 'x': flagset[i] = fa_dontcare; break; + case '?': flagset[i] = fa_unknown; break; + default: flagset[i] = fa_set; break; + } + } + + getnextch(); + while (isspace(nextch)) + getnextch(); + + if (nextch != ':') /* Get flag used information */ + abort(); + + for(i = 0; i < 5; i++) { + getnextch(); + switch(nextch){ + case '-': flaguse[i] = fu_unused; break; + case '/': flaguse[i] = fu_isjmp; break; + case '+': flaguse[i] = fu_maybecc; break; + case '?': flaguse[i] = fu_unknown; break; + default: flaguse[i] = fu_used; break; + } + } + + getnextch(); + while (isspace(nextch)) + getnextch(); + + if (nextch != ':') /* Get control flow information */ + abort(); + + cflow = 0; + for(i = 0; i < 2; i++) { + getnextch(); + switch(nextch){ + case '-': break; + case 'R': cflow |= fl_return; break; + case 'B': cflow |= fl_branch; break; + case 'J': cflow |= fl_jump; break; + case 'T': cflow |= fl_trap; break; + default: abort(); + } + } + + getnextch(); + while (isspace(nextch)) + getnextch(); + + if (nextch != ':') /* Get source/dest usage information */ + abort(); + + getnextch(); + sduse = nextchtohex() << 4; + getnextch(); + sduse |= nextchtohex(); + + getnextch(); + while (isspace(nextch)) + getnextch(); + + if (nextch != ':') + abort(); + + assert(fgets(opcstr, 250, tablef) != NULL); + getnextch(); + { + int j; + /* Remove superfluous spaces from the string */ + char *opstrp = opcstr, *osendp; + int slen = 0; + + while (isspace((int)*opstrp)) + opstrp++; + + osendp = opstrp; + while (*osendp) { + if (!isspace ((int)*osendp)) + slen = osendp - opstrp + 1; + osendp++; + } + opstrp[slen] = 0; + + if (no_insns > 0) + printf(",\n"); + no_insns++; + printf("{ %d, %d, {", bitpattern, n_variable); + for (j = 0; j < 16; j++) { + printf("%d", bitpos[j]); + if (j < 15) + printf(","); + } + printf ("}, %d, %d, %d, { ", bitmask, cpulevel, plevel); + for(i = 0; i < 5; i++) { + printf("{ %d, %d }%c ", flaguse[i], flagset[i], i == 4 ? ' ' : ','); + } + printf("}, %d, %d, \"%s\"}", cflow, sduse, opstrp); + } + } + printf("};\nint n_defs68k = %d;\n", no_insns); + return 0; +} diff --git a/BasiliskII/src/uae_cpu_2021/compiler/codegen_x86.cpp b/BasiliskII/src/uae_cpu_2021/compiler/codegen_x86.cpp new file mode 100644 index 000000000..22c010804 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/codegen_x86.cpp @@ -0,0 +1,3292 @@ +/* + * compiler/codegen_x86.cpp - IA-32 and AMD64 code generator + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * 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 + */ + +/* This should eventually end up in machdep/, but for now, x86 is the + only target, and it's easier this way... */ + +#include "flags_x86.h" + +/************************************************************************* + * Some basic information about the the target CPU * + *************************************************************************/ + +#define R1 RR1 +#define R2 RR2 +#define R4 RR4 + +#define EAX_INDEX 0 +#define ECX_INDEX 1 +#define EDX_INDEX 2 +#define EBX_INDEX 3 +#define ESP_INDEX 4 +#define EBP_INDEX 5 +#define ESI_INDEX 6 +#define EDI_INDEX 7 +#if defined(CPU_x86_64) +#define R8_INDEX 8 +#define R9_INDEX 9 +#define R10_INDEX 10 +#define R11_INDEX 11 +#define R12_INDEX 12 +#define R13_INDEX 13 +#define R14_INDEX 14 +#define R15_INDEX 15 +#endif +/* XXX this has to match X86_Reg8H_Base + 4 */ +#define AH_INDEX (0x10+4+EAX_INDEX) +#define CH_INDEX (0x10+4+ECX_INDEX) +#define DH_INDEX (0x10+4+EDX_INDEX) +#define BH_INDEX (0x10+4+EBX_INDEX) + +/* The register in which subroutines return an integer return value */ +#define REG_RESULT EAX_INDEX + +/* The registers subroutines take their first and second argument in */ +#ifdef _WIN32 +/* Handle the _fastcall parameters of ECX and EDX */ +#define REG_PAR1 ECX_INDEX +#define REG_PAR2 EDX_INDEX +#elif defined(CPU_x86_64) +#define REG_PAR1 EDI_INDEX +#define REG_PAR2 ESI_INDEX +#else +#define REG_PAR1 EAX_INDEX +#define REG_PAR2 EDX_INDEX +#endif + +#define REG_PC_PRE EAX_INDEX /* The register we use for preloading regs.pc_p */ +#ifdef _WIN32 +#define REG_PC_TMP ECX_INDEX +#else +#define REG_PC_TMP ECX_INDEX /* Another register that is not the above */ +#endif + +#define SHIFTCOUNT_NREG ECX_INDEX /* Register that can be used for shiftcount. + -1 if any reg will do */ +#define MUL_NREG1 EAX_INDEX /* %eax will hold the low 32 bits after a 32x32 mul */ +#define MUL_NREG2 EDX_INDEX /* %edx will hold the high 32 bits */ + +#define STACK_ALIGN 16 +#define STACK_OFFSET sizeof(void *) +#ifdef _WIN64 +/* In the Microsoft x64 calling convention, it's the caller's responsibility + * to allocate 32 bytes of "shadow space" on the stack right before calling + * the function (regardless of the actual number of parameters used). */ +#define STACK_SHADOW_SPACE 32 +#else +#define STACK_SHADOW_SPACE 0 +#endif + +#if defined(CPU_x86_64) +#ifdef UAE +/* Register R12 (and ESP) cannot be used with simple [r/m + disp32] addressing, + * since r/m bits 100 implies SIB byte. Simplest fix is to not use these + * registers. Also note that these registers are listed in the freescratch + * function as well. */ +uae_s8 always_used[] = { ESP_INDEX, R12_INDEX, -1 }; +#else +uae_s8 always_used[] = { ESP_INDEX, -1 }; +#endif +uae_s8 can_byte[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1}; +uae_s8 can_word[]={0,1,2,3,5,6,7,8,9,10,11,12,13,14,15,-1}; +#else +uae_s8 always_used[] = { ESP_INDEX, -1 }; +uae_s8 can_byte[]={0,1,2,3,-1}; +uae_s8 can_word[]={0,1,2,3,5,6,7,-1}; +#endif +static bool have_lahf_lm = true; // target has LAHF supported in long mode ? + +#if USE_OPTIMIZED_CALLS +/* Make sure interpretive core does not use cpuopti */ +uae_u8 call_saved[]={0,0,0,1,1,1,1,1}; +#error FIXME: code not ready +#else +/* cpuopti mutate instruction handlers to assume registers are saved + by the caller */ +uae_u8 call_saved[]={0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; +#endif + +/* This *should* be the same as call_saved. But: + - We might not really know which registers are saved, and which aren't, + so we need to preserve some, but don't want to rely on everyone else + also saving those registers + - Special registers (such like the stack pointer) should not be "preserved" + by pushing, even though they are "saved" across function calls +*/ +#if defined(CPU_x86_64) +#ifdef _WIN64 +/* https://msdn.microsoft.com/en-us/library/6t169e9c.aspx: + * "The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are + * considered nonvolatile and must be saved and restored by a function that + * uses them". Also saving r11 for now (see comment below). */ +static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,1,1,0,0,0,1,1,1,1,1}; +#else +/* callee-saved registers as defined by Linux AMD64 ABI: rbx, rbp, rsp, r12 - r15 */ +/* preserve r11 because it's generally used to hold pointers to functions */ +/* FIXME: not really sure what the point of saving r11 is (??). If functions + * cannot assume calle preserves it, it will not be used across calls anyway? */ +static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1}; +#endif +#else +/* callee-saved registers as defined by System V IA-32 ABI: edi, esi, ebx, ebp */ +static const uae_u8 need_to_preserve[]={0,0,0,1,0,1,1,1}; +#endif + +/* Whether classes of instructions do or don't clobber the native flags */ +#define CLOBBER_MOV +#define CLOBBER_LEA +#define CLOBBER_CMOV +#define CLOBBER_POP +#define CLOBBER_PUSH +#define CLOBBER_SUB clobber_flags() +#define CLOBBER_SBB clobber_flags() +#define CLOBBER_CMP clobber_flags() +#define CLOBBER_ADD clobber_flags() +#define CLOBBER_ADC clobber_flags() +#define CLOBBER_AND clobber_flags() +#define CLOBBER_OR clobber_flags() +#define CLOBBER_XOR clobber_flags() + +#define CLOBBER_ROL clobber_flags() +#define CLOBBER_ROR clobber_flags() +#define CLOBBER_SHLL clobber_flags() +#define CLOBBER_SHRL clobber_flags() +#define CLOBBER_SHRA clobber_flags() +#define CLOBBER_TEST clobber_flags() +#define CLOBBER_CL16 +#define CLOBBER_CL8 +#define CLOBBER_SE32 +#define CLOBBER_SE16 +#define CLOBBER_SE8 +#define CLOBBER_ZE32 +#define CLOBBER_ZE16 +#define CLOBBER_ZE8 +#define CLOBBER_SW16 clobber_flags() +#define CLOBBER_SW32 +#define CLOBBER_SETCC +#define CLOBBER_MUL clobber_flags() +#define CLOBBER_BT clobber_flags() +#define CLOBBER_BSF clobber_flags() + +#if defined(CPU_x86_64) +#define X86_TARGET_64BIT 1 +/* The address override prefix causes a 5 cycles penalty on Intel Core + processors. Another solution would be to decompose the load in an LEA, + MOV (to zero-extend), MOV (from memory): is it better? */ +#define ADDR32 x86_emit_byte(0x67), +#else +#define ADDR32 +#endif +#define X86_FLAT_REGISTERS 0 +#define X86_OPTIMIZE_ALU 1 +#define X86_OPTIMIZE_ROTSHI 1 +#include "codegen_x86.h" + +#define x86_emit_byte(B) emit_byte(B) +#define x86_emit_word(W) emit_word(W) +#define x86_emit_long(L) emit_long(L) +#define x86_emit_quad(Q) emit_quad(Q) +#define x86_get_target() get_target() +#define x86_emit_failure(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__) + +static inline void x86_64_addr32(void) +{ +#ifdef CPU_x86_64 + emit_byte(0x67); +#endif +} + +static inline void x86_64_rex(bool /* w */, uae_u32 * /* r */, uae_u32 * /* x */, uae_u32 *b) +{ +#ifdef CPU_x86_64 + int rex_byte = 0x40; + if (*b >= R8_INDEX) { + *b -= R8_INDEX; + rex_byte |= 1; + } + if (rex_byte != 0x40) { + emit_byte(rex_byte); + } +#else + UNUSED(b); +#endif +} + +static inline void x86_64_prefix( + bool addr32, bool w, uae_u32 *r, uae_u32 *x, uae_u32 *b) +{ + if (addr32) { + x86_64_addr32(); + } + x86_64_rex(w, r, x, b); +} + +// Some mappings to mark compemu_support calls as only used by compemu +// These are still mainly x86 minded. Should be more CPU independent in the future +#define compemu_raw_add_l_mi(a,b) raw_add_l_mi(a,b) +#define compemu_raw_and_l_ri(a,b) raw_and_l_ri(a,b) +#define compemu_raw_bswap_32(a) raw_bswap_32(a) +#define compemu_raw_bt_l_ri(a,b) raw_bt_l_ri(a,b) +#define compemu_raw_call(a) raw_call(a) +#define compemu_raw_cmov_l_rm_indexed(a,b,c,d,e) raw_cmov_l_rm_indexed(a,b,c,d,e) +#define compemu_raw_cmp_l_mi(a,b) raw_cmp_l_mi(a,b) +#define compemu_raw_cmp_l_mi8(a,b) raw_cmp_l_mi(a,b) +#define compemu_raw_jcc_b_oponly(a) raw_jcc_b_oponly(a) +#define compemu_raw_jcc_l_oponly(a) raw_jcc_l_oponly(a) +#define compemu_raw_jl(a) raw_jl(a) +#define compemu_raw_jmp(a) raw_jmp(a) +#define compemu_raw_jmp_m_indexed(a,b,c) raw_jmp_m_indexed(a,b,c) +#define compemu_raw_jmp_r(a) raw_jmp_r(a) +#define compemu_raw_jnz(a) raw_jnz(a) +#define compemu_raw_jz_b_oponly() raw_jz_b_oponly() +#define compemu_raw_jnz_b_oponly() raw_jnz_b_oponly() +#define compemu_raw_lea_l_brr(a,b,c) raw_lea_l_brr(a,b,c) +#define compemu_raw_lea_l_brr_indexed(a,b,c,d,e) raw_lea_l_brr_indexed(a,b,c,d,e) +#define compemu_raw_mov_b_mr(a,b) raw_mov_b_mr(a,b) +#define compemu_raw_mov_l_mi(a,b) raw_mov_l_mi(a,b) +#define compemu_raw_mov_l_mr(a,b) raw_mov_l_mr(a,b) +#define compemu_raw_mov_l_ri(a,b) raw_mov_l_ri(a,b) +#define compemu_raw_mov_l_rm(a,b) raw_mov_l_rm(a,b) +#define compemu_raw_mov_l_rr(a,b) raw_mov_l_rr(a,b) +#define compemu_raw_mov_w_mr(a,b) raw_mov_w_mr(a,b) +#define compemu_raw_sub_l_mi(a,b) raw_sub_l_mi(a,b) +#define compemu_raw_test_l_rr(a,b) raw_test_l_rr(a,b) +#define compemu_raw_zero_extend_16_rr(a,b) raw_zero_extend_16_rr(a,b) +#define compemu_raw_lea_l_rr_indexed(a,b,c,d) raw_lea_l_rr_indexed(a,b,c,d) + +static void jit_fail(const char *msg, const char *file, int line, const char *function) +{ + jit_abort("failure in function %s from file %s at line %d: %s", + function, file, line, msg); +} + +LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r)) +{ +#if defined(CPU_x86_64) + PUSHQr(r); +#else + PUSHLr(r); +#endif +} + +LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r)) +{ +#if defined(CPU_x86_64) + POPQr(r); +#else + POPLr(r); +#endif +} + +LOWFUNC(NONE,READ,1,raw_pop_l_m,(MEMW d)) +{ +#if defined(CPU_x86_64) + POPQm(d, X86_NOREG, X86_NOREG, 1); +#else + POPLm(d, X86_NOREG, X86_NOREG, 1); +#endif +} + +LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i)) +{ + BTLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b)) +{ + BTLrr(b, r); +} + +LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i)) +{ + BTCLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b)) +{ + BTCLrr(b, r); +} + +LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i)) +{ + BTRLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b)) +{ + BTRLrr(b, r); +} + +LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i)) +{ + BTSLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b)) +{ + BTSLrr(b, r); +} + +LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i)) +{ + SUBWir(i, d); +} + +LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s)) +{ + ADDR32 MOVLmr(s, X86_NOREG, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s)) +{ + ADDR32 MOVLim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s)) +{ + ADDR32 MOVWim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s)) +{ + ADDR32 MOVBim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i)) +{ + ADDR32 ROLBim(i, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i)) +{ + ROLBir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i)) +{ + ROLWir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i)) +{ + ROLLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r)) +{ + ROLLrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r)) +{ + ROLWrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r)) +{ + ROLBrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r)) +{ + SHLLrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r)) +{ + SHLWrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r)) +{ + SHLBrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i)) +{ + RORBir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i)) +{ + RORWir(i, r); +} + +LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s)) +{ + ADDR32 ORLmr(s, X86_NOREG, X86_NOREG, 1, d); +} + +LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i)) +{ + RORLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r)) +{ + RORLrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r)) +{ + RORWrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r)) +{ + RORBrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r)) +{ + SHRLrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r)) +{ + SHRWrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r)) +{ + SHRBrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r)) +{ + SARLrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r)) +{ + SARWrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r)) +{ + SARBrr(r, d); +} + +LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i)) +{ + SHLLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i)) +{ + SHLWir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i)) +{ + SHLBir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i)) +{ + SHRLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i)) +{ + SHRWir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i)) +{ + SHRBir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i)) +{ + SARLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i)) +{ + SARWir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i)) +{ + SARBir(i, r); +} + +LOWFUNC(WRITE,NONE,1,raw_sahf,(R2)) +{ + SAHF(); +} + +LOWFUNC(NONE,NONE,1,raw_cpuid,(R4)) +{ + CPUID(); +} + +LOWFUNC(READ,NONE,1,raw_lahf,(W2)) +{ + LAHF(); +} + +LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc)) +{ + SETCCir(cc, d); +} + +LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc)) +{ + ADDR32 SETCCim(cc, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc)) +{ + if (have_cmov) + CMOVLrr(cc, s, d); + else { /* replacement using branch and mov */ + uae_s8 *target_p = (uae_s8 *)x86_get_target() + 1; + JCCSii(cc^1, 0); + MOVLrr(s, d); + *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); + } +} + +LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s)) +{ + BSFLrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_sign_extend_32_rr,(W4 d, R4 s)) +{ + MOVSLQrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s)) +{ + MOVSWLrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s)) +{ + MOVSBLrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s)) +{ + MOVZWLrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s)) +{ + MOVZBLrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s)) +{ + IMULLrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s)) +{ + if (d!=MUL_NREG1 || s!=MUL_NREG2) { + jit_abort("Bad register in IMUL: d=%d, s=%d",d,s); + } + IMULLr(s); +} + +LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s)) +{ + if (d!=MUL_NREG1 || s!=MUL_NREG2) { + jit_abort("Bad register in MUL: d=%d, s=%d",d,s); + } + MULLr(s); +} + +LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4, R4)) +{ + x86_emit_failure("raw_mul_32_32"); /* %^$&%^$%#^ x86! */ +} + +LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s)) +{ + MOVBrr(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s)) +{ + MOVWrr(s, d); +} + +LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor)) +{ + ADDR32 MOVLmr(0, baser, index, factor, d); +} + +LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor)) +{ + ADDR32 MOVWmr(0, baser, index, factor, d); +} + +LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor)) +{ + ADDR32 MOVBmr(0, baser, index, factor, d); +} + +LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s)) +{ + ADDR32 MOVLrm(s, 0, baser, index, factor); +} + +LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s)) +{ + ADDR32 MOVWrm(s, 0, baser, index, factor); +} + +LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s)) +{ + ADDR32 MOVBrm(s, 0, baser, index, factor); +} + +LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s)) +{ + ADDR32 MOVLrm(s, base, baser, index, factor); +} + +LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s)) +{ + ADDR32 MOVWrm(s, base, baser, index, factor); +} + +LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s)) +{ + ADDR32 MOVBrm(s, base, baser, index, factor); +} + +LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor)) +{ + ADDR32 MOVLmr(base, baser, index, factor, d); +} + +LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor)) +{ + ADDR32 MOVWmr(base, baser, index, factor, d); +} + +LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor)) +{ + ADDR32 MOVBmr(base, baser, index, factor, d); +} + +LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor)) +{ + ADDR32 MOVLmr(base, X86_NOREG, index, factor, d); +} + +LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond)) +{ + if (have_cmov) + ADDR32 CMOVLmr(cond, base, X86_NOREG, index, factor, d); + else { /* replacement using branch and mov */ + uae_s8 *target_p = (uae_s8 *)x86_get_target() + 1; + JCCSii(cond^1, 0); + ADDR32 MOVLmr(base, X86_NOREG, index, factor, d); + *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); + } +} + +LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond)) +{ + if (have_cmov) + CMOVLmr(cond, mem, X86_NOREG, X86_NOREG, 1, d); + else { /* replacement using branch and mov */ + uae_s8 *target_p = (uae_s8 *)x86_get_target() + 1; + JCCSii(cond^1, 0); + ADDR32 MOVLmr(mem, X86_NOREG, X86_NOREG, 1, d); + *target_p = (uintptr)x86_get_target() - ((uintptr)target_p + 1); + } +} + +LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset)) +{ + ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset)) +{ + ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset)) +{ + ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset)) +{ + ADDR32 MOVLmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset)) +{ + ADDR32 MOVWmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset)) +{ + ADDR32 MOVBmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset)) +{ + ADDR32 MOVLim(i, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset)) +{ + ADDR32 MOVWim(i, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset)) +{ + ADDR32 MOVBim(i, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset)) +{ + ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset)) +{ + ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset)) +{ + ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset)) +{ + ADDR32 LEALmr(offset, s, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset)) +{ + ADDR32 LEALmr(offset, s, index, factor, d); +} + +LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor)) +{ + ADDR32 LEALmr(0, s, index, factor, d); +} + +LOWFUNC(NONE,NONE,4,raw_lea_l_r_scaled,(W4 d, R4 index, IMM factor)) +{ + ADDR32 LEALmr(0, X86_NOREG, index, factor, d); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset)) +{ + ADDR32 MOVLrm(s, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset)) +{ + ADDR32 MOVWrm(s, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset)) +{ + ADDR32 MOVBrm(s, offset, d, X86_NOREG, 1); +} + +LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r)) +{ + BSWAPLr(r); +} + +LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r)) +{ + ROLWir(8, r); +} + +LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s)) +{ + MOVLrr(s, d); +} + +LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s)) +{ + ADDR32 MOVLrm(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s)) +{ + ADDR32 MOVWrm(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s)) +{ + ADDR32 MOVWmr(s, X86_NOREG, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s)) +{ + ADDR32 MOVBrm(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s)) +{ + ADDR32 MOVBmr(s, X86_NOREG, X86_NOREG, 1, d); +} + +LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s)) +{ + MOVLir(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s)) +{ + MOVWir(s, d); +} + +LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s)) +{ + MOVBir(s, d); +} + +LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s)) +{ + ADDR32 ADCLim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s)) +{ + ADDR32 ADDLim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s)) +{ + ADDR32 ADDWim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s)) +{ + ADDR32 ADDBim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i)) +{ + TESTLir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s)) +{ + TESTLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s)) +{ + TESTWrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s)) +{ + TESTBrr(s, d); +} + +LOWFUNC(WRITE,READ,2,raw_test_b_mi,(IMM d, IMM s)) +{ + ADDR32 TESTBim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i)) +{ + XORLir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i)) +{ + ANDLir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i)) +{ + ANDWir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s)) +{ + ANDLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s)) +{ + ANDWrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s)) +{ + ANDBrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i)) +{ + ORLir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s)) +{ + ORLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s)) +{ + ORWrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s)) +{ + ORBrr(s, d); +} + +LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s)) +{ + ADCLrr(s, d); +} + +LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s)) +{ + ADCWrr(s, d); +} + +LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s)) +{ + ADCBrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s)) +{ + ADDLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s)) +{ + ADDWrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s)) +{ + ADDBrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i)) +{ + SUBLir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i)) +{ + SUBBir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i)) +{ + ADDLir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i)) +{ + ADDWir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i)) +{ + ADDBir(i, d); +} + +LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s)) +{ + SBBLrr(s, d); +} + +LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s)) +{ + SBBWrr(s, d); +} + +LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s)) +{ + SBBBrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s)) +{ + SUBLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s)) +{ + SUBWrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s)) +{ + SUBBrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s)) +{ + CMPLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i)) +{ + CMPLir(i, r); +} + +LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s)) +{ + CMPWrr(s, d); +} + +LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s)) +{ + ADDR32 CMPBim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i)) +{ + CMPBir(i, d); +} + +LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s)) +{ + CMPBrr(s, d); +} + +LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor)) +{ + ADDR32 CMPLmr(offset, X86_NOREG, index, factor, d); +} + +LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s)) +{ + XORLrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s)) +{ + XORWrr(s, d); +} + +LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s)) +{ + XORBrr(s, d); +} + +LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s)) +{ + ADDR32 SUBLim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s)) +{ + ADDR32 CMPLim(s, d, X86_NOREG, X86_NOREG, 1); +} + +LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2)) +{ + XCHGLrr(r2, r1); +} + +LOWFUNC(NONE,NONE,2,raw_xchg_b_rr,(RW4 r1, RW4 r2)) +{ + XCHGBrr(r2, r1); +} + +LOWFUNC(READ,WRITE,0,raw_pushfl,(void)) +{ + PUSHF(); +} + +LOWFUNC(WRITE,READ,0,raw_popfl,(void)) +{ + POPF(); +} + +/* Generate floating-point instructions */ +static inline void x86_fadd_m(MEMR s) +{ + ADDR32 FADDLm(s,X86_NOREG,X86_NOREG,1); +} + + +/************************************************************************* + * Unoptimizable stuff --- jump * + *************************************************************************/ + +static inline void raw_call_r(R4 r) +{ + CALLsr(r); +} + +static inline void raw_call_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m) +{ + ADDR32 CALLsm(base, X86_NOREG, r, m); +} + +static inline void raw_jmp_r(R4 r) +{ + JMPsr(r); +} + +static inline void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m) +{ + ADDR32 JMPsm(base, X86_NOREG, r, m); +} + +static inline void raw_jmp_m(uae_u32 base) +{ + emit_byte(0xff); + emit_byte(0x25); + emit_long(base); +} + + +static inline void raw_call(uae_u32 t) +{ + ADDR32 CALLm(t); +} + +static inline void raw_jmp(uae_u32 t) +{ + ADDR32 JMPm(t); +} + +static inline void raw_jcc_l_oponly(int cc) +{ + emit_byte(0x0f); + emit_byte(0x80+cc); +} + +static inline void raw_jz_l_oponly(void) +{ + raw_jcc_l_oponly(NATIVE_CC_EQ); +} + +static inline void raw_jnz_l_oponly(void) +{ + raw_jcc_l_oponly(NATIVE_CC_NE); +} + +static inline void raw_jl(uae_u32 t) +{ + raw_jcc_l_oponly(NATIVE_CC_LT); + emit_long(t-(uintptr)target-4); +} + +static inline void raw_jz(uae_u32 t) +{ + raw_jz_l_oponly(); + emit_long(t-(uintptr)target-4); +} + +static inline void raw_jnz(uae_u32 t) +{ + raw_jnz_l_oponly(); + emit_long(t-(uintptr)target-4); +} + +static inline void raw_jcc_b_oponly(int cc) +{ + emit_byte(0x70+cc); +} + +static inline void raw_jnz_b_oponly(void) +{ + raw_jcc_b_oponly(NATIVE_CC_NE); +} + +static inline void raw_jz_b_oponly(void) +{ + raw_jcc_b_oponly(NATIVE_CC_EQ); +} + +static inline void raw_jmp_l_oponly(void) +{ + emit_byte(0xe9); +} + +static inline void raw_jmp_b_oponly(void) +{ + emit_byte(0xeb); +} + +static inline void raw_ret(void) +{ + emit_byte(0xc3); +} + +static inline void raw_emit_nop(void) +{ + emit_byte(0x90); +} + +static inline void raw_emit_nop_filler(int nbytes) +{ + +#if defined(CPU_x86_64) + /* The recommended way to pad 64bit code is to use NOPs preceded by + maximally four 0x66 prefixes. Balance the size of nops. */ + static const uae_u8 prefixes[4] = { 0x66, 0x66, 0x66, 0x66 }; + if (nbytes == 0) + return; + + int i; + int nnops = (nbytes + 3) / 4; + int len = nbytes / nnops; + int remains = nbytes - nnops * len; + + for (i = 0; i < remains; i++) { + emit_block(prefixes, len); + raw_emit_nop(); + } + for (; i < nnops; i++) { + emit_block(prefixes, len - 1); + raw_emit_nop(); + } +#else + /* Source: GNU Binutils 2.12.90.0.15 */ + /* Various efficient no-op patterns for aligning code labels. + Note: Don't try to assemble the instructions in the comments. + 0L and 0w are not legal. */ + static const uae_u8 f32_1[] = + {0x90}; /* nop */ + static const uae_u8 f32_2[] = + {0x89,0xf6}; /* movl %esi,%esi */ + static const uae_u8 f32_3[] = + {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */ + static const uae_u8 f32_4[] = + {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ + static const uae_u8 f32_5[] = + {0x90, /* nop */ + 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ + static const uae_u8 f32_6[] = + {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */ + static const uae_u8 f32_7[] = + {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ + static const uae_u8 f32_8[] = + {0x90, /* nop */ + 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ + static const uae_u8 f32_9[] = + {0x89,0xf6, /* movl %esi,%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const uae_u8 f32_10[] = + {0x8d,0x76,0x00, /* leal 0(%esi),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const uae_u8 f32_11[] = + {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const uae_u8 f32_12[] = + {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ + 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */ + static const uae_u8 f32_13[] = + {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const uae_u8 f32_14[] = + {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const uae_u8 f32_15[] = + {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */ + 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; + static const uae_u8 f32_16[] = + {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */ + 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; + static const uae_u8 *const f32_patt[] = { + f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8, + f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15 + }; + + int nloops = nbytes / 16; + while (nloops-- > 0) + emit_block(f32_16, sizeof(f32_16)); + + nbytes %= 16; + if (nbytes) + emit_block(f32_patt[nbytes - 1], nbytes); +#endif +} + + +/************************************************************************* + * Flag handling, to and fro UAE flag register * + *************************************************************************/ + +static inline void raw_flags_evicted(int r) +{ + //live.state[FLAGTMP].status=CLEAN; + live.state[FLAGTMP].status=INMEM; + live.state[FLAGTMP].realreg=-1; + /* We just "evicted" FLAGTMP. */ + if (live.nat[r].nholds!=1) { + /* Huh? */ + abort(); + } + live.nat[r].nholds=0; +} + +#define FLAG_NREG1_FLAGREG EAX_INDEX /* Set to -1 if any register will do */ +static inline void raw_flags_to_reg_FLAGREG(int r) +{ + raw_lahf(0); /* Most flags in AH */ + //raw_setcc(r,0); /* V flag in AL */ + raw_setcc_m((uintptr)live.state[FLAGTMP].mem,0); + +#if 1 /* Let's avoid those nasty partial register stalls */ + //raw_mov_b_mr((uintptr)live.state[FLAGTMP].mem,r); + raw_mov_b_mr(((uintptr)live.state[FLAGTMP].mem)+1,AH_INDEX); + raw_flags_evicted(r); +#endif +} + +#define FLAG_NREG2_FLAGREG EAX_INDEX /* Set to -1 if any register will do */ +static inline void raw_reg_to_flags_FLAGREG(int r) +{ + raw_cmp_b_ri(r,-127); /* set V */ + raw_sahf(0); +} + +#define FLAG_NREG3_FLAGREG EAX_INDEX /* Set to -1 if any register will do */ +static __inline__ void raw_flags_set_zero_FLAGREG(int s, int tmp) +{ + raw_mov_l_rr(tmp,s); + raw_lahf(s); /* flags into ah */ + SETOr(X86_AL); /* V flag into al */ + raw_and_l_ri(s,0xffffbfff); + raw_and_l_ri(tmp,0x00004000); + raw_xor_l_ri(tmp,0x00004000); + raw_or_l(s,tmp); + raw_cmp_b_ri(X86_AL,-127); /* set V */ + raw_sahf(s); +} + +static inline void raw_flags_init_FLAGREG(void) { } + +#define FLAG_NREG1_FLAGSTK -1 /* Set to -1 if any register will do */ +static inline void raw_flags_to_reg_FLAGSTK(int r) +{ + raw_pushfl(); + raw_pop_l_r(r); + raw_mov_l_mr((uintptr)live.state[FLAGTMP].mem,r); + raw_flags_evicted(r); +} + +#define FLAG_NREG2_FLAGSTK -1 /* Set to -1 if any register will do */ +static inline void raw_reg_to_flags_FLAGSTK(int r) +{ + raw_push_l_r(r); + raw_popfl(); +} + +#define FLAG_NREG3_FLAGSTK -1 /* Set to -1 if any register will do */ +static inline void raw_flags_set_zero_FLAGSTK(int s, int tmp) +{ + raw_mov_l_rr(tmp,s); + raw_pushfl(); + raw_pop_l_r(s); + raw_and_l_ri(s,0xffffffbf); + raw_and_l_ri(tmp,0x00000040); + raw_xor_l_ri(tmp,0x00000040); + raw_or_l(s,tmp); + raw_push_l_r(s); + raw_popfl(); +} + +static inline void raw_flags_init_FLAGSTK(void) { } + +#if defined(CPU_x86_64) +/* Try to use the LAHF/SETO method on x86_64 since it is faster. + This can't be the default because some older CPUs don't support + LAHF/SAHF in long mode. */ +static int FLAG_NREG1_FLAGGEN = EAX_INDEX; +static inline void raw_flags_to_reg_FLAGGEN(int r) +{ + if (have_lahf_lm) { + // NOTE: the interpreter uses the normal EFLAGS layout + // pushf/popf CF(0) ZF( 6) SF( 7) OF(11) + // sahf/lahf CF(8) ZF(14) SF(15) OF( 0) + assert(r == 0); + raw_setcc(r,0); /* V flag in AL */ + raw_lea_l_r_scaled(0,0,8); /* move it to its EFLAGS location */ + raw_mov_b_mr(((uintptr)live.state[FLAGTMP].mem)+1,0); + raw_lahf(0); /* most flags in AH */ + raw_mov_b_mr((uintptr)live.state[FLAGTMP].mem,AH_INDEX); + raw_flags_evicted(r); + } + else + raw_flags_to_reg_FLAGSTK(r); +} + +static int FLAG_NREG2_FLAGGEN = EAX_INDEX; +static inline void raw_reg_to_flags_FLAGGEN(int r) +{ + if (have_lahf_lm) { + raw_xchg_b_rr(0,AH_INDEX); + raw_cmp_b_ri(r,-120); /* set V */ + raw_sahf(0); + } + else + raw_reg_to_flags_FLAGSTK(r); +} + +static int FLAG_NREG3_FLAGGEN = EAX_INDEX; +static inline void raw_flags_set_zero_FLAGGEN(int s, int tmp) +{ + if (have_lahf_lm) + raw_flags_set_zero_FLAGREG(s, tmp); + else + raw_flags_set_zero_FLAGSTK(s, tmp); +} + +static inline void raw_flags_init_FLAGGEN(void) +{ + if (have_lahf_lm) { + FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGREG; + FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGREG; + FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGREG; + } + else { + FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGSTK; + FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGSTK; + FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGSTK; + } +} +#endif + +#ifdef SAHF_SETO_PROFITABLE +#define FLAG_SUFFIX FLAGREG +#elif defined CPU_x86_64 +#define FLAG_SUFFIX FLAGGEN +#else +#define FLAG_SUFFIX FLAGSTK +#endif + +#define FLAG_GLUE_2(x, y) x ## _ ## y +#define FLAG_GLUE_1(x, y) FLAG_GLUE_2(x, y) +#define FLAG_GLUE(x) FLAG_GLUE_1(x, FLAG_SUFFIX) + +#define raw_flags_init FLAG_GLUE(raw_flags_init) +#define FLAG_NREG1 FLAG_GLUE(FLAG_NREG1) +#define raw_flags_to_reg FLAG_GLUE(raw_flags_to_reg) +#define FLAG_NREG2 FLAG_GLUE(FLAG_NREG2) +#define raw_reg_to_flags FLAG_GLUE(raw_reg_to_flags) +#define FLAG_NREG3 FLAG_GLUE(FLAG_NREG3) +#define raw_flags_set_zero FLAG_GLUE(raw_flags_set_zero) + +/* Apparently, there are enough instructions between flag store and + flag reload to avoid the partial memory stall */ +static inline void raw_load_flagreg(uae_u32 target) +{ + /* attention: in 64bit mode, relies on LITTE_ENDIANESS of regflags.cznv */ + raw_mov_l_rm(target,(uintptr)live.state[FLAGTMP].mem); +} + +static inline void raw_load_flagx(uae_u32 target) +{ +#if FLAGBIT_X < 8 + if (live.nat[target].canbyte) + raw_mov_b_rm(target,(uintptr)live.state[FLAGX].mem); + else +#endif + if (live.nat[target].canword) + raw_mov_w_rm(target,(uintptr)live.state[FLAGX].mem); + else + raw_mov_l_rm(target,(uintptr)live.state[FLAGX].mem); +} + +static inline void raw_dec_sp(int off) +{ + if (off) { +#ifdef CPU_x86_64 + emit_byte(0x48); /* REX prefix */ +#endif + raw_sub_l_ri(ESP_INDEX,off); + } +} + +static inline void raw_inc_sp(int off) +{ + if (off) { +#ifdef CPU_x86_64 + emit_byte(0x48); /* REX prefix */ +#endif + raw_add_l_ri(ESP_INDEX,off); + } +} + +static inline void raw_push_regs_to_preserve(void) { + for (int i=N_REGS;i--;) { + if (need_to_preserve[i]) + raw_push_l_r(i); + } +} + +static inline void raw_pop_preserved_regs(void) { + for (int i=0;ix86_vendor_id; + + if (!strcmp(v, "GenuineIntel")) + c->x86_vendor = X86_VENDOR_INTEL; + else if (!strcmp(v, "AuthenticAMD")) + c->x86_vendor = X86_VENDOR_AMD; + else if (!strcmp(v, "CyrixInstead")) + c->x86_vendor = X86_VENDOR_CYRIX; + else if (!strcmp(v, "Geode by NSC")) + c->x86_vendor = X86_VENDOR_NSC; + else if (!strcmp(v, "UMC UMC UMC ")) + c->x86_vendor = X86_VENDOR_UMC; + else if (!strcmp(v, "CentaurHauls")) + c->x86_vendor = X86_VENDOR_CENTAUR; + else if (!strcmp(v, "NexGenDriven")) + c->x86_vendor = X86_VENDOR_NEXGEN; + else if (!strcmp(v, "RiseRiseRise")) + c->x86_vendor = X86_VENDOR_RISE; + else if (!strcmp(v, "GenuineTMx86") || !strcmp(v, "TransmetaCPU")) + c->x86_vendor = X86_VENDOR_TRANSMETA; + else + c->x86_vendor = X86_VENDOR_UNKNOWN; +} + +/* + * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. + */ +/* Some CPUID calls want 'count' to be placed in ecx */ +#ifdef __GNUC__ +static void cpuid_count(uae_u32 op, uae_u32 count, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx) +{ + uae_u32 _eax, _ebx, _ecx, _edx; + _eax = op; + _ecx = count; + __asm__ __volatile__( + " movl %0,%%eax \n" + " movl %2,%%ecx \n" + " cpuid \n" + " movl %%eax,%0 \n" + " movl %%ebx,%1 \n" + " movl %%ecx,%2 \n" + " movl %%edx,%3 \n" + : "+m" (_eax), + "=m" (_ebx), + "+m" (_ecx), + "=m" (_edx) + : + : "eax", "ebx", "ecx", "edx"); + *eax = _eax; + *ebx = _ebx; + *ecx = _ecx; + *edx = _edx; +} +#endif + +#ifdef _MSC_VER +#include +static void cpuid_count(uae_u32 op, uae_u32 count, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx) +{ + int cpuinfo[4]; + cpuinfo[0] = op; + cpuinfo[1] = 0; + cpuinfo[2] = count; + cpuinfo[3] = 0; + __cpuidex(cpuinfo, op, count); + *eax = cpuinfo[0]; + *ebx = cpuinfo[1]; + *ecx = cpuinfo[2]; + *edx = cpuinfo[3]; +} +#endif + +static void +cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx) +{ + cpuid_count(op, 0, eax, ebx, ecx, edx); +} + +static void raw_init_cpu(void) +{ + struct cpuinfo_x86 *c = &cpuinfo; + uae_u32 dummy; + + /* Defaults */ + c->x86_processor = X86_PROCESSOR_max; + c->x86_vendor = X86_VENDOR_UNKNOWN; + c->cpuid_level = -1; /* CPUID not detected */ + c->x86_model = c->x86_mask = 0; /* So far unknown... */ + c->x86_vendor_id[0] = '\0'; /* Unset */ + c->x86_hwcap = 0; +#ifdef CPU_x86_64 + c->x86_clflush_size = 64; +#else + c->x86_clflush_size = 32; +#endif + + /* Get vendor name */ + c->x86_vendor_id[12] = '\0'; + cpuid(0x00000000, + (uae_u32 *)&c->cpuid_level, + (uae_u32 *)&c->x86_vendor_id[0], + (uae_u32 *)&c->x86_vendor_id[8], + (uae_u32 *)&c->x86_vendor_id[4]); + x86_get_cpu_vendor(c); + + /* Intel-defined flags: level 0x00000001 */ + c->x86_brand_id = 0; + if ( c->cpuid_level >= 0x00000001 ) { + uae_u32 tfms, brand_id; + cpuid(0x00000001, &tfms, &brand_id, &dummy, &c->x86_hwcap); + c->x86 = (tfms >> 8) & 15; + if (c->x86 == 0xf) + c->x86 += (tfms >> 20) & 0xff; /* extended family */ + c->x86_model = (tfms >> 4) & 15; + if (c->x86_model == 0xf) + c->x86_model |= (tfms >> 12) & 0xf0; /* extended model */ + c->x86_brand_id = brand_id & 0xff; + c->x86_mask = tfms & 15; + if (c->x86_hwcap & (1 << 19)) + { + c->x86_clflush_size = ((brand_id >> 8) & 0xff) * 8; + } + } else { + /* Have CPUID level 0 only - unheard of */ + c->x86 = 4; + } + + /* AMD-defined flags: level 0x80000001 */ + uae_u32 xlvl; + cpuid(0x80000000, &xlvl, &dummy, &dummy, &dummy); + if ( (xlvl & 0xffff0000) == 0x80000000 ) { + if ( xlvl >= 0x80000001 ) { + uae_u32 features, extra_features; + cpuid(0x80000001, &dummy, &dummy, &extra_features, &features); + if (features & (1 << 29)) { + /* Assume x86-64 if long mode is supported */ + c->x86_processor = X86_PROCESSOR_X86_64; + } + if (extra_features & (1 << 0)) + have_lahf_lm = true; + } + } + + /* Canonicalize processor ID */ + switch (c->x86) { + case 3: + c->x86_processor = X86_PROCESSOR_I386; + break; + case 4: + c->x86_processor = X86_PROCESSOR_I486; + break; + case 5: + if (c->x86_vendor == X86_VENDOR_AMD) + c->x86_processor = X86_PROCESSOR_K6; + else + c->x86_processor = X86_PROCESSOR_PENTIUM; + break; + case 6: + if (c->x86_vendor == X86_VENDOR_AMD) + c->x86_processor = X86_PROCESSOR_ATHLON; + else + c->x86_processor = X86_PROCESSOR_PENTIUMPRO; + break; + case 15: + if (c->x86_processor == X86_PROCESSOR_max) { + switch (c->x86_vendor) { + case X86_VENDOR_INTEL: + c->x86_processor = X86_PROCESSOR_PENTIUM4; + break; + case X86_VENDOR_AMD: + /* Assume a 32-bit Athlon processor if not in long mode */ + c->x86_processor = X86_PROCESSOR_ATHLON; + break; + } + } + break; + } + if (c->x86_processor == X86_PROCESSOR_max) { + c->x86_processor = X86_PROCESSOR_I386; + jit_log("Error: unknown processor type"); + jit_log(" Family : %d", c->x86); + jit_log(" Model : %d", c->x86_model); + jit_log(" Mask : %d", c->x86_mask); + jit_log(" Vendor : %s [%d]", c->x86_vendor_id, c->x86_vendor); + if (c->x86_brand_id) + { + jit_log(" BrandID : %02x", c->x86_brand_id); + } + } + + /* Have CMOV support? */ + have_cmov = (c->x86_hwcap & (1 << 15)) != 0; +#if defined(CPU_x86_64) + if (!have_cmov) { + jit_abort("x86-64 implementations are bound to have CMOV!"); + } +#endif + + c->x86_has_xmm2 = (c->x86_hwcap & (1 << 26)) != 0; + + /* Can the host CPU suffer from partial register stalls? */ + // non-RAT_STALL mode is currently broken + have_rat_stall = true; //(c->x86_vendor == X86_VENDOR_INTEL); +#if 0 + /* It appears that partial register writes are a bad idea even on + AMD K7 cores, even though they are not supposed to have the + dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */ + if (c->x86_processor == X86_PROCESSOR_ATHLON) + have_rat_stall = true; +#endif + + /* Alignments */ + if (tune_alignment) { + align_loops = x86_alignments[c->x86_processor].align_loop; + align_jumps = x86_alignments[c->x86_processor].align_jump; + } + + jit_log(" : Max CPUID level=%d Processor is %s [%s]", + c->cpuid_level, c->x86_vendor_id, + x86_processor_string_table[c->x86_processor]); + + raw_flags_init(); +} + +#ifndef UAE +static void __attribute__((noinline)) prevent_redzone_use(void) {} + +static bool target_check_bsf(void) +{ + bool mismatch = false; + for (int g_ZF = 0; g_ZF <= 1; g_ZF++) { + for (int g_CF = 0; g_CF <= 1; g_CF++) { + for (int g_OF = 0; g_OF <= 1; g_OF++) { + for (int g_SF = 0; g_SF <= 1; g_SF++) { + for (int value = -1; value <= 1; value++) { + uintptr flags = (g_SF << 7) | (g_OF << 11) | (g_ZF << 6) | g_CF; + intptr tmp = value; + prevent_redzone_use(); + __asm__ __volatile__ ("push %0; popf; bsf %1,%1; pushf; pop %0" + : "+r" (flags), "+r" (tmp) : : "cc"); + int OF = (flags >> 11) & 1; + int SF = (flags >> 7) & 1; + int ZF = (flags >> 6) & 1; + int CF = flags & 1; + tmp = (value == 0); + if (ZF != tmp || SF != g_SF || OF != g_OF || CF != g_CF) + mismatch = true; + } + } + } + } + } + if (mismatch) + { + jit_log(" : Target CPU defines all flags on BSF instruction"); + } + return !mismatch; +} +#endif + +/************************************************************************* + * FPU stuff * + *************************************************************************/ + + +static inline void raw_fp_init(void) +{ + int i; + + for (i=0;i1) { + emit_byte(0x9b); + emit_byte(0xdb); + emit_byte(0xe3); + live.tos=-1; + } +#endif + while (live.tos>=1) { + emit_byte(0xde); + emit_byte(0xd9); + live.tos-=2; + } + while (live.tos>=0) { + emit_byte(0xdd); + emit_byte(0xd8); + live.tos--; + } + raw_fp_init(); +} + +static inline void make_tos(int r) +{ + int p,q; + + if (live.spos[r]<0) { /* Register not yet on stack */ + emit_byte(0xd9); + emit_byte(0xe8); /* Push '1' on the stack, just to grow it */ + live.tos++; + live.spos[r]=live.tos; + live.onstack[live.tos]=r; + return; + } + /* Register is on stack */ + if (live.tos==live.spos[r]) + return; + p=live.spos[r]; + q=live.onstack[live.tos]; + + emit_byte(0xd9); + emit_byte(0xc8+live.tos-live.spos[r]); /* exchange it with top of stack */ + live.onstack[live.tos]=r; + live.spos[r]=live.tos; + live.onstack[p]=q; + live.spos[q]=p; +} + +static inline void make_tos2(int r, int r2) +{ + int q; + + make_tos(r2); /* Put the reg that's supposed to end up in position2 on top */ + + if (live.spos[r]<0) { /* Register not yet on stack */ + make_tos(r); /* This will extend the stack */ + return; + } + /* Register is on stack */ + emit_byte(0xd9); + emit_byte(0xc9); /* Move r2 into position 2 */ + + q=live.onstack[live.tos-1]; + live.onstack[live.tos]=q; + live.spos[q]=live.tos; + live.onstack[live.tos-1]=r2; + live.spos[r2]=live.tos-1; + + make_tos(r); /* And r into 1 */ +} + +static inline int stackpos(int r) +{ + if (live.spos[r]<0) + abort(); + if (live.tos=0) { + /* source is on top of stack, and we already have the dest */ + int dd=stackpos(d); + emit_byte(0xdd); + emit_byte(0xd0+dd); + } + else { + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source on tos */ + tos_make(d); /* store to destination, pop if necessary */ + } +} + +LOWFUNC(NONE,READ,2,raw_fldcw_m_indexed,(R4 index, IMM base)) +{ + x86_64_prefix(true, false, NULL, NULL, &index); + emit_byte(0xd9); + emit_byte(0xa8 + index); + emit_long(base); +} + +LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xfa); /* take square root */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xfa); /* take square root */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xe1); /* take fabs */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xe1); /* take fabs */ + } +} + +LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xfc); /* take frndint */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xfc); /* take frndint */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xff); /* take cos */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xff); /* take cos */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xfe); /* fsin sin(x) */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xfe); /* fsin y=sin(x) */ + } +} + +static const double one = 1; + +LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s)) +{ + int ds; + + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(x) */ + emit_byte(0xd9); + emit_byte(0xc9); /* swap top two elements */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub frac(x) = x - int(x) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); /* Add '1' without using extra stack space */ + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x) */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy & pop */ + tos_make(d); /* store y=2^x */ +} + +LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s)) +{ + int ds; + + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xea); /* fldl2e log2(e) */ + emit_byte(0xde); + emit_byte(0xc9); /* fmulp --- multiply source by log2(e) */ + + emit_byte(0xd9); + emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */ + emit_byte(0xd9); + emit_byte(0xfc); /* rndint */ + emit_byte(0xd9); + emit_byte(0xc9); /* swap top two elements */ + emit_byte(0xd8); + emit_byte(0xe1); /* subtract rounded from original */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 */ + x86_fadd_m((uintptr)&one); /* Add '1' without using extra stack space */ + emit_byte(0xd9); + emit_byte(0xfd); /* and scale it */ + emit_byte(0xdd); + emit_byte(0xd9); /* take he rounded value off */ + tos_make(d); /* store to destination */ +} + +LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s)) +{ + int ds; + + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xe8); /* push '1' */ + emit_byte(0xd9); + emit_byte(0xc9); /* swap top two */ + emit_byte(0xd9); + emit_byte(0xf1); /* take 1*log2(x) */ + tos_make(d); /* store to destination */ +} + + +LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + usereg(s); + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* duplicate source */ + emit_byte(0xd9); + emit_byte(0xe0); /* take fchs */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xe0); /* take fchs */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + if (live.spos[s]==live.tos) { + /* Source is on top of stack */ + ds=stackpos(d); + emit_byte(0xdc); + emit_byte(0xc0+ds); /* add source to dest*/ + } + else { + make_tos(d); + ds=stackpos(s); + + emit_byte(0xd8); + emit_byte(0xc0+ds); /* add source to dest*/ + } +} + +LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + if (live.spos[s]==live.tos) { + /* Source is on top of stack */ + ds=stackpos(d); + emit_byte(0xdc); + emit_byte(0xe8+ds); /* sub source from dest*/ + } + else { + make_tos(d); + ds=stackpos(s); + + emit_byte(0xd8); + emit_byte(0xe0+ds); /* sub src from dest */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + make_tos(d); + ds=stackpos(s); + + emit_byte(0xdd); + emit_byte(0xe0+ds); /* cmp dest with source*/ +} + +LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + if (live.spos[s]==live.tos) { + /* Source is on top of stack */ + ds=stackpos(d); + emit_byte(0xdc); + emit_byte(0xc8+ds); /* mul dest by source*/ + } + else { + make_tos(d); + ds=stackpos(s); + + emit_byte(0xd8); + emit_byte(0xc8+ds); /* mul dest by source*/ + } +} + +LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + if (live.spos[s]==live.tos) { + /* Source is on top of stack */ + ds=stackpos(d); + emit_byte(0xdc); + emit_byte(0xf8+ds); /* div dest by source */ + } + else { + make_tos(d); + ds=stackpos(s); + + emit_byte(0xd8); + emit_byte(0xf0+ds); /* div dest by source*/ + } +} + +LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + make_tos2(d,s); + ds=stackpos(s); + + if (ds!=1) { + jit_abort("Failed horribly in raw_frem_rr! ds is %d",ds); + } + emit_byte(0xd9); + emit_byte(0xf8); /* take rem from dest by source */ +} + +LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) +{ + int ds; + + usereg(s); + usereg(d); + + make_tos2(d,s); + ds=stackpos(s); + + if (ds!=1) { + jit_abort("Failed horribly in raw_frem1_rr! ds is %d",ds); + } + emit_byte(0xd9); + emit_byte(0xf5); /* take rem1 from dest by source */ +} + + +LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r)) +{ + make_tos(r); + emit_byte(0xd9); /* ftst */ + emit_byte(0xe4); +} + +LOWFUNC(NONE,NONE,2,raw_fetoxM1_rr,(FW d, FR s)) +{ + int ds; + + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xea); /* fldl2e log2(e) */ + emit_byte(0xd8); + emit_byte(0xc9); /* fmul x*log2(e) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy up */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap top two elements */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + emit_byte(0xd9); + emit_byte(0xfd); /* fscale ((2^frac(x))-1)*2^int(x*log2(e)) */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy & pop */ + if (s!=d) + tos_make(d); /* store y=(e^x)-1 */ +} + +LOWFUNC(NONE,NONE,2,raw_ftentox_rr,(FW d, FR s)) +{ + int ds; + + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xe9); /* fldl2t log2(10) */ + emit_byte(0xd8); + emit_byte(0xc9); /* fmul x*log2(10) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy up */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(x*log2(10)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap top two elements */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub x*log2(10) - int(x*log2(10)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(10)) */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy & pop */ + if (s!=d) + tos_make(d); /* store y=10^x */ +} + +LOWFUNC(NONE,NONE,3,raw_fsincos_rr,(FW d, FW c, FR s)) +{ + int ds; + + if (s==d) { + //write_log (_T("FSINCOS src = dest\n")); + make_tos(s); + emit_byte(0xd9); + emit_byte(0xfb); /* fsincos sin(x) push cos(x) */ + tos_make(c); /* store cos(x) to c */ + return; + } + + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xfb); /* fsincos sin(x) push cos(x) */ + if (live.spos[c]<0) { + if (live.spos[d]<0) { /* occupy both regs directly */ + live.tos++; + live.spos[d]=live.tos; + live.onstack[live.tos]=d; /* sin(x) comes first */ + live.tos++; + live.spos[c]=live.tos; + live.onstack[live.tos]=c; + } + else { + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap cos(x) with sin(x) */ + emit_byte(0xdd); /* store sin(x) to d & pop */ + emit_byte(0xd8+(live.tos+2)-live.spos[d]); + live.tos++; /* occupy a reg for cos(x) here */ + live.spos[c]=live.tos; + live.onstack[live.tos]=c; + } + } + else { + emit_byte(0xdd); /* store cos(x) to c & pop */ + emit_byte(0xd8+(live.tos+2)-live.spos[c]); + tos_make(d); /* store sin(x) to destination */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fscale_rr,(FRW d, FR s)) +{ + int ds; + + if (live.spos[d]==live.tos && live.spos[s]==live.tos-1) { + //write_log (_T("fscale found x in TOS-1 and y in TOS\n")); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale y*(2^x) */ + } + else { + make_tos(s); /* tos=x */ + ds=stackpos(d); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld y */ + emit_byte(0xd9); + emit_byte(0xfd); /* fscale y*(2^x) */ + tos_make(d); /* store y=y*(2^x) */ + } +} + +LOWFUNC(NONE,NONE,2,raw_ftan_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xf2); /* fptan tan(x)=y/1.0 */ + emit_byte(0xdd); + emit_byte(0xd8); /* fstp pop 1.0 */ + tos_make(d); /* store to destination */ + } + else { + make_tos(d); + emit_byte(0xd9); + emit_byte(0xf2); /* fptan tan(x)=y/1.0 */ + emit_byte(0xdd); + emit_byte(0xd8); /* fstp pop 1.0 */ + } +} + +#ifdef CPU_x86_64 +#define REX64() emit_byte(0x48) +#else +#define REX64() +#endif + +LOWFUNC(NONE,NONE,1,raw_fcuts_r,(FRW r)) +{ + make_tos(r); /* TOS = r */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0xfc); /* add -4 to esp */ + emit_byte(0xd9); + emit_byte(0x1c); + emit_byte(0x24); /* fstp store r as SINGLE to [esp] and pop */ + emit_byte(0xd9); + emit_byte(0x04); + emit_byte(0x24); /* fld load r as SINGLE from [esp] */ + emit_byte(0x9b); /* let the CPU wait on FPU exceptions */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0x04); /* add +4 to esp */ +} + +LOWFUNC(NONE,NONE,1,raw_fcut_r,(FRW r)) +{ + make_tos(r); /* TOS = r */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0xf8); /* add -8 to esp */ + emit_byte(0xdd); + emit_byte(0x1c); + emit_byte(0x24); /* fstp store r as DOUBLE to [esp] and pop */ + emit_byte(0xdd); + emit_byte(0x04); + emit_byte(0x24); /* fld load r as DOUBLE from [esp] */ + emit_byte(0x9b); /* let the CPU wait on FPU exceptions */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0x08); /* add +8 to esp */ +} + +LOWFUNC(NONE,NONE,2,raw_fgetexp_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xf4); /* fxtract exp push man */ + emit_byte(0xdd); + emit_byte(0xd8); /* fstp just pop man */ + tos_make(d); /* store exp to destination */ + } + else { + make_tos(d); /* tos=x=y */ + emit_byte(0xd9); + emit_byte(0xf4); /* fxtract exp push man */ + emit_byte(0xdd); + emit_byte(0xd8); /* fstp just pop man */ + } +} + +LOWFUNC(NONE,NONE,2,raw_fgetman_rr,(FW d, FR s)) +{ + int ds; + + if (d!=s) { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xf4); /* fxtract exp push man */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy man up & pop */ + tos_make(d); /* store man to destination */ + } + else { + make_tos(d); /* tos=x=y */ + emit_byte(0xd9); + emit_byte(0xf4); /* fxtract exp push man */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy man up & pop */ + } +} + +LOWFUNC(NONE,NONE,2,raw_flogN_rr,(FW d, FR s)) +{ + int ds; + + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xed); /* fldln2 logN(2) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap logN(2) with x */ + emit_byte(0xd9); + emit_byte(0xf1); /* fyl2x logN(2)*log2(x) */ + if (s!=d) + tos_make(d); /* store y=logN(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_flogNP1_rr,(FW d, FR s)) +{ + int ds; + + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xed); /* fldln2 logN(2) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap logN(2) with x */ + emit_byte(0xd9); + emit_byte(0xf9); /* fyl2xp1 logN(2)*log2(x+1) */ + if (s!=d) + tos_make(d); /* store y=logN(x+1) */ +} + +LOWFUNC(NONE,NONE,2,raw_flog10_rr,(FW d, FR s)) +{ + int ds; + + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xec); /* fldlg2 log10(2) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap log10(2) with x */ + emit_byte(0xd9); + emit_byte(0xf1); /* fyl2x log10(2)*log2(x) */ + if (s!=d) + tos_make(d); /* store y=log10(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_fasin_rr,(FW d, FR s)) +{ + int ds; + + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd8); + emit_byte(0xc8); /* fmul x*x */ + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xde); + emit_byte(0xe1); /* fsubrp 1 - (x^2) */ + emit_byte(0xd9); + emit_byte(0xfa); /* fsqrt sqrt(1-(x^2)) */ + emit_byte(0xd9); + emit_byte(0xc1+ds); /* fld x again */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap x with sqrt(1-(x^2)) */ + emit_byte(0xd9); + emit_byte(0xf3); /* fpatan atan(x/sqrt(1-(x^2))) & pop */ + tos_make(d); /* store y=asin(x) */ +} + +static uae_u32 const pihalf[] = {0x2168c234, 0xc90fdaa2, 0x3fff}; // LSB=0 to get acos(1)=0 + +LOWFUNC(NONE,NONE,2,raw_facos_rr,(FW d, FR s)) +{ + int ds; + + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd8); + emit_byte(0xc8); /* fmul x*x */ + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xde); + emit_byte(0xe1); /* fsubrp 1 - (x^2) */ + emit_byte(0xd9); + emit_byte(0xfa); /* fsqrt sqrt(1-(x^2)) */ + emit_byte(0xd9); + emit_byte(0xc1+ds); /* fld x again */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap x with sqrt(1-(x^2)) */ + emit_byte(0xd9); + emit_byte(0xf3); /* fpatan atan(x/sqrt(1-(x^2))) & pop */ + raw_fldt((uintptr) &pihalf); /* fld load pi/2 from pihalf */ + emit_byte(0xde); + emit_byte(0xe1); /* fsubrp pi/2 - asin(x) & pop */ + tos_make(d); /* store y=acos(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_fatan_rr,(FW d, FR s)) +{ + int ds; + + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xd9); + emit_byte(0xf3); /* fpatan atan(x)/1 & pop*/ + if (s!=d) + tos_make(d); /* store y=atan(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_fatanh_rr,(FW d, FR s)) +{ + int ds; + + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xdc); + emit_byte(0xc1); /* fadd 1 + x */ + emit_byte(0xd8); + emit_byte(0xe2+ds); /* fsub 1 - x */ + emit_byte(0xde); + emit_byte(0xf9); /* fdivp (1+x)/(1-x) */ + emit_byte(0xd9); + emit_byte(0xed); /* fldl2e logN(2) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap logN(2) with (1+x)/(1-x) */ + emit_byte(0xd9); + emit_byte(0xf1); /* fyl2x logN(2)*log2((1+x)/(1-x)) pop */ + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xd9); + emit_byte(0xe0); /* fchs -1.0 */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd9); + emit_byte(0xfd); /* fscale logN((1+x)/(1-x)) * 2^(-1) */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy & pop */ + tos_make(d); /* store y=atanh(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_fsinh_rr,(FW d, FR s)) +{ + int ds,tr; + + tr=live.onstack[live.tos+3]; + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xea); /* fldl2e log2(e) */ + emit_byte(0xd8); + emit_byte(0xc9); /* fmul x*log2(e) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy x*log2(e) */ + if (tr>=0) { + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap with temp-reg */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0xf4); /* add -12 to esp */ + emit_byte(0xdb); + emit_byte(0x3c); + emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */ + } + emit_byte(0xd9); + emit_byte(0xe0); /* fchs -x*log2(e) */ + emit_byte(0xd9); + emit_byte(0xc0); /* fld -x*log2(e) again */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(-x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub -x*log2(e) - int(-x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap e^-x with x*log2(e) in tr */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy x*log2(e) */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy e^x & pop */ + if (tr>=0) { + emit_byte(0xdb); + emit_byte(0x2c); + emit_byte(0x24); /* fld load temp-reg from [esp] */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */ + emit_byte(0xde); + emit_byte(0xe9); /* fsubp (e^x)-(e^-x) */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0x0c); /* delayed add +12 to esp */ + } + else { + emit_byte(0xde); + emit_byte(0xe1); /* fsubrp (e^x)-(e^-x) */ + } + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xd9); + emit_byte(0xe0); /* fchs -1.0 */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd9); + emit_byte(0xfd); /* fscale ((e^x)-(e^-x))/2 */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy & pop */ + if (s!=d) + tos_make(d); /* store y=sinh(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_fcosh_rr,(FW d, FR s)) +{ + int ds,tr; + + tr=live.onstack[live.tos+3]; + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xea); /* fldl2e log2(e) */ + emit_byte(0xd8); + emit_byte(0xc9); /* fmul x*log2(e) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy x*log2(e) */ + if (tr>=0) { + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap with temp-reg */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0xf4); /* add -12 to esp */ + emit_byte(0xdb); + emit_byte(0x3c); + emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */ + } + emit_byte(0xd9); + emit_byte(0xe0); /* fchs -x*log2(e) */ + emit_byte(0xd9); + emit_byte(0xc0); /* fld -x*log2(e) again */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(-x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub -x*log2(e) - int(-x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap e^-x with x*log2(e) in tr */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy x*log2(e) */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy e^x & pop */ + if (tr>=0) { + emit_byte(0xdb); + emit_byte(0x2c); + emit_byte(0x24); /* fld load temp-reg from [esp] */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0x0c); /* delayed add +12 to esp */ + } + emit_byte(0xde); + emit_byte(0xc1); /* faddp (e^x)+(e^-x) */ + emit_byte(0xd9); + emit_byte(0xe8); /* fld 1.0 */ + emit_byte(0xd9); + emit_byte(0xe0); /* fchs -1.0 */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd9); + emit_byte(0xfd); /* fscale ((e^x)+(e^-x))/2 */ + emit_byte(0xdd); + emit_byte(0xd9); /* fstp copy & pop */ + if (s!=d) + tos_make(d); /* store y=cosh(x) */ +} + +LOWFUNC(NONE,NONE,2,raw_ftanh_rr,(FW d, FR s)) +{ + int ds,tr; + + tr=live.onstack[live.tos+3]; + if (s==d) + make_tos(s); + else { + ds=stackpos(s); + emit_byte(0xd9); + emit_byte(0xc0+ds); /* fld x */ + } + emit_byte(0xd9); + emit_byte(0xea); /* fldl2e log2(e) */ + emit_byte(0xd8); + emit_byte(0xc9); /* fmul x*log2(e) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy x*log2(e) */ + if (tr>=0) { + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap with temp-reg */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0xf4); /* add -12 to esp */ + emit_byte(0xdb); + emit_byte(0x3c); + emit_byte(0x24); /* fstp store temp-reg to [esp] & pop */ + } + emit_byte(0xd9); + emit_byte(0xe0); /* fchs -x*log2(e) */ + emit_byte(0xd9); + emit_byte(0xc0); /* fld -x*log2(e) again */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(-x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub -x*log2(e) - int(-x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap e^-x with x*log2(e) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy x*log2(e) */ + emit_byte(0xd9); + emit_byte(0xfc); /* frndint int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xc9); /* fxch swap */ + emit_byte(0xd8); + emit_byte(0xe1); /* fsub x*log2(e) - int(x*log2(e)) */ + emit_byte(0xd9); + emit_byte(0xf0); /* f2xm1 (2^frac(x))-1 */ + x86_fadd_m((uintptr) &one); + emit_byte(0xd9); + emit_byte(0xfd); /* fscale (2^frac(x))*2^int(x*log2(e)) */ + emit_byte(0xdd); + emit_byte(0xd1); /* fst copy e^x */ + emit_byte(0xd8); + emit_byte(0xc2); /* fadd (e^x)+(e^-x) */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap with e^-x */ + emit_byte(0xde); + emit_byte(0xe9); /* fsubp (e^x)-(e^-x) */ + if (tr>=0) { + emit_byte(0xdb); + emit_byte(0x2c); + emit_byte(0x24); /* fld load temp-reg from [esp] */ + emit_byte(0xd9); + emit_byte(0xca); /* fxch swap temp-reg with e^-x in tr */ + emit_byte(0xde); + emit_byte(0xf9); /* fdivp ((e^x)-(e^-x))/((e^x)+(e^-x)) */ + REX64(); + emit_byte(0x83); + emit_byte(0xc4); + emit_byte(0x0c); /* delayed add +12 to esp */ + } + else { + emit_byte(0xde); + emit_byte(0xf1); /* fdivrp ((e^x)-(e^-x))/((e^x)+(e^-x)) */ + } + if (s!=d) + tos_make(d); /* store y=tanh(x) */ +} + +/* %eax register is clobbered if target processor doesn't support fucomi */ +#define FFLAG_NREG_CLOBBER_CONDITION !have_cmov +#define FFLAG_NREG EAX_INDEX + +static inline void raw_fflags_into_flags(int r) +{ + int p; + + usereg(r); + p=stackpos(r); + + emit_byte(0xd9); + emit_byte(0xee); /* Push 0 */ + emit_byte(0xd9); + emit_byte(0xc9+p); /* swap top two around */ + if (have_cmov) { + // gb-- fucomi is for P6 cores only, not K6-2 then... + emit_byte(0xdb); + emit_byte(0xe9+p); /* fucomi them */ + } + else { + emit_byte(0xdd); + emit_byte(0xe1+p); /* fucom them */ + emit_byte(0x9b); + emit_byte(0xdf); + emit_byte(0xe0); /* fstsw ax */ + raw_sahf(0); /* sahf */ + } + emit_byte(0xdd); + emit_byte(0xd9+p); /* store value back, and get rid of 0 */ +} diff --git a/BasiliskII/src/uae_cpu_2021/compiler/codegen_x86.h b/BasiliskII/src/uae_cpu_2021/compiler/codegen_x86.h new file mode 100644 index 000000000..0eaef50af --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/codegen_x86.h @@ -0,0 +1,2028 @@ +/* + * compiler/codegen_x86.h - IA-32 and AMD64 code generator + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * This file is derived from CCG, copyright 1999-2003 Ian Piumarta + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * 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 X86_RTASM_H +#define X86_RTASM_H + +/* NOTES + * + * o Best viewed on a 1024x768 screen with fixed-6x10 font ;-) + * + * TODO + * + * o Fix FIXMEs + * o i387 FPU instructions + * o SSE instructions + * o Optimize for cases where register numbers are not integral constants + */ + +/* --- Configuration ------------------------------------------------------- */ + +/* Define to settle a "flat" register set, i.e. different regno for + each size variant. */ +#ifndef X86_FLAT_REGISTERS +#define X86_FLAT_REGISTERS 1 +#endif + +/* Define to generate x86-64 code. */ +#ifndef X86_TARGET_64BIT +#define X86_TARGET_64BIT 0 +#endif + +/* Define to optimize ALU instructions. */ +#ifndef X86_OPTIMIZE_ALU +#define X86_OPTIMIZE_ALU 1 +#endif + +/* Define to optimize rotate/shift instructions. */ +#ifndef X86_OPTIMIZE_ROTSHI +#define X86_OPTIMIZE_ROTSHI 1 +#endif + +/* Define to optimize absolute addresses for RIP relative addressing. */ +#ifndef X86_RIP_RELATIVE_ADDR +#define X86_RIP_RELATIVE_ADDR 1 +#endif + + +/* --- Macros -------------------------------------------------------------- */ + +/* Functions used to emit code. + * + * x86_emit_byte(B) + * x86_emit_word(W) + * x86_emit_long(L) + */ + +/* Get pointer to current code + * + * x86_get_target() + */ + +/* Abort assembler, fatal failure. + * + * x86_emit_failure(MSG) + */ + +#define x86_emit_failure0(MSG) (x86_emit_failure(MSG),0) + + +/* --- Register set -------------------------------------------------------- */ + +enum { + X86_RIP = -2, +#if X86_FLAT_REGISTERS + X86_NOREG = 0, + X86_Reg8L_Base = 0x10, + X86_Reg8H_Base = 0x20, + X86_Reg16_Base = 0x30, + X86_Reg32_Base = 0x40, + X86_Reg64_Base = 0x50, + X86_RegMMX_Base = 0x60, + X86_RegXMM_Base = 0x70, +#else + X86_NOREG = -1, + X86_Reg8L_Base = 0, + X86_Reg8H_Base = 16, + X86_Reg16_Base = 0, + X86_Reg32_Base = 0, + X86_Reg64_Base = 0, + X86_RegMMX_Base = 0, + X86_RegXMM_Base = 0, +#endif +}; + +enum { + X86_AL = X86_Reg8L_Base, + X86_CL, X86_DL, X86_BL, + X86_SPL, X86_BPL, X86_SIL, X86_DIL, + X86_R8B, X86_R9B, X86_R10B, X86_R11B, + X86_R12B, X86_R13B, X86_R14B, X86_R15B, + X86_AH = X86_Reg8H_Base + 4, + X86_CH, X86_DH, X86_BH +}; + +enum { + X86_AX = X86_Reg16_Base, + X86_CX, X86_DX, X86_BX, + X86_SP, X86_BP, X86_SI, X86_DI, + X86_R8W, X86_R9W, X86_R10W, X86_R11W, + X86_R12W, X86_R13W, X86_R14W, X86_R15W +}; + +enum { + X86_EAX = X86_Reg32_Base, + X86_ECX, X86_EDX, X86_EBX, + X86_ESP, X86_EBP, X86_ESI, X86_EDI, + X86_R8D, X86_R9D, X86_R10D, X86_R11D, + X86_R12D, X86_R13D, X86_R14D, X86_R15D +}; + +enum { + X86_RAX = X86_Reg64_Base, + X86_RCX, X86_RDX, X86_RBX, + X86_RSP, X86_RBP, X86_RSI, X86_RDI, + X86_R8, X86_R9, X86_R10, X86_R11, + X86_R12, X86_R13, X86_R14, X86_R15 +}; + +enum { + X86_MM0 = X86_RegMMX_Base, + X86_MM1, X86_MM2, X86_MM3, + X86_MM4, X86_MM5, X86_MM6, X86_MM7, +}; + +enum { + X86_XMM0 = X86_RegXMM_Base, + X86_XMM1, X86_XMM2, X86_XMM3, + X86_XMM4, X86_XMM5, X86_XMM6, X86_XMM7, + X86_XMM8, X86_XMM9, X86_XMM10, X86_XMM11, + X86_XMM12, X86_XMM13, X86_XMM14, X86_XMM15 +}; + +/* Register control and access + * + * _r0P(R) Null register? + * _rIP(R) RIP register? + * _rXP(R) Extended register? + * + * _rC(R) Class of register (only valid if X86_FLAT_REGISTERS) + * _rR(R) Full register number + * _rN(R) Short register number for encoding + * + * _r1(R) 8-bit register ID + * _r2(R) 16-bit register ID + * _r4(R) 32-bit register ID + * _r8(R) 64-bit register ID + * _rM(R) MMX register ID + * _rX(R) XMM register ID + * _rA(R) Address register ID used for EA calculation + */ + +#define _r0P(R) ((int)(R) == (int)X86_NOREG) +#define _rIP(R) ((int)(R) == (int)X86_RIP) + +#if X86_FLAT_REGISTERS +#define _rC(R) ((R) & 0xf0) +#define _rR(R) ((R) & 0x0f) +#define _rN(R) ((R) & 0x07) +#define _rXP(R) ((R) > 0 && _rR(R) > 7) +#else +#define _rN(R) ((R) & 0x07) +#define _rR(R) (int(R)) +#define _rXP(R) (_rR(R) > 7 && _rR(R) < 16) +#endif + +#if !defined(_ASM_SAFETY) || ! X86_FLAT_REGISTERS +#define _r1(R) _rN(R) +#define _r2(R) _rN(R) +#define _r4(R) _rN(R) +#define _r8(R) _rN(R) +#define _rA(R) _rN(R) +#define _rM(R) _rN(R) +#define _rX(R) _rN(R) +#else +#define _r1(R) ( ((_rC(R) & (X86_Reg8L_Base | X86_Reg8H_Base)) != 0) ? _rN(R) : x86_emit_failure0( "8-bit register required")) +#define _r2(R) ( (_rC(R) == X86_Reg16_Base) ? _rN(R) : x86_emit_failure0("16-bit register required")) +#define _r4(R) ( (_rC(R) == X86_Reg32_Base) ? _rN(R) : x86_emit_failure0("32-bit register required")) +#define _r8(R) ( (_rC(R) == X86_Reg64_Base) ? _rN(R) : x86_emit_failure0("64-bit register required")) +#define _rA(R) ( X86_TARGET_64BIT ? \ + ( (_rC(R) == X86_Reg64_Base) ? _rN(R) : x86_emit_failure0("not a valid 64-bit base/index expression")) : \ + ( (_rC(R) == X86_Reg32_Base) ? _rN(R) : x86_emit_failure0("not a valid 32-bit base/index expression")) ) +#define _rM(R) ( (_rC(R) == X86_RegMMX_Base) ? _rN(R) : x86_emit_failure0("MMX register required")) +#define _rX(R) ( (_rC(R) == X86_RegXMM_Base) ? _rN(R) : x86_emit_failure0("SSE register required")) +#endif + +#define _rSP() (X86_TARGET_64BIT ? (int)X86_RSP : (int)X86_ESP) +#define _r1e8lP(R) (int(R) >= X86_SPL && int(R) <= X86_DIL) +#define _rbpP(R) (_rR(R) == _rR(X86_RBP)) +#define _rspP(R) (_rR(R) == _rR(X86_RSP)) +#define _rbp13P(R) (_rN(R) == _rN(X86_RBP)) +#define _rsp12P(R) (_rN(R) == _rN(X86_RSP)) + + +/* ========================================================================= */ +/* --- UTILITY ------------------------------------------------------------- */ +/* ========================================================================= */ + +typedef signed char _sc; +typedef unsigned char _uc; +typedef signed short _ss; +typedef unsigned short _us; +typedef signed int _sl; +typedef unsigned int _ul; + +#define _UC(X) ((_uc )(uintptr_t)(X)) +#define _US(X) ((_us )(uintptr_t)(X)) +#define _SL(X) ((_sl )(uintptr_t)(X)) +#define _UL(X) ((_ul )(uintptr_t)(X)) + +#define _PUC(X) ((_uc *)(X)) +#define _PUS(X) ((_us *)(X)) +#define _PSL(X) ((_sl *)(X)) +#define _PUL(X) ((_ul *)(X)) + +#undef _B +#undef _W +#undef _L +#undef _Q + +#define _B(B) x86_emit_byte((B)) +#define _W(W) x86_emit_word((W)) +#define _L(L) x86_emit_long((L)) +#define _Q(Q) x86_emit_quad((Q)) + +#define _MASK(N) ((unsigned)((1<<(N)))-1) +#define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N))) +#define _uiP(N,I) (!(((unsigned)(I))&~_MASK(N))) +#define _suiP(N,I) (_siP(N,I) | _uiP(N,I)) + +#ifndef _ASM_SAFETY +#define _ck_s(W,I) (_UL(I) & _MASK(W)) +#define _ck_u(W,I) (_UL(I) & _MASK(W)) +#define _ck_su(W,I) (_UL(I) & _MASK(W)) +#define _ck_d(W,I) (_UL(I) & _MASK(W)) +#else +#define _ck_s(W,I) (_siP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "signed integer `"#I"' too large for "#W"-bit field")) +#define _ck_u(W,I) (_uiP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0("unsigned integer `"#I"' too large for "#W"-bit field")) +#define _ck_su(W,I) (_suiP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "integer `"#I"' too large for "#W"-bit field")) +#define _ck_d(W,I) (_siP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "displacement `"#I"' too large for "#W"-bit field")) +#endif + +#define _s0P(I) ((I)==0) +#define _s8P(I) _siP(8,I) +#define _s16P(I) _siP(16,I) +#define _u8P(I) _uiP(8,I) +#define _u16P(I) _uiP(16,I) + +#define _su8(I) _ck_su(8,I) +#define _su16(I) _ck_su(16,I) + +#define _s1(I) _ck_s( 1,I) +#define _s2(I) _ck_s( 2,I) +#define _s3(I) _ck_s( 3,I) +#define _s4(I) _ck_s( 4,I) +#define _s5(I) _ck_s( 5,I) +#define _s6(I) _ck_s( 6,I) +#define _s7(I) _ck_s( 7,I) +#define _s8(I) _ck_s( 8,I) +#define _s9(I) _ck_s( 9,I) +#define _s10(I) _ck_s(10,I) +#define _s11(I) _ck_s(11,I) +#define _s12(I) _ck_s(12,I) +#define _s13(I) _ck_s(13,I) +#define _s14(I) _ck_s(14,I) +#define _s15(I) _ck_s(15,I) +#define _s16(I) _ck_s(16,I) +#define _s17(I) _ck_s(17,I) +#define _s18(I) _ck_s(18,I) +#define _s19(I) _ck_s(19,I) +#define _s20(I) _ck_s(20,I) +#define _s21(I) _ck_s(21,I) +#define _s22(I) _ck_s(22,I) +#define _s23(I) _ck_s(23,I) +#define _s24(I) _ck_s(24,I) +#define _s25(I) _ck_s(25,I) +#define _s26(I) _ck_s(26,I) +#define _s27(I) _ck_s(27,I) +#define _s28(I) _ck_s(28,I) +#define _s29(I) _ck_s(29,I) +#define _s30(I) _ck_s(30,I) +#define _s31(I) _ck_s(31,I) +#define _u1(I) _ck_u( 1,I) +#define _u2(I) _ck_u( 2,I) +#define _u3(I) _ck_u( 3,I) +#define _u4(I) _ck_u( 4,I) +#define _u5(I) _ck_u( 5,I) +#define _u6(I) _ck_u( 6,I) +#define _u7(I) _ck_u( 7,I) +#define _u8(I) _ck_u( 8,I) +#define _u9(I) _ck_u( 9,I) +#define _u10(I) _ck_u(10,I) +#define _u11(I) _ck_u(11,I) +#define _u12(I) _ck_u(12,I) +#define _u13(I) _ck_u(13,I) +#define _u14(I) _ck_u(14,I) +#define _u15(I) _ck_u(15,I) +#define _u16(I) _ck_u(16,I) +#define _u17(I) _ck_u(17,I) +#define _u18(I) _ck_u(18,I) +#define _u19(I) _ck_u(19,I) +#define _u20(I) _ck_u(20,I) +#define _u21(I) _ck_u(21,I) +#define _u22(I) _ck_u(22,I) +#define _u23(I) _ck_u(23,I) +#define _u24(I) _ck_u(24,I) +#define _u25(I) _ck_u(25,I) +#define _u26(I) _ck_u(26,I) +#define _u27(I) _ck_u(27,I) +#define _u28(I) _ck_u(28,I) +#define _u29(I) _ck_u(29,I) +#define _u30(I) _ck_u(30,I) +#define _u31(I) _ck_u(31,I) + +/* ========================================================================= */ +/* --- ASSEMBLER ----------------------------------------------------------- */ +/* ========================================================================= */ + +#define _b00 0 +#define _b01 1 +#define _b10 2 +#define _b11 3 + +#define _b000 0 +#define _b001 1 +#define _b010 2 +#define _b011 3 +#define _b100 4 +#define _b101 5 +#define _b110 6 +#define _b111 7 + +#define _OFF4(D) (_UL(D) - _UL(x86_get_target())) +#define _CKD8(D) _ck_d(8, ((_uc) _OFF4(D)) ) + +#define _D8(D) (_B(0), ((*(_PUC(x86_get_target())-1))= _CKD8(D))) +#define _D32(D) (_L(0), ((*(_PUL(x86_get_target())-1))= _OFF4(D))) + +#ifndef _ASM_SAFETY +# define _M(M) (M) +# define _r(R) (R) +# define _m(M) (M) +# define _s(S) (S) +# define _i(I) (I) +# define _b(B) (B) +#else +# define _M(M) (((M)>3) ? x86_emit_failure0("internal error: mod = " #M) : (M)) +# define _r(R) (((R)>7) ? x86_emit_failure0("internal error: reg = " #R) : (R)) +# define _m(M) (((M)>7) ? x86_emit_failure0("internal error: r/m = " #M) : (M)) +# define _s(S) (((S)>3) ? x86_emit_failure0("internal error: memory scale = " #S) : (S)) +# define _i(I) (((I)>7) ? x86_emit_failure0("internal error: memory index = " #I) : (I)) +# define _b(B) (((B)>7) ? x86_emit_failure0("internal error: memory base = " #B) : (B)) +#endif + +#define _Mrm(Md,R,M) _B((_M(Md)<<6)|(_r(R)<<3)|_m(M)) +#define _SIB(Sc,I, B) _B((_s(Sc)<<6)|(_i(I)<<3)|_b(B)) + +#define _SCL(S) ((((S)==1) ? _b00 : \ + (((S)==2) ? _b01 : \ + (((S)==4) ? _b10 : \ + (((S)==8) ? _b11 : x86_emit_failure0("illegal scale: " #S)))))) + + +/* --- Memory subformats - urgh! ------------------------------------------- */ + +/* _r_D() is RIP addressing mode if X86_TARGET_64BIT, use _r_DSIB() instead */ +#define _r_D( R, D ) (_Mrm(_b00,_rN(R),_b101 ) ,_L((uae_u32)(D))) +#define _r_DSIB(R, D ) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(1),_b100 ,_b101 ),_L((uae_u32)(D))) +#define _r_0B( R, B ) (_Mrm(_b00,_rN(R),_rA(B)) ) +#define _r_0BIS(R, B,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)) ) +#define _r_1B( R, D,B ) (_Mrm(_b01,_rN(R),_rA(B)) ,_B((uae_u32)(D))) +#define _r_1BIS(R, D,B,I,S) (_Mrm(_b01,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_B((uae_u32)(D))) +#define _r_4B( R, D,B ) (_Mrm(_b10,_rN(R),_rA(B)) ,_L((uae_u32)(D))) +#define _r_4IS( R, D,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_b101 ),_L((uae_u32)(D))) +#define _r_4BIS(R, D,B,I,S) (_Mrm(_b10,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_L((uae_u32)(D))) + +#define _r_DB( R, D,B ) ((_s0P(D) && (!_rbp13P(B)) ? _r_0B (R, B ) : (_s8P(D) ? _r_1B( R,D,B ) : _r_4B( R,D,B )))) +#define _r_DBIS(R, D,B,I,S) ((_s0P(D) && (!_rbp13P(B)) ? _r_0BIS(R, B,I,S) : (_s8P(D) ? _r_1BIS(R,D,B,I,S) : _r_4BIS(R,D,B,I,S)))) + +/* Use RIP-addressing in 64-bit mode, if possible */ +#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && x86_RIP_addressing_possible(D, O)) + +static inline int x86_RIP_addressing_possible(uintptr addr, uintptr offset) +{ +#if X86_TARGET_64BIT + /* + * address of the next instruction. + * The opcode has already been emmitted, + * so this is the size of an 32bit displacement + + * the size of any immediate value that is part of the instruction (offset), + */ + uintptr dst = (uintptr)get_target() + 4 + offset; + intptr disp = dst - addr; + int ok = disp >= -0x80000000LL && disp <= 0x7fffffffLL; + /* fprintf(stderr, "x86_RIP_addressing_possible: %llx - %llx %16llx = %d\n", (unsigned long long)dst, (unsigned long long)addr, (long long)disp, ok); */ + return ok; +#else + UNUSED(addr); + UNUSED(offset); + return 0; +#endif +} + + +static inline int x86_DISP32_addressing_possible(uintptr addr) +{ +#if X86_TARGET_64BIT + return addr <= 0xFFFFFFFFULL; +#else + UNUSED(addr); + return 1; +#endif +} + + +#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? (!X86_TARGET_64BIT ? _r_D(R,D) : \ + (_x86_RIP_addressing_possible(D, O) ? \ + _r_D(R, (D) - ((uintptr)x86_get_target() + 4 + (O))) : \ + _r_DSIB(R,D))) : \ + (_rIP(B) ? _r_D (R,D ) : \ + (_rsp12P(B) ? _r_DBIS(R,D,_rSP(),_rSP(),1) : \ + _r_DB (R,D, B )))) : \ + (_r0P(B) ? _r_4IS (R,D, I,S) : \ + (!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \ + x86_emit_failure("illegal index register: %esp")))) + + +/* --- Instruction formats ------------------------------------------------- */ + +#define _m32only(X) (! X86_TARGET_64BIT ? X : x86_emit_failure("invalid instruction in 64-bit mode")) +#define _m64only(X) ( X86_TARGET_64BIT ? X : x86_emit_failure("invalid instruction in 32-bit mode")) +#define _m64(X) ( X86_TARGET_64BIT ? X : ((void)0) ) + +/* _format Opcd ModR/M dN(rB,rI,Sc) imm... */ + +#define _d16() ( _B(0x66 ) ) +#define _O( OP ) ( _B( OP ) ) +#define _Or( OP,R ) ( _B( (OP)|_r(R)) ) +#define _OO( OP ) ( _B((OP)>>8), _B( (uae_u8)(OP) ) ) +#define _OOr( OP,R ) ( _B((OP)>>8), _B( (OP)|_r(R)) ) +#define _Os( OP,B ) ( _s8P(B) ? _B(((OP)|_b10)) : _B(OP) ) +#define _sW( W ) ( _s8P(W) ? _B(W):_W(W) ) +#define _sL( L ) ( _s8P(L) ? _B(L):_L(L) ) +#define _sWO( W ) ( _s8P(W) ? 1 : 2 ) +#define _sLO( L ) ( _s8P(L) ? 1 : 4 ) +#define _O_B( OP ,B ) ( _O ( OP ) ,_B(B) ) +#define _O_W( OP ,W ) ( _O ( OP ) ,_W(W) ) +#define _O_L( OP ,L ) ( _O ( OP ) ,_L(L) ) +#define _O_D8( OP ,D ) ( _O ( OP ) ,_D8(D) ) +#define _O_D32( OP ,D ) ( _O ( OP ) ,_D32(D) ) +#define _OO_D32( OP ,D ) ( _OO ( OP ) ,_D32(D) ) +#define _Os_sW( OP ,W ) ( _Os ( OP,W) ,_sW(W) ) +#define _Os_sL( OP ,L ) ( _Os ( OP,L) ,_sL(L) ) +#define _O_W_B( OP ,W,B) ( _O ( OP ) ,_W(W),_B(B)) +#define _Or_B( OP,R ,B ) ( _Or ( OP,R) ,_B(B) ) +#define _Or_W( OP,R ,W ) ( _Or ( OP,R) ,_W(W) ) +#define _Or_L( OP,R ,L ) ( _Or ( OP,R) ,_L(L) ) +#define _Or_Q( OP,R ,Q ) ( _Or ( OP,R) ,_Q(Q) ) +#define _O_Mrm( OP ,MO,R,M ) ( _O ( OP ),_Mrm(MO,R,M ) ) +#define _OO_Mrm( OP ,MO,R,M ) ( _OO ( OP ),_Mrm(MO,R,M ) ) +#define _O_Mrm_B( OP ,MO,R,M ,B ) ( _O ( OP ),_Mrm(MO,R,M ) ,_B(B) ) +#define _O_Mrm_W( OP ,MO,R,M ,W ) ( _O ( OP ),_Mrm(MO,R,M ) ,_W(W) ) +#define _O_Mrm_L( OP ,MO,R,M ,L ) ( _O ( OP ),_Mrm(MO,R,M ) ,_L(L) ) +#define _OO_Mrm_B( OP ,MO,R,M ,B ) ( _OO ( OP ),_Mrm(MO,R,M ) ,_B(B) ) +#define _Os_Mrm_sW(OP ,MO,R,M ,W ) ( _Os ( OP,W),_Mrm(MO,R,M ),_sW(W) ) +#define _Os_Mrm_sL(OP ,MO,R,M ,L ) ( _Os ( OP,L),_Mrm(MO,R,M ),_sL(L) ) +#define _O_r_X( OP ,R ,MD,MB,MI,MS ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,0) ) +#define _OO_r_X( OP ,R ,MD,MB,MI,MS ) ( _OO ( OP ),_r_X( R ,MD,MB,MI,MS,0) ) +#define _O_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,1) ,_B(B) ) +#define _O_r_X_W( OP ,R ,MD,MB,MI,MS,W ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,2) ,_W(W) ) +#define _O_r_X_L( OP ,R ,MD,MB,MI,MS,L ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,4) ,_L(L) ) +#define _OO_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _OO ( OP ),_r_X( R ,MD,MB,MI,MS,1) ,_B(B) ) +#define _Os_r_X_sW(OP ,R ,MD,MB,MI,MS,W ) ( _Os ( OP,W),_r_X( R ,MD,MB,MI,MS,_sWO(W)),_sW(W)) +#define _Os_r_X_sL(OP ,R ,MD,MB,MI,MS,L ) ( _Os ( OP,L),_r_X( R ,MD,MB,MI,MS,_sLO(L)),_sL(L)) +#define _O_X_B( OP ,MD,MB,MI,MS,B ) ( _O_r_X_B( OP ,0 ,MD,MB,MI,MS ,B) ) +#define _O_X_W( OP ,MD,MB,MI,MS,W ) ( _O_r_X_W( OP ,0 ,MD,MB,MI,MS ,W) ) +#define _O_X_L( OP ,MD,MB,MI,MS,L ) ( _O_r_X_L( OP ,0 ,MD,MB,MI,MS ,L) ) + + +/* --- REX prefixes -------------------------------------------------------- */ + +#undef _VOID + +#define _VOID() ((void)0) +#define _BIT(X) (!!(X)) +#define _d64(W,R,X,B) (_B(0x40|(W)<<3|(R)<<2|(X)<<1|(B))) + +#define __REXwrxb(L,W,R,X,B) ((W|R|X|B) || (L) ? _d64(W,R,X,B) : _VOID()) +#define __REXwrx_(L,W,R,X,MR) (__REXwrxb(L,W,R,X,_BIT(_rIP(MR)?0:_rXP(MR)))) +#define __REXw_x_(L,W,R,X,MR) (__REXwrx_(L,W,_BIT(_rXP(R)),X,MR)) +#define __REX_reg(RR) (__REXwrxb(0,0,0,00,_BIT(_rXP(RR)))) +#define __REX_mem(MB,MI) (__REXwrxb(0,0,0,_BIT(_rXP(MI)),_BIT(_rXP(MB)))) + +// FIXME: can't mix new (SPL,BPL,SIL,DIL) with (AH,BH,CH,DH) +#define _REXBrr(RR,MR) _m64(__REXw_x_(_r1e8lP(RR)||_r1e8lP(MR),0,RR,0,MR)) +#define _REXBmr(MB,MI,RD) _m64(__REXw_x_(_r1e8lP(RD)||_r1e8lP(MB),0,RD,_BIT(_rXP(MI)),MB)) +#define _REXBrm(RS,MB,MI) _REXBmr(MB,MI,RS) + +#define _REXBLrr(RR,MR) _m64(__REXw_x_(_r1e8lP(MR),0,RR,0,MR)) +#define _REXLrr(RR,MR) _m64(__REXw_x_(0,0,RR,0,MR)) +#define _REXLmr(MB,MI,RD) _m64(__REXw_x_(0,0,RD,_BIT(_rXP(MI)),MB)) +#define _REXLrm(RS,MB,MI) _REXLmr(MB,MI,RS) +#define _REXLr(RR) _m64(__REX_reg(RR)) +#define _REXLm(MB,MI) _m64(__REX_mem(MB,MI)) + +#define _REXQrr(RR,MR) _m64only(__REXw_x_(0,1,RR,0,MR)) +#define _REXQmr(MB,MI,RD) _m64only(__REXw_x_(0,1,RD,_BIT(_rXP(MI)),MB)) +#define _REXQrm(RS,MB,MI) _REXQmr(MB,MI,RS) +#define _REXQr(RR) _m64only(__REX_reg(RR)) +#define _REXQm(MB,MI) _m64only(__REX_mem(MB,MI)) + + +/* ========================================================================= */ +/* --- Fully-qualified intrinsic instructions ------------------------------ */ +/* ========================================================================= */ + +/* OPCODE + i = immediate operand + * + r = register operand + * + m = memory operand (disp,base,index,scale) + * + sr/sm = a star preceding a register or memory + * + 0 = top of stack register (for FPU instructions) + * + * NOTE in x86-64 mode: a memory operand with only a valid + * displacement value will lead to the expect absolute mode. If + * RIP addressing is necessary, X86_RIP shall be used as the base + * register argument. + */ + +/* --- ALU instructions ---------------------------------------------------- */ + +enum { + X86_ADD = 0, + X86_OR = 1, + X86_ADC = 2, + X86_SBB = 3, + X86_AND = 4, + X86_SUB = 5, + X86_XOR = 6, + X86_CMP = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _ALUBrr(OP,RS, RD) (_REXBrr(RS, RD), _O_Mrm (((OP) << 3) ,_b11,_r1(RS),_r1(RD) )) +#define _ALUBmr(OP, MD, MB, MI, MS, RD) (_REXBmr(MB, MI, RD), _O_r_X (((OP) << 3) + 2,_r1(RD) ,MD,MB,MI,MS )) +#define _ALUBrm(OP, RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (((OP) << 3) , ,_r1(RS) ,MD,MB,MI,MS )) +#define _ALUBir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AL) ? \ + (_REXBrr(0, RD), _O_B (((OP) << 3) + 4 ,_su8(IM))) : \ + (_REXBrr(0, RD), _O_Mrm_B (0x80 ,_b11,OP ,_r1(RD) ,_su8(IM))) ) +#define _ALUBim(OP, IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X_B (0x80 ,OP ,MD,MB,MI,MS ,_su8(IM))) + +#define _ALUWrr(OP, RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r2(RS),_r2(RD) )) +#define _ALUWmr(OP, MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r2(RD) ,MD,MB,MI,MS )) +#define _ALUWrm(OP, RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r2(RS) ,MD,MB,MI,MS )) +#define _ALUWir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AX) ? \ + (_d16(), _REXLrr(0, RD), _O_W (((OP) << 3) + 5 ,_su16(IM))) : \ + (_d16(), _REXLrr(0, RD), _Os_Mrm_sW (0x81 ,_b11,OP ,_r2(RD) ,_su16(IM))) ) +#define _ALUWim(OP, IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _Os_r_X_sW (0x81 ,OP ,MD,MB,MI,MS ,_su16(IM))) + +#define _ALULrr(OP, RS, RD) (_REXLrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r4(RS),_r4(RD) )) +#define _ALULmr(OP, MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r4(RD) ,MD,MB,MI,MS )) +#define _ALULrm(OP, RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r4(RS) ,MD,MB,MI,MS )) +#define _ALULir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_EAX) ? \ + (_REXLrr(0, RD), _O_L (((OP) << 3) + 5 ,IM )) : \ + (_REXLrr(0, RD), _Os_Mrm_sL (0x81 ,_b11,OP ,_r4(RD) ,IM )) ) +#define _ALULim(OP, IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _Os_r_X_sL (0x81 ,OP ,MD,MB,MI,MS ,IM )) + +#define _ALUQrr(OP, RS, RD) (_REXQrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r8(RS),_r8(RD) )) +#define _ALUQmr(OP, MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r8(RD) ,MD,MB,MI,MS )) +#define _ALUQrm(OP, RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r8(RS) ,MD,MB,MI,MS )) +#define _ALUQir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_RAX) ? \ + (_REXQrr(0, RD), _O_L (((OP) << 3) + 5 ,IM )) : \ + (_REXQrr(0, RD), _Os_Mrm_sL (0x81 ,_b11,OP ,_r8(RD) ,IM )) ) +#define _ALUQim(OP, IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _Os_r_X_sL (0x81 ,OP ,MD,MB,MI,MS ,IM )) + +#define ADCBrr(RS, RD) _ALUBrr(X86_ADC, RS, RD) +#define ADCBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCBir(IM, RD) _ALUBir(X86_ADC, IM, RD) +#define ADCBim(IM, MD, MB, MI, MS) _ALUBim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADCWrr(RS, RD) _ALUWrr(X86_ADC, RS, RD) +#define ADCWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCWir(IM, RD) _ALUWir(X86_ADC, IM, RD) +#define ADCWim(IM, MD, MB, MI, MS) _ALUWim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADCLrr(RS, RD) _ALULrr(X86_ADC, RS, RD) +#define ADCLmr(MD, MB, MI, MS, RD) _ALULmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCLrm(RS, MD, MB, MI, MS) _ALULrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCLir(IM, RD) _ALULir(X86_ADC, IM, RD) +#define ADCLim(IM, MD, MB, MI, MS) _ALULim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADCQrr(RS, RD) _ALUQrr(X86_ADC, RS, RD) +#define ADCQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCQir(IM, RD) _ALUQir(X86_ADC, IM, RD) +#define ADCQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADDBrr(RS, RD) _ALUBrr(X86_ADD, RS, RD) +#define ADDBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDBir(IM, RD) _ALUBir(X86_ADD, IM, RD) +#define ADDBim(IM, MD, MB, MI, MS) _ALUBim(X86_ADD, IM, MD, MB, MI, MS) + +#define ADDWrr(RS, RD) _ALUWrr(X86_ADD, RS, RD) +#define ADDWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDWir(IM, RD) _ALUWir(X86_ADD, IM, RD) +#define ADDWim(IM, MD, MB, MI, MS) _ALUWim(X86_ADD, IM, MD, MB, MI, MS) + +#define ADDLrr(RS, RD) _ALULrr(X86_ADD, RS, RD) +#define ADDLmr(MD, MB, MI, MS, RD) _ALULmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDLrm(RS, MD, MB, MI, MS) _ALULrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDLir(IM, RD) _ALULir(X86_ADD, IM, RD) +#define ADDLim(IM, MD, MB, MI, MS) _ALULim(X86_ADD, IM, MD, MB, MI, MS) + +#define ADDQrr(RS, RD) _ALUQrr(X86_ADD, RS, RD) +#define ADDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDQir(IM, RD) _ALUQir(X86_ADD, IM, RD) +#define ADDQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADD, IM, MD, MB, MI, MS) + +#define ANDBrr(RS, RD) _ALUBrr(X86_AND, RS, RD) +#define ANDBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDBir(IM, RD) _ALUBir(X86_AND, IM, RD) +#define ANDBim(IM, MD, MB, MI, MS) _ALUBim(X86_AND, IM, MD, MB, MI, MS) + +#define ANDWrr(RS, RD) _ALUWrr(X86_AND, RS, RD) +#define ANDWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDWir(IM, RD) _ALUWir(X86_AND, IM, RD) +#define ANDWim(IM, MD, MB, MI, MS) _ALUWim(X86_AND, IM, MD, MB, MI, MS) + +#define ANDLrr(RS, RD) _ALULrr(X86_AND, RS, RD) +#define ANDLmr(MD, MB, MI, MS, RD) _ALULmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDLrm(RS, MD, MB, MI, MS) _ALULrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDLir(IM, RD) _ALULir(X86_AND, IM, RD) +#define ANDLim(IM, MD, MB, MI, MS) _ALULim(X86_AND, IM, MD, MB, MI, MS) + +#define ANDQrr(RS, RD) _ALUQrr(X86_AND, RS, RD) +#define ANDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDQir(IM, RD) _ALUQir(X86_AND, IM, RD) +#define ANDQim(IM, MD, MB, MI, MS) _ALUQim(X86_AND, IM, MD, MB, MI, MS) + +#define CMPBrr(RS, RD) _ALUBrr(X86_CMP, RS, RD) +#define CMPBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPBir(IM, RD) _ALUBir(X86_CMP, IM, RD) +#define CMPBim(IM, MD, MB, MI, MS) _ALUBim(X86_CMP, IM, MD, MB, MI, MS) + +#define CMPWrr(RS, RD) _ALUWrr(X86_CMP, RS, RD) +#define CMPWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPWir(IM, RD) _ALUWir(X86_CMP, IM, RD) +#define CMPWim(IM, MD, MB, MI, MS) _ALUWim(X86_CMP, IM, MD, MB, MI, MS) + +#define CMPLrr(RS, RD) _ALULrr(X86_CMP, RS, RD) +#define CMPLmr(MD, MB, MI, MS, RD) _ALULmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPLrm(RS, MD, MB, MI, MS) _ALULrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPLir(IM, RD) _ALULir(X86_CMP, IM, RD) +#define CMPLim(IM, MD, MB, MI, MS) _ALULim(X86_CMP, IM, MD, MB, MI, MS) + +#define CMPQrr(RS, RD) _ALUQrr(X86_CMP, RS, RD) +#define CMPQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPQir(IM, RD) _ALUQir(X86_CMP, IM, RD) +#define CMPQim(IM, MD, MB, MI, MS) _ALUQim(X86_CMP, IM, MD, MB, MI, MS) + +#define ORBrr(RS, RD) _ALUBrr(X86_OR, RS, RD) +#define ORBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_OR, MD, MB, MI, MS, RD) +#define ORBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_OR, RS, MD, MB, MI, MS) +#define ORBir(IM, RD) _ALUBir(X86_OR, IM, RD) +#define ORBim(IM, MD, MB, MI, MS) _ALUBim(X86_OR, IM, MD, MB, MI, MS) + +#define ORWrr(RS, RD) _ALUWrr(X86_OR, RS, RD) +#define ORWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_OR, MD, MB, MI, MS, RD) +#define ORWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_OR, RS, MD, MB, MI, MS) +#define ORWir(IM, RD) _ALUWir(X86_OR, IM, RD) +#define ORWim(IM, MD, MB, MI, MS) _ALUWim(X86_OR, IM, MD, MB, MI, MS) + +#define ORLrr(RS, RD) _ALULrr(X86_OR, RS, RD) +#define ORLmr(MD, MB, MI, MS, RD) _ALULmr(X86_OR, MD, MB, MI, MS, RD) +#define ORLrm(RS, MD, MB, MI, MS) _ALULrm(X86_OR, RS, MD, MB, MI, MS) +#define ORLir(IM, RD) _ALULir(X86_OR, IM, RD) +#define ORLim(IM, MD, MB, MI, MS) _ALULim(X86_OR, IM, MD, MB, MI, MS) + +#define ORQrr(RS, RD) _ALUQrr(X86_OR, RS, RD) +#define ORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_OR, MD, MB, MI, MS, RD) +#define ORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_OR, RS, MD, MB, MI, MS) +#define ORQir(IM, RD) _ALUQir(X86_OR, IM, RD) +#define ORQim(IM, MD, MB, MI, MS) _ALUQim(X86_OR, IM, MD, MB, MI, MS) + +#define SBBBrr(RS, RD) _ALUBrr(X86_SBB, RS, RD) +#define SBBBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBBir(IM, RD) _ALUBir(X86_SBB, IM, RD) +#define SBBBim(IM, MD, MB, MI, MS) _ALUBim(X86_SBB, IM, MD, MB, MI, MS) + +#define SBBWrr(RS, RD) _ALUWrr(X86_SBB, RS, RD) +#define SBBWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBWir(IM, RD) _ALUWir(X86_SBB, IM, RD) +#define SBBWim(IM, MD, MB, MI, MS) _ALUWim(X86_SBB, IM, MD, MB, MI, MS) + +#define SBBLrr(RS, RD) _ALULrr(X86_SBB, RS, RD) +#define SBBLmr(MD, MB, MI, MS, RD) _ALULmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBLrm(RS, MD, MB, MI, MS) _ALULrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBLir(IM, RD) _ALULir(X86_SBB, IM, RD) +#define SBBLim(IM, MD, MB, MI, MS) _ALULim(X86_SBB, IM, MD, MB, MI, MS) + +#define SBBQrr(RS, RD) _ALUQrr(X86_SBB, RS, RD) +#define SBBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBQir(IM, RD) _ALUQir(X86_SBB, IM, RD) +#define SBBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SBB, IM, MD, MB, MI, MS) + +#define SUBBrr(RS, RD) _ALUBrr(X86_SUB, RS, RD) +#define SUBBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBBir(IM, RD) _ALUBir(X86_SUB, IM, RD) +#define SUBBim(IM, MD, MB, MI, MS) _ALUBim(X86_SUB, IM, MD, MB, MI, MS) + +#define SUBWrr(RS, RD) _ALUWrr(X86_SUB, RS, RD) +#define SUBWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBWir(IM, RD) _ALUWir(X86_SUB, IM, RD) +#define SUBWim(IM, MD, MB, MI, MS) _ALUWim(X86_SUB, IM, MD, MB, MI, MS) + +#define SUBLrr(RS, RD) _ALULrr(X86_SUB, RS, RD) +#define SUBLmr(MD, MB, MI, MS, RD) _ALULmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBLrm(RS, MD, MB, MI, MS) _ALULrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBLir(IM, RD) _ALULir(X86_SUB, IM, RD) +#define SUBLim(IM, MD, MB, MI, MS) _ALULim(X86_SUB, IM, MD, MB, MI, MS) + +#define SUBQrr(RS, RD) _ALUQrr(X86_SUB, RS, RD) +#define SUBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBQir(IM, RD) _ALUQir(X86_SUB, IM, RD) +#define SUBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SUB, IM, MD, MB, MI, MS) + +#define XORBrr(RS, RD) _ALUBrr(X86_XOR, RS, RD) +#define XORBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORBir(IM, RD) _ALUBir(X86_XOR, IM, RD) +#define XORBim(IM, MD, MB, MI, MS) _ALUBim(X86_XOR, IM, MD, MB, MI, MS) + +#define XORWrr(RS, RD) _ALUWrr(X86_XOR, RS, RD) +#define XORWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORWir(IM, RD) _ALUWir(X86_XOR, IM, RD) +#define XORWim(IM, MD, MB, MI, MS) _ALUWim(X86_XOR, IM, MD, MB, MI, MS) + +#define XORLrr(RS, RD) _ALULrr(X86_XOR, RS, RD) +#define XORLmr(MD, MB, MI, MS, RD) _ALULmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORLrm(RS, MD, MB, MI, MS) _ALULrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORLir(IM, RD) _ALULir(X86_XOR, IM, RD) +#define XORLim(IM, MD, MB, MI, MS) _ALULim(X86_XOR, IM, MD, MB, MI, MS) + +#define XORQrr(RS, RD) _ALUQrr(X86_XOR, RS, RD) +#define XORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORQir(IM, RD) _ALUQir(X86_XOR, IM, RD) +#define XORQim(IM, MD, MB, MI, MS) _ALUQim(X86_XOR, IM, MD, MB, MI, MS) + + +/* --- Shift/Rotate instructions ------------------------------------------- */ + +enum { + X86_ROL = 0, + X86_ROR = 1, + X86_RCL = 2, + X86_RCR = 3, + X86_SHL = 4, + X86_SHR = 5, + X86_SAR = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _ROTSHIBir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXBrr(0, RD), _O_Mrm (0xd0 ,_b11,OP,_r1(RD) )) : \ + (_REXBrr(0, RD), _O_Mrm_B (0xc0 ,_b11,OP,_r1(RD) ,_u8(IM))) ) +#define _ROTSHIBim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXBrm(0, MB, MI), _O_r_X (0xd0 ,OP ,MD,MB,MI,MS )) : \ + (_REXBrm(0, MB, MI), _O_r_X_B (0xc0 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHIBrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_REXBrr(RS, RD), _O_Mrm (0xd2 ,_b11,OP,_r1(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHIBrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_REXBrm(RS, MB, MI), _O_r_X (0xd2 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define _ROTSHIWir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_d16(), _REXLrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r2(RD) )) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r2(RD) ,_u8(IM))) ) +#define _ROTSHIWim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ + (_d16(), _REXLrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHIWrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_d16(), _REXLrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r2(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHIWrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define _ROTSHILir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXLrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r4(RD) )) : \ + (_REXLrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r4(RD) ,_u8(IM))) ) +#define _ROTSHILim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXLrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ + (_REXLrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHILrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_REXLrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r4(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHILrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_REXLrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define _ROTSHIQir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXQrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r8(RD) )) : \ + (_REXQrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r8(RD) ,_u8(IM))) ) +#define _ROTSHIQim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXQrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ + (_REXQrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHIQrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_REXQrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r8(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHIQrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_REXQrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define ROLBir(IM, RD) _ROTSHIBir(X86_ROL, IM, RD) +#define ROLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLBrr(RS, RD) _ROTSHIBrr(X86_ROL, RS, RD) +#define ROLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_ROL, RS, MD, MB, MI, MS) + +#define ROLWir(IM, RD) _ROTSHIWir(X86_ROL, IM, RD) +#define ROLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLWrr(RS, RD) _ROTSHIWrr(X86_ROL, RS, RD) +#define ROLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_ROL, RS, MD, MB, MI, MS) + +#define ROLLir(IM, RD) _ROTSHILir(X86_ROL, IM, RD) +#define ROLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLLrr(RS, RD) _ROTSHILrr(X86_ROL, RS, RD) +#define ROLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_ROL, RS, MD, MB, MI, MS) + +#define ROLQir(IM, RD) _ROTSHIQir(X86_ROL, IM, RD) +#define ROLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLQrr(RS, RD) _ROTSHIQrr(X86_ROL, RS, RD) +#define ROLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROL, RS, MD, MB, MI, MS) + +#define RORBir(IM, RD) _ROTSHIBir(X86_ROR, IM, RD) +#define RORBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_ROR, IM, MD, MB, MI, MS) +#define RORBrr(RS, RD) _ROTSHIBrr(X86_ROR, RS, RD) +#define RORBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RORWir(IM, RD) _ROTSHIWir(X86_ROR, IM, RD) +#define RORWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_ROR, IM, MD, MB, MI, MS) +#define RORWrr(RS, RD) _ROTSHIWrr(X86_ROR, RS, RD) +#define RORWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RORLir(IM, RD) _ROTSHILir(X86_ROR, IM, RD) +#define RORLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_ROR, IM, MD, MB, MI, MS) +#define RORLrr(RS, RD) _ROTSHILrr(X86_ROR, RS, RD) +#define RORLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RORQir(IM, RD) _ROTSHIQir(X86_ROR, IM, RD) +#define RORQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROR, IM, MD, MB, MI, MS) +#define RORQrr(RS, RD) _ROTSHIQrr(X86_ROR, RS, RD) +#define RORQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RCLBir(IM, RD) _ROTSHIBir(X86_RCL, IM, RD) +#define RCLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLBrr(RS, RD) _ROTSHIBrr(X86_RCL, RS, RD) +#define RCLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCLWir(IM, RD) _ROTSHIWir(X86_RCL, IM, RD) +#define RCLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLWrr(RS, RD) _ROTSHIWrr(X86_RCL, RS, RD) +#define RCLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCLLir(IM, RD) _ROTSHILir(X86_RCL, IM, RD) +#define RCLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLLrr(RS, RD) _ROTSHILrr(X86_RCL, RS, RD) +#define RCLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCLQir(IM, RD) _ROTSHIQir(X86_RCL, IM, RD) +#define RCLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLQrr(RS, RD) _ROTSHIQrr(X86_RCL, RS, RD) +#define RCLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCRBir(IM, RD) _ROTSHIBir(X86_RCR, IM, RD) +#define RCRBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRBrr(RS, RD) _ROTSHIBrr(X86_RCR, RS, RD) +#define RCRBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_RCR, RS, MD, MB, MI, MS) + +#define RCRWir(IM, RD) _ROTSHIWir(X86_RCR, IM, RD) +#define RCRWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRWrr(RS, RD) _ROTSHIWrr(X86_RCR, RS, RD) +#define RCRWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_RCR, RS, MD, MB, MI, MS) + +#define RCRLir(IM, RD) _ROTSHILir(X86_RCR, IM, RD) +#define RCRLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRLrr(RS, RD) _ROTSHILrr(X86_RCR, RS, RD) +#define RCRLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_RCR, RS, MD, MB, MI, MS) + +#define RCRQir(IM, RD) _ROTSHIQir(X86_RCR, IM, RD) +#define RCRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRQrr(RS, RD) _ROTSHIQrr(X86_RCR, RS, RD) +#define RCRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCR, RS, MD, MB, MI, MS) + +#define SHLBir(IM, RD) _ROTSHIBir(X86_SHL, IM, RD) +#define SHLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLBrr(RS, RD) _ROTSHIBrr(X86_SHL, RS, RD) +#define SHLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHLWir(IM, RD) _ROTSHIWir(X86_SHL, IM, RD) +#define SHLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLWrr(RS, RD) _ROTSHIWrr(X86_SHL, RS, RD) +#define SHLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHLLir(IM, RD) _ROTSHILir(X86_SHL, IM, RD) +#define SHLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLLrr(RS, RD) _ROTSHILrr(X86_SHL, RS, RD) +#define SHLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHLQir(IM, RD) _ROTSHIQir(X86_SHL, IM, RD) +#define SHLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLQrr(RS, RD) _ROTSHIQrr(X86_SHL, RS, RD) +#define SHLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHRBir(IM, RD) _ROTSHIBir(X86_SHR, IM, RD) +#define SHRBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRBrr(RS, RD) _ROTSHIBrr(X86_SHR, RS, RD) +#define SHRBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SHRWir(IM, RD) _ROTSHIWir(X86_SHR, IM, RD) +#define SHRWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRWrr(RS, RD) _ROTSHIWrr(X86_SHR, RS, RD) +#define SHRWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SHRLir(IM, RD) _ROTSHILir(X86_SHR, IM, RD) +#define SHRLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRLrr(RS, RD) _ROTSHILrr(X86_SHR, RS, RD) +#define SHRLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SHRQir(IM, RD) _ROTSHIQir(X86_SHR, IM, RD) +#define SHRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRQrr(RS, RD) _ROTSHIQrr(X86_SHR, RS, RD) +#define SHRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SALBir SHLBir +#define SALBim SHLBim +#define SALBrr SHLBrr +#define SALBrm SHLBrm + +#define SALWir SHLWir +#define SALWim SHLWim +#define SALWrr SHLWrr +#define SALWrm SHLWrm + +#define SALLir SHLLir +#define SALLim SHLLim +#define SALLrr SHLLrr +#define SALLrm SHLLrm + +#define SALQir SHLQir +#define SALQim SHLQim +#define SALQrr SHLQrr +#define SALQrm SHLQrm + +#define SARBir(IM, RD) _ROTSHIBir(X86_SAR, IM, RD) +#define SARBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SAR, IM, MD, MB, MI, MS) +#define SARBrr(RS, RD) _ROTSHIBrr(X86_SAR, RS, RD) +#define SARBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SAR, RS, MD, MB, MI, MS) + +#define SARWir(IM, RD) _ROTSHIWir(X86_SAR, IM, RD) +#define SARWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SAR, IM, MD, MB, MI, MS) +#define SARWrr(RS, RD) _ROTSHIWrr(X86_SAR, RS, RD) +#define SARWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SAR, RS, MD, MB, MI, MS) + +#define SARLir(IM, RD) _ROTSHILir(X86_SAR, IM, RD) +#define SARLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SAR, IM, MD, MB, MI, MS) +#define SARLrr(RS, RD) _ROTSHILrr(X86_SAR, RS, RD) +#define SARLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SAR, RS, MD, MB, MI, MS) + +#define SARQir(IM, RD) _ROTSHIQir(X86_SAR, IM, RD) +#define SARQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SAR, IM, MD, MB, MI, MS) +#define SARQrr(RS, RD) _ROTSHIQrr(X86_SAR, RS, RD) +#define SARQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SAR, RS, MD, MB, MI, MS) + + +/* --- Bit test instructions ----------------------------------------------- */ + +enum { + X86_BT = 4, + X86_BTS = 5, + X86_BTR = 6, + X86_BTC = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _BTWir(OP, IM, RD) (_d16(), _REXLrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r2(RD) ,_u8(IM))) +#define _BTWim(OP, IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) +#define _BTWrr(OP, RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r2(RS),_r2(RD) )) +#define _BTWrm(OP, RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r2(RS) ,MD,MB,MI,MS )) + +#define _BTLir(OP, IM, RD) (_REXLrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r4(RD) ,_u8(IM))) +#define _BTLim(OP, IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) +#define _BTLrr(OP, RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r4(RS),_r4(RD) )) +#define _BTLrm(OP, RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r4(RS) ,MD,MB,MI,MS )) + +#define _BTQir(OP, IM, RD) (_REXQrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r8(RD) ,_u8(IM))) +#define _BTQim(OP, IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) +#define _BTQrr(OP, RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r8(RS),_r8(RD) )) +#define _BTQrm(OP, RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r8(RS) ,MD,MB,MI,MS )) + +#define BTWir(IM, RD) _BTWir(X86_BT, IM, RD) +#define BTWim(IM, MD, MB, MI, MS) _BTWim(X86_BT, IM, MD, MI, MS) +#define BTWrr(RS, RD) _BTWrr(X86_BT, RS, RD) +#define BTWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BT, RS, MD, MB, MI, MS) + +#define BTLir(IM, RD) _BTLir(X86_BT, IM, RD) +#define BTLim(IM, MD, MB, MI, MS) _BTLim(X86_BT, IM, MD, MB, MI, MS) +#define BTLrr(RS, RD) _BTLrr(X86_BT, RS, RD) +#define BTLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BT, RS, MD, MB, MI, MS) + +#define BTQir(IM, RD) _BTQir(X86_BT, IM, RD) +#define BTQim(IM, MD, MB, MI, MS) _BTQim(X86_BT, IM, MD, MB, MI, MS) +#define BTQrr(RS, RD) _BTQrr(X86_BT, RS, RD) +#define BTQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BT, RS, MD, MB, MI, MS) + +#define BTCWir(IM, RD) _BTWir(X86_BTC, IM, RD) +#define BTCWim(IM, MD, MB, MI, MS) _BTWim(X86_BTC, IM, MD, MI, MS) +#define BTCWrr(RS, RD) _BTWrr(X86_BTC, RS, RD) +#define BTCWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTC, RS, MD, MB, MI, MS) + +#define BTCLir(IM, RD) _BTLir(X86_BTC, IM, RD) +#define BTCLim(IM, MD, MB, MI, MS) _BTLim(X86_BTC, IM, MD, MB, MI, MS) +#define BTCLrr(RS, RD) _BTLrr(X86_BTC, RS, RD) +#define BTCLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTC, RS, MD, MB, MI, MS) + +#define BTCQir(IM, RD) _BTQir(X86_BTC, IM, RD) +#define BTCQim(IM, MD, MB, MI, MS) _BTQim(X86_BTC, IM, MD, MB, MI, MS) +#define BTCQrr(RS, RD) _BTQrr(X86_BTC, RS, RD) +#define BTCQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTC, RS, MD, MB, MI, MS) + +#define BTRWir(IM, RD) _BTWir(X86_BTR, IM, RD) +#define BTRWim(IM, MD, MB, MI, MS) _BTWim(X86_BTR, IM, MD, MI, MS) +#define BTRWrr(RS, RD) _BTWrr(X86_BTR, RS, RD) +#define BTRWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTR, RS, MD, MB, MI, MS) + +#define BTRLir(IM, RD) _BTLir(X86_BTR, IM, RD) +#define BTRLim(IM, MD, MB, MI, MS) _BTLim(X86_BTR, IM, MD, MB, MI, MS) +#define BTRLrr(RS, RD) _BTLrr(X86_BTR, RS, RD) +#define BTRLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTR, RS, MD, MB, MI, MS) + +#define BTRQir(IM, RD) _BTQir(X86_BTR, IM, RD) +#define BTRQim(IM, MD, MB, MI, MS) _BTQim(X86_BTR, IM, MD, MB, MI, MS) +#define BTRQrr(RS, RD) _BTQrr(X86_BTR, RS, RD) +#define BTRQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTR, RS, MD, MB, MI, MS) + +#define BTSWir(IM, RD) _BTWir(X86_BTS, IM, RD) +#define BTSWim(IM, MD, MB, MI, MS) _BTWim(X86_BTS, IM, MD, MI, MS) +#define BTSWrr(RS, RD) _BTWrr(X86_BTS, RS, RD) +#define BTSWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTS, RS, MD, MB, MI, MS) + +#define BTSLir(IM, RD) _BTLir(X86_BTS, IM, RD) +#define BTSLim(IM, MD, MB, MI, MS) _BTLim(X86_BTS, IM, MD, MB, MI, MS) +#define BTSLrr(RS, RD) _BTLrr(X86_BTS, RS, RD) +#define BTSLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTS, RS, MD, MB, MI, MS) + +#define BTSQir(IM, RD) _BTQir(X86_BTS, IM, RD) +#define BTSQim(IM, MD, MB, MI, MS) _BTQim(X86_BTS, IM, MD, MB, MI, MS) +#define BTSQrr(RS, RD) _BTQrr(X86_BTS, RS, RD) +#define BTSQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTS, RS, MD, MB, MI, MS) + + +/* --- Move instructions --------------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define MOVBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x88 ,_b11,_r1(RS),_r1(RD) )) +#define MOVBmr(MD, MB, MI, MS, RD) (_REXBmr(MB, MI, RD), _O_r_X (0x8a ,_r1(RD) ,MD,MB,MI,MS )) +#define MOVBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x88 ,_r1(RS) ,MD,MB,MI,MS )) +#define MOVBir(IM, R) (_REXBrr(0, R), _Or_B (0xb0,_r1(R) ,_su8(IM))) +#define MOVBim(IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_X_B (0xc6 ,MD,MB,MI,MS ,_su8(IM))) + +#define MOVWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x89 ,_b11,_r2(RS),_r2(RD) )) +#define MOVWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _O_r_X (0x8b ,_r2(RD) ,MD,MB,MI,MS )) +#define MOVWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x89 ,_r2(RS) ,MD,MB,MI,MS )) +#define MOVWir(IM, R) (_d16(), _REXLrr(0, R), _Or_W (0xb8,_r2(R) ,_su16(IM))) +#define MOVWim(IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_X_W (0xc7 ,MD,MB,MI,MS ,_su16(IM))) + +#define MOVLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x89 ,_b11,_r4(RS),_r4(RD) )) +#define MOVLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (0x8b ,_r4(RD) ,MD,MB,MI,MS )) +#define MOVLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x89 ,_r4(RS) ,MD,MB,MI,MS )) +#define MOVLir(IM, R) (_REXLrr(0, R), _Or_L (0xb8,_r4(R) ,IM )) +#define MOVLim(IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM )) + +#define MOVQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x89 ,_b11,_r8(RS),_r8(RD) )) +#define MOVQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8b ,_r8(RD) ,MD,MB,MI,MS )) +#define MOVQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x89 ,_r8(RS) ,MD,MB,MI,MS )) +#define MOVQir(IM, R) (_REXQrr(0, R), _Or_Q (0xb8,_r8(R) ,IM )) +#define MOVQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM )) + + +/* --- Unary and Multiply/Divide instructions ------------------------------ */ + +enum { + X86_NOT = 2, + X86_NEG = 3, + X86_MUL = 4, + X86_IMUL = 5, + X86_DIV = 6, + X86_IDIV = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _UNARYBr(OP, RS) (_REXBrr(0, RS), _O_Mrm (0xf6 ,_b11,OP ,_r1(RS) )) +#define _UNARYBm(OP, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xf6 ,OP ,MD,MB,MI,MS )) +#define _UNARYWr(OP, RS) (_d16(), _REXLrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r2(RS) )) +#define _UNARYWm(OP, MD, MB, MI, MS) (_d16(), _REXLmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) +#define _UNARYLr(OP, RS) (_REXLrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r4(RS) )) +#define _UNARYLm(OP, MD, MB, MI, MS) (_REXLmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) +#define _UNARYQr(OP, RS) (_REXQrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r8(RS) )) +#define _UNARYQm(OP, MD, MB, MI, MS) (_REXQmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) + +#define NOTBr(RS) _UNARYBr(X86_NOT, RS) +#define NOTBm(MD, MB, MI, MS) _UNARYBm(X86_NOT, MD, MB, MI, MS) +#define NOTWr(RS) _UNARYWr(X86_NOT, RS) +#define NOTWm(MD, MB, MI, MS) _UNARYWm(X86_NOT, MD, MB, MI, MS) +#define NOTLr(RS) _UNARYLr(X86_NOT, RS) +#define NOTLm(MD, MB, MI, MS) _UNARYLm(X86_NOT, MD, MB, MI, MS) +#define NOTQr(RS) _UNARYQr(X86_NOT, RS) +#define NOTQm(MD, MB, MI, MS) _UNARYQm(X86_NOT, MD, MB, MI, MS) + +#define NEGBr(RS) _UNARYBr(X86_NEG, RS) +#define NEGBm(MD, MB, MI, MS) _UNARYBm(X86_NEG, MD, MB, MI, MS) +#define NEGWr(RS) _UNARYWr(X86_NEG, RS) +#define NEGWm(MD, MB, MI, MS) _UNARYWm(X86_NEG, MD, MB, MI, MS) +#define NEGLr(RS) _UNARYLr(X86_NEG, RS) +#define NEGLm(MD, MB, MI, MS) _UNARYLm(X86_NEG, MD, MB, MI, MS) +#define NEGQr(RS) _UNARYQr(X86_NEG, RS) +#define NEGQm(MD, MB, MI, MS) _UNARYQm(X86_NEG, MD, MB, MI, MS) + +#define MULBr(RS) _UNARYBr(X86_MUL, RS) +#define MULBm(MD, MB, MI, MS) _UNARYBm(X86_MUL, MD, MB, MI, MS) +#define MULWr(RS) _UNARYWr(X86_MUL, RS) +#define MULWm(MD, MB, MI, MS) _UNARYWm(X86_MUL, MD, MB, MI, MS) +#define MULLr(RS) _UNARYLr(X86_MUL, RS) +#define MULLm(MD, MB, MI, MS) _UNARYLm(X86_MUL, MD, MB, MI, MS) +#define MULQr(RS) _UNARYQr(X86_MUL, RS) +#define MULQm(MD, MB, MI, MS) _UNARYQm(X86_MUL, MD, MB, MI, MS) + +#define IMULBr(RS) _UNARYBr(X86_IMUL, RS) +#define IMULBm(MD, MB, MI, MS) _UNARYBm(X86_IMUL, MD, MB, MI, MS) +#define IMULWr(RS) _UNARYWr(X86_IMUL, RS) +#define IMULWm(MD, MB, MI, MS) _UNARYWm(X86_IMUL, MD, MB, MI, MS) +#define IMULLr(RS) _UNARYLr(X86_IMUL, RS) +#define IMULLm(MD, MB, MI, MS) _UNARYLm(X86_IMUL, MD, MB, MI, MS) +#define IMULQr(RS) _UNARYQr(X86_IMUL, RS) +#define IMULQm(MD, MB, MI, MS) _UNARYQm(X86_IMUL, MD, MB, MI, MS) + +#define DIVBr(RS) _UNARYBr(X86_DIV, RS) +#define DIVBm(MD, MB, MI, MS) _UNARYBm(X86_DIV, MD, MB, MI, MS) +#define DIVWr(RS) _UNARYWr(X86_DIV, RS) +#define DIVWm(MD, MB, MI, MS) _UNARYWm(X86_DIV, MD, MB, MI, MS) +#define DIVLr(RS) _UNARYLr(X86_DIV, RS) +#define DIVLm(MD, MB, MI, MS) _UNARYLm(X86_DIV, MD, MB, MI, MS) +#define DIVQr(RS) _UNARYQr(X86_DIV, RS) +#define DIVQm(MD, MB, MI, MS) _UNARYQm(X86_DIV, MD, MB, MI, MS) + +#define IDIVBr(RS) _UNARYBr(X86_IDIV, RS) +#define IDIVBm(MD, MB, MI, MS) _UNARYBm(X86_IDIV, MD, MB, MI, MS) +#define IDIVWr(RS) _UNARYWr(X86_IDIV, RS) +#define IDIVWm(MD, MB, MI, MS) _UNARYWm(X86_IDIV, MD, MB, MI, MS) +#define IDIVLr(RS) _UNARYLr(X86_IDIV, RS) +#define IDIVLm(MD, MB, MI, MS) _UNARYLm(X86_IDIV, MD, MB, MI, MS) +#define IDIVQr(RS) _UNARYQr(X86_IDIV, RS) +#define IDIVQm(MD, MB, MI, MS) _UNARYQm(X86_IDIV, MD, MB, MI, MS) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define IMULWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r2(RD),_r2(RS) )) +#define IMULWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0faf ,_r2(RD) ,MD,MB,MI,MS )) + +#define IMULWirr(IM,RS,RD) (_d16(), _REXLrr(RS, RD), _Os_Mrm_sW (0x69 ,_b11,_r2(RS),_r2(RD) ,_su16(IM) )) +#define IMULWimr(IM,MD,MB,MI,MS,RD) (_d16(), _REXLmr(MB, MI, RD), _Os_r_X_sW (0x69 ,_r2(RD) ,MD,MB,MI,MS ,_su16(IM) )) + +#define IMULLir(IM, RD) (_REXLrr(0, RD), _Os_Mrm_sL (0x69 ,_b11,_r4(RD),_r4(RD) ,IM )) +#define IMULLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r4(RD),_r4(RS) )) +#define IMULLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0faf ,_r4(RD) ,MD,MB,MI,MS )) + +#define IMULQir(IM, RD) (_REXQrr(0, RD), _Os_Mrm_sL (0x69 ,_b11,_r8(RD),_r8(RD) ,IM )) +#define IMULQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r8(RD),_r8(RS) )) +#define IMULQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0faf ,_r8(RD) ,MD,MB,MI,MS )) + +#define IMULLirr(IM,RS,RD) (_REXLrr(RS, RD), _Os_Mrm_sL (0x69 ,_b11,_r4(RS),_r4(RD) ,IM )) +#define IMULLimr(IM,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r4(RD) ,MD,MB,MI,MS ,IM )) + +#define IMULQirr(IM,RS,RD) (_REXQrr(RS, RD), _Os_Mrm_sL (0x69 ,_b11,_r8(RS),_r8(RD) ,IM )) +#define IMULQimr(IM,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r8(RD) ,MD,MB,MI,MS ,IM )) + + +/* --- Control Flow related instructions ----------------------------------- */ + +enum { + X86_CC_O = 0x0, + X86_CC_NO = 0x1, + X86_CC_NAE = 0x2, + X86_CC_B = 0x2, + X86_CC_C = 0x2, + X86_CC_AE = 0x3, + X86_CC_NB = 0x3, + X86_CC_NC = 0x3, + X86_CC_E = 0x4, + X86_CC_Z = 0x4, + X86_CC_NE = 0x5, + X86_CC_NZ = 0x5, + X86_CC_BE = 0x6, + X86_CC_NA = 0x6, + X86_CC_A = 0x7, + X86_CC_NBE = 0x7, + X86_CC_S = 0x8, + X86_CC_NS = 0x9, + X86_CC_P = 0xa, + X86_CC_PE = 0xa, + X86_CC_NP = 0xb, + X86_CC_PO = 0xb, + X86_CC_L = 0xc, + X86_CC_NGE = 0xc, + X86_CC_GE = 0xd, + X86_CC_NL = 0xd, + X86_CC_LE = 0xe, + X86_CC_NG = 0xe, + X86_CC_G = 0xf, + X86_CC_NLE = 0xf, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode +#define CALLm(M) _O_D32 (0xe8 ,(int)(M) ) +#define _CALLLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r4(R) )) +#define _CALLQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r8(R) )) +#define CALLsr(R) ( X86_TARGET_64BIT ? _CALLQsr(R) : _CALLLsr(R)) +#define CALLsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b010 ,(int)(D),B,I,S )) + +// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode +#define JMPSm(M) _O_D8 (0xeb ,(int)(M) ) +#define JMPm(M) _O_D32 (0xe9 ,(int)(M) ) +#define _JMPLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r4(R) )) +#define _JMPQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r8(R) )) +#define JMPsr(R) ( X86_TARGET_64BIT ? _JMPQsr(R) : _JMPLsr(R)) +#define JMPsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b100 ,(int)(D),B,I,S )) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define JCCSii(CC, D) _O_B (0x70|(CC) ,(_sc)(int)(D) ) +#define JCCSim(CC, D) _O_D8 (0x70|(CC) ,(int)(D) ) +#define JOSm(D) JCCSim(0x0, D) +#define JNOSm(D) JCCSim(0x1, D) +#define JBSm(D) JCCSim(0x2, D) +#define JNAESm(D) JCCSim(0x2, D) +#define JNBSm(D) JCCSim(0x3, D) +#define JAESm(D) JCCSim(0x3, D) +#define JESm(D) JCCSim(0x4, D) +#define JZSm(D) JCCSim(0x4, D) +#define JNESm(D) JCCSim(0x5, D) +#define JNZSm(D) JCCSim(0x5, D) +#define JBESm(D) JCCSim(0x6, D) +#define JNASm(D) JCCSim(0x6, D) +#define JNBESm(D) JCCSim(0x7, D) +#define JASm(D) JCCSim(0x7, D) +#define JSSm(D) JCCSim(0x8, D) +#define JNSSm(D) JCCSim(0x9, D) +#define JPSm(D) JCCSim(0xa, D) +#define JPESm(D) JCCSim(0xa, D) +#define JNPSm(D) JCCSim(0xb, D) +#define JPOSm(D) JCCSim(0xb, D) +#define JLSm(D) JCCSim(0xc, D) +#define JNGESm(D) JCCSim(0xc, D) +#define JNLSm(D) JCCSim(0xd, D) +#define JGESm(D) JCCSim(0xd, D) +#define JLESm(D) JCCSim(0xe, D) +#define JNGSm(D) JCCSim(0xe, D) +#define JNLESm(D) JCCSim(0xf, D) +#define JGSm(D) JCCSim(0xf, D) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define JCCii(CC, D) _OO_L (0x0f80|(CC) ,(int)(D) ) +#define JCCim(CC, D) _OO_D32 (0x0f80|(CC) ,(int)(D) ) +#define JOm(D) JCCim(0x0, D) +#define JNOm(D) JCCim(0x1, D) +#define JBm(D) JCCim(0x2, D) +#define JNAEm(D) JCCim(0x2, D) +#define JNBm(D) JCCim(0x3, D) +#define JAEm(D) JCCim(0x3, D) +#define JEm(D) JCCim(0x4, D) +#define JZm(D) JCCim(0x4, D) +#define JNEm(D) JCCim(0x5, D) +#define JNZm(D) JCCim(0x5, D) +#define JBEm(D) JCCim(0x6, D) +#define JNAm(D) JCCim(0x6, D) +#define JNBEm(D) JCCim(0x7, D) +#define JAm(D) JCCim(0x7, D) +#define JSm(D) JCCim(0x8, D) +#define JNSm(D) JCCim(0x9, D) +#define JPm(D) JCCim(0xa, D) +#define JPEm(D) JCCim(0xa, D) +#define JNPm(D) JCCim(0xb, D) +#define JPOm(D) JCCim(0xb, D) +#define JLm(D) JCCim(0xc, D) +#define JNGEm(D) JCCim(0xc, D) +#define JNLm(D) JCCim(0xd, D) +#define JGEm(D) JCCim(0xd, D) +#define JLEm(D) JCCim(0xe, D) +#define JNGm(D) JCCim(0xe, D) +#define JNLEm(D) JCCim(0xf, D) +#define JGm(D) JCCim(0xf, D) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define SETCCir(CC, RD) (_REXBrr(0, RD), _OO_Mrm (0x0f90|(CC) ,_b11,_b000,_r1(RD) )) +#define SETOr(RD) SETCCir(0x0,RD) +#define SETNOr(RD) SETCCir(0x1,RD) +#define SETBr(RD) SETCCir(0x2,RD) +#define SETNAEr(RD) SETCCir(0x2,RD) +#define SETNBr(RD) SETCCir(0x3,RD) +#define SETAEr(RD) SETCCir(0x3,RD) +#define SETEr(RD) SETCCir(0x4,RD) +#define SETZr(RD) SETCCir(0x4,RD) +#define SETNEr(RD) SETCCir(0x5,RD) +#define SETNZr(RD) SETCCir(0x5,RD) +#define SETBEr(RD) SETCCir(0x6,RD) +#define SETNAr(RD) SETCCir(0x6,RD) +#define SETNBEr(RD) SETCCir(0x7,RD) +#define SETAr(RD) SETCCir(0x7,RD) +#define SETSr(RD) SETCCir(0x8,RD) +#define SETNSr(RD) SETCCir(0x9,RD) +#define SETPr(RD) SETCCir(0xa,RD) +#define SETPEr(RD) SETCCir(0xa,RD) +#define SETNPr(RD) SETCCir(0xb,RD) +#define SETPOr(RD) SETCCir(0xb,RD) +#define SETLr(RD) SETCCir(0xc,RD) +#define SETNGEr(RD) SETCCir(0xc,RD) +#define SETNLr(RD) SETCCir(0xd,RD) +#define SETGEr(RD) SETCCir(0xd,RD) +#define SETLEr(RD) SETCCir(0xe,RD) +#define SETNGr(RD) SETCCir(0xe,RD) +#define SETNLEr(RD) SETCCir(0xf,RD) +#define SETGr(RD) SETCCir(0xf,RD) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define SETCCim(CC,MD,MB,MI,MS) (_REXBrm(0, MB, MI), _OO_r_X (0x0f90|(CC) ,_b000 ,MD,MB,MI,MS )) +#define SETOm(D, B, I, S) SETCCim(0x0, D, B, I, S) +#define SETNOm(D, B, I, S) SETCCim(0x1, D, B, I, S) +#define SETBm(D, B, I, S) SETCCim(0x2, D, B, I, S) +#define SETNAEm(D, B, I, S) SETCCim(0x2, D, B, I, S) +#define SETNBm(D, B, I, S) SETCCim(0x3, D, B, I, S) +#define SETAEm(D, B, I, S) SETCCim(0x3, D, B, I, S) +#define SETEm(D, B, I, S) SETCCim(0x4, D, B, I, S) +#define SETZm(D, B, I, S) SETCCim(0x4, D, B, I, S) +#define SETNEm(D, B, I, S) SETCCim(0x5, D, B, I, S) +#define SETNZm(D, B, I, S) SETCCim(0x5, D, B, I, S) +#define SETBEm(D, B, I, S) SETCCim(0x6, D, B, I, S) +#define SETNAm(D, B, I, S) SETCCim(0x6, D, B, I, S) +#define SETNBEm(D, B, I, S) SETCCim(0x7, D, B, I, S) +#define SETAm(D, B, I, S) SETCCim(0x7, D, B, I, S) +#define SETSm(D, B, I, S) SETCCim(0x8, D, B, I, S) +#define SETNSm(D, B, I, S) SETCCim(0x9, D, B, I, S) +#define SETPm(D, B, I, S) SETCCim(0xa, D, B, I, S) +#define SETPEm(D, B, I, S) SETCCim(0xa, D, B, I, S) +#define SETNPm(D, B, I, S) SETCCim(0xb, D, B, I, S) +#define SETPOm(D, B, I, S) SETCCim(0xb, D, B, I, S) +#define SETLm(D, B, I, S) SETCCim(0xc, D, B, I, S) +#define SETNGEm(D, B, I, S) SETCCim(0xc, D, B, I, S) +#define SETNLm(D, B, I, S) SETCCim(0xd, D, B, I, S) +#define SETGEm(D, B, I, S) SETCCim(0xd, D, B, I, S) +#define SETLEm(D, B, I, S) SETCCim(0xe, D, B, I, S) +#define SETNGm(D, B, I, S) SETCCim(0xe, D, B, I, S) +#define SETNLEm(D, B, I, S) SETCCim(0xf, D, B, I, S) +#define SETGm(D, B, I, S) SETCCim(0xf, D, B, I, S) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define CMOVWrr(CC,RS,RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r2(RD),_r2(RS) )) +#define CMOVWmr(CC,MD,MB,MI,MS,RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r2(RD) ,MD,MB,MI,MS )) +#define CMOVLrr(CC,RS,RD) (_REXLrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r4(RD),_r4(RS) )) +#define CMOVLmr(CC,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r4(RD) ,MD,MB,MI,MS )) +#define CMOVQrr(CC,RS,RD) (_REXQrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r8(RD),_r8(RS) )) +#define CMOVQmr(CC,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r8(RD) ,MD,MB,MI,MS )) + + +/* --- Push/Pop instructions ----------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define POPWr(RD) _m32only((_d16(), _Or (0x58,_r2(RD) ))) +#define POPWm(MD, MB, MI, MS) _m32only((_d16(), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ))) + +#define POPLr(RD) _m32only( _Or (0x58,_r4(RD) )) +#define POPLm(MD, MB, MI, MS) _m32only( _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS )) + +#define POPQr(RD) _m64only((_REXQr(RD), _Or (0x58,_r8(RD) ))) +#define POPQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ))) + +#define PUSHWr(RS) _m32only((_d16(), _Or (0x50,_r2(RS) ))) +#define PUSHWm(MD, MB, MI, MS) _m32only((_d16(), _O_r_X (0xff, ,_b110 ,MD,MB,MI,MS ))) +#define PUSHWi(IM) _m32only((_d16(), _Os_sW (0x68 ,IM ))) + +#define PUSHLr(RS) _m32only( _Or (0x50,_r4(RS) )) +#define PUSHLm(MD, MB, MI, MS) _m32only( _O_r_X (0xff ,_b110 ,MD,MB,MI,MS )) +#define PUSHLi(IM) _m32only( _Os_sL (0x68 ,IM )) + +#define PUSHQr(RS) _m64only((_REXQr(RS), _Or (0x50,_r8(RS) ))) +#define PUSHQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0xff ,_b110 ,MD,MB,MI,MS ))) +#define PUSHQi(IM) _m64only( _Os_sL (0x68 ,IM )) + +#define POPA() (_d16(), _O (0x61 )) +#define POPAD() _O (0x61 ) + +#define PUSHA() (_d16(), _O (0x60 )) +#define PUSHAD() _O (0x60 ) + +#define POPF() _O (0x9d ) +#define PUSHF() _O (0x9c ) + + +/* --- Test instructions --------------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define TESTBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x84 ,_b11,_r1(RS),_r1(RD) )) +#define TESTBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x84 ,_r1(RS) ,MD,MB,MI,MS )) +#define TESTBir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AL) ? \ + (_REXBrr(0, RD), _O_B (0xa8 ,_u8(IM))) : \ + (_REXBrr(0, RD), _O_Mrm_B (0xf6 ,_b11,_b000 ,_r1(RD) ,_u8(IM))) ) +#define TESTBim(IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X_B (0xf6 ,_b000 ,MD,MB,MI,MS ,_u8(IM))) + +#define TESTWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x85 ,_b11,_r2(RS),_r2(RD) )) +#define TESTWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x85 ,_r2(RS) ,MD,MB,MI,MS )) +#define TESTWir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AX) ? \ + (_d16(), _REXLrr(0, RD), _O_W (0xa9 ,_u16(IM))) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm_W (0xf7 ,_b11,_b000 ,_r2(RD) ,_u16(IM))) ) +#define TESTWim(IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X_W (0xf7 ,_b000 ,MD,MB,MI,MS ,_u16(IM))) + +#define TESTLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x85 ,_b11,_r4(RS),_r4(RD) )) +#define TESTLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x85 ,_r4(RS) ,MD,MB,MI,MS )) +#define TESTLir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_EAX) ? \ + (_REXLrr(0, RD), _O_L (0xa9 ,IM )) : \ + (_REXLrr(0, RD), _O_Mrm_L (0xf7 ,_b11,_b000 ,_r4(RD) ,IM )) ) +#define TESTLim(IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM )) + +#define TESTQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x85 ,_b11,_r8(RS),_r8(RD) )) +#define TESTQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x85 ,_r8(RS) ,MD,MB,MI,MS )) +#define TESTQir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_RAX) ? \ + (_REXQrr(0, RD), _O_L (0xa9 ,IM )) : \ + (_REXQrr(0, RD), _O_Mrm_L (0xf7 ,_b11,_b000 ,_r8(RD) ,IM )) ) +#define TESTQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM )) + + +/* --- Exchange instructions ----------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define CMPXCHGBrr(RS, RD) (_REXBrr(RS, RD), _OO_Mrm (0x0fb0 ,_b11,_r1(RS),_r1(RD) )) +#define CMPXCHGBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _OO_r_X (0x0fb0 ,_r1(RS) ,MD,MB,MI,MS )) + +#define CMPXCHGWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r2(RS),_r2(RD) )) +#define CMPXCHGWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r2(RS) ,MD,MB,MI,MS )) + +#define CMPXCHGLrr(RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r4(RS),_r4(RD) )) +#define CMPXCHGLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r4(RS) ,MD,MB,MI,MS )) + +#define CMPXCHGQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r8(RS),_r8(RD) )) +#define CMPXCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r8(RS) ,MD,MB,MI,MS )) + +#define XADDBrr(RS, RD) (_REXBrr(RS, RD), _OO_Mrm (0x0fc0 ,_b11,_r1(RS),_r1(RD) )) +#define XADDBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _OO_r_X (0x0fc0 ,_r1(RS) ,MD,MB,MI,MS )) + +#define XADDWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r2(RS),_r2(RD) )) +#define XADDWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r2(RS) ,MD,MB,MI,MS )) + +#define XADDLrr(RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r4(RS),_r4(RD) )) +#define XADDLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r4(RS) ,MD,MB,MI,MS )) + +#define XADDQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r8(RS),_r8(RD) )) +#define XADDQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r8(RS) ,MD,MB,MI,MS )) + +#define XCHGBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x86 ,_b11,_r1(RS),_r1(RD) )) +#define XCHGBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x86 ,_r1(RS) ,MD,MB,MI,MS )) + +#define XCHGWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x87 ,_b11,_r2(RS),_r2(RD) )) +#define XCHGWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x87 ,_r2(RS) ,MD,MB,MI,MS )) + +#define XCHGLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x87 ,_b11,_r4(RS),_r4(RD) )) +#define XCHGLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x87 ,_r4(RS) ,MD,MB,MI,MS )) + +#define XCHGQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x87 ,_b11,_r8(RS),_r8(RD) )) +#define XCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x87 ,_r8(RS) ,MD,MB,MI,MS )) + + +/* --- Increment/Decrement instructions ------------------------------------ */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define DECBm(MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xfe ,_b001 ,MD,MB,MI,MS )) +#define DECBr(RD) (_REXBrr(0, RD), _O_Mrm (0xfe ,_b11,_b001 ,_r1(RD) )) + +#define DECWm(MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) +#define DECWr(RD) (! X86_TARGET_64BIT ? (_d16(), _Or (0x48,_r2(RD) )) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r2(RD) ))) + +#define DECLm(MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) +#define DECLr(RD) (! X86_TARGET_64BIT ? _Or (0x48,_r4(RD) ) : \ + (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r4(RD) ))) + +#define DECQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) +#define DECQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r8(RD) )) + +#define INCBm(MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xfe ,_b000 ,MD,MB,MI,MS )) +#define INCBr(RD) (_REXBrr(0, RD), _O_Mrm (0xfe ,_b11,_b000 ,_r1(RD) )) + +#define INCWm(MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) +#define INCWr(RD) (! X86_TARGET_64BIT ? (_d16(), _Or (0x40,_r2(RD) )) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r2(RD) )) ) + +#define INCLm(MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) +#define INCLr(RD) (! X86_TARGET_64BIT ? _Or (0x40,_r4(RD) ) : \ + (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r4(RD) ))) + +#define INCQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) +#define INCQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r8(RD) )) + + +/* --- Misc instructions --------------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define BSFWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r2(RD),_r2(RS) )) +#define BSFWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r2(RD) ,MD,MB,MI,MS )) +#define BSRWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r2(RD),_r2(RS) )) +#define BSRWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r2(RD) ,MD,MB,MI,MS )) + +#define BSFLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r4(RD),_r4(RS) )) +#define BSFLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r4(RD) ,MD,MB,MI,MS )) +#define BSRLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r4(RD),_r4(RS) )) +#define BSRLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r4(RD) ,MD,MB,MI,MS )) + +#define BSFQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r8(RD),_r8(RS) )) +#define BSFQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r8(RD) ,MD,MB,MI,MS )) +#define BSRQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r8(RD),_r8(RS) )) +#define BSRQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r8(RD) ,MD,MB,MI,MS )) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define MOVSBWrr(RS, RD) (_d16(), _REXBLrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r2(RD),_r1(RS) )) +#define MOVSBWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r2(RD) ,MD,MB,MI,MS )) +#define MOVZBWrr(RS, RD) (_d16(), _REXBLrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r2(RD),_r1(RS) )) +#define MOVZBWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r2(RD) ,MD,MB,MI,MS )) + +#define MOVSBLrr(RS, RD) (_REXBLrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r4(RD),_r1(RS) )) +#define MOVSBLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r4(RD) ,MD,MB,MI,MS )) +#define MOVZBLrr(RS, RD) (_REXBLrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r4(RD),_r1(RS) )) +#define MOVZBLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r4(RD) ,MD,MB,MI,MS )) + +#define MOVSBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r8(RD),_r1(RS) )) +#define MOVSBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r8(RD) ,MD,MB,MI,MS )) +#define MOVZBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r8(RD),_r1(RS) )) +#define MOVZBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r8(RD) ,MD,MB,MI,MS )) + +#define MOVSWLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r4(RD),_r2(RS) )) +#define MOVSWLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r4(RD) ,MD,MB,MI,MS )) +#define MOVZWLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r4(RD),_r2(RS) )) +#define MOVZWLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r4(RD) ,MD,MB,MI,MS )) + +#define MOVSWQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r8(RD),_r2(RS) )) +#define MOVSWQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r8(RD) ,MD,MB,MI,MS )) +#define MOVZWQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r8(RD),_r2(RS) )) +#define MOVZWQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r8(RD) ,MD,MB,MI,MS )) + +#define MOVSLQrr(RS, RD) _m64only((_REXQrr(RD, RS), _O_Mrm (0x63 ,_b11,_r8(RD),_r4(RS) ))) +#define MOVSLQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _O_r_X (0x63 ,_r8(RD) ,MD,MB,MI,MS ))) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define LEALmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS )) + +#define BSWAPLr(R) (_REXLrr(0, R), _OOr (0x0fc8,_r4(R) )) +#define BSWAPQr(R) (_REXQrr(0, R), _OOr (0x0fc8,_r8(R) )) + +#define CLC() _O (0xf8 ) +#define STC() _O (0xf9 ) + +#define CMC() _O (0xf5 ) +#define CLD() _O (0xfc ) +#define STD() _O (0xfd ) + +#define CBTW() (_d16(), _O (0x98 )) +#define CWTL() _O (0x98 ) +#define CLTQ() _m64only(_REXQrr(0, 0), _O (0x98 )) + +#define CBW CBTW +#define CWDE CWTL +#define CDQE CLTQ + +#define CWTD() (_d16(), _O (0x99 )) +#define CLTD() _O (0x99 ) +#define CQTO() _m64only(_REXQrr(0, 0), _O (0x99 )) + +#define CWD CWTD +#define CDQ CLTD +#define CQO CQTO + +#define LAHF() _O (0x9f ) +#define SAHF() _O (0x9e ) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define CPUID() _OO (0x0fa2 ) +#define RDTSC() _OO (0xff31 ) + +#define ENTERii(W, B) _O_W_B (0xc8 ,_su16(W),_su8(B)) + +#define LEAVE() _O (0xc9 ) +#define RET() _O (0xc3 ) +#define RETi(IM) _O_W (0xc2 ,_su16(IM)) + +#define NOP() _O (0x90 ) + + +/* --- Media 128-bit instructions ------------------------------------------ */ + +enum { + X86_SSE_CVTIS = 0x2a, + X86_SSE_CVTSI = 0x2d, + X86_SSE_UCOMI = 0x2e, + X86_SSE_COMI = 0x2f, + X86_SSE_SQRT = 0x51, + X86_SSE_RSQRT = 0x52, + X86_SSE_RCP = 0x53, + X86_SSE_AND = 0x54, + X86_SSE_ANDN = 0x55, + X86_SSE_OR = 0x56, + X86_SSE_XOR = 0x57, + X86_SSE_ADD = 0x58, + X86_SSE_MUL = 0x59, + X86_SSE_CVTSD = 0x5a, + X86_SSE_CVTDT = 0x5b, + X86_SSE_SUB = 0x5c, + X86_SSE_MIN = 0x5d, + X86_SSE_DIV = 0x5e, + X86_SSE_MAX = 0x5f, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define __SSELrr(OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __SSELmr(OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __SSELrm(OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) + +#define __SSEQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __SSEQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __SSEQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) + +#define _SSELrr(PX,OP,RS,RSA,RD,RDA) (_B(PX), __SSELrr(OP, RS, RSA, RD, RDA)) +#define _SSELmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_B(PX), __SSELmr(OP, MD, MB, MI, MS, RD, RDA)) +#define _SSELrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_B(PX), __SSELrm(OP, RS, RSA, MD, MB, MI, MS)) + +#define _SSEQrr(PX,OP,RS,RSA,RD,RDA) (_B(PX), __SSEQrr(OP, RS, RSA, RD, RDA)) +#define _SSEQmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_B(PX), __SSEQmr(OP, MD, MB, MI, MS, RD, RDA)) +#define _SSEQrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_B(PX), __SSEQrm(OP, RS, RSA, MD, MB, MI, MS)) + +#define _SSEPSrr(OP,RS,RD) __SSELrr( OP, RS,_rX, RD,_rX) +#define _SSEPSmr(OP,MD,MB,MI,MS,RD) __SSELmr( OP, MD, MB, MI, MS, RD,_rX) +#define _SSEPSrm(OP,RS,MD,MB,MI,MS) __SSELrm( OP, RS,_rX, MD, MB, MI, MS) + +#define _SSEPDrr(OP,RS,RD) _SSELrr(0x66, OP, RS,_rX, RD,_rX) +#define _SSEPDmr(OP,MD,MB,MI,MS,RD) _SSELmr(0x66, OP, MD, MB, MI, MS, RD,_rX) +#define _SSEPDrm(OP,RS,MD,MB,MI,MS) _SSELrm(0x66, OP, RS,_rX, MD, MB, MI, MS) + +#define _SSESSrr(OP,RS,RD) _SSELrr(0xf3, OP, RS,_rX, RD,_rX) +#define _SSESSmr(OP,MD,MB,MI,MS,RD) _SSELmr(0xf3, OP, MD, MB, MI, MS, RD,_rX) +#define _SSESSrm(OP,RS,MD,MB,MI,MS) _SSELrm(0xf3, OP, RS,_rX, MD, MB, MI, MS) + +#define _SSESDrr(OP,RS,RD) _SSELrr(0xf2, OP, RS,_rX, RD,_rX) +#define _SSESDmr(OP,MD,MB,MI,MS,RD) _SSELmr(0xf2, OP, MD, MB, MI, MS, RD,_rX) +#define _SSESDrm(OP,RS,MD,MB,MI,MS) _SSELrm(0xf2, OP, RS,_rX, MD, MB, MI, MS) + +#define ADDPSrr(RS, RD) _SSEPSrr(X86_SSE_ADD, RS, RD) +#define ADDPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_ADD, MD, MB, MI, MS, RD) +#define ADDPDrr(RS, RD) _SSEPDrr(X86_SSE_ADD, RS, RD) +#define ADDPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_ADD, MD, MB, MI, MS, RD) + +#define ADDSSrr(RS, RD) _SSESSrr(X86_SSE_ADD, RS, RD) +#define ADDSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_ADD, MD, MB, MI, MS, RD) +#define ADDSDrr(RS, RD) _SSESDrr(X86_SSE_ADD, RS, RD) +#define ADDSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_ADD, MD, MB, MI, MS, RD) + +#define ANDNPSrr(RS, RD) _SSEPSrr(X86_SSE_ANDN, RS, RD) +#define ANDNPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_ANDN, MD, MB, MI, MS, RD) +#define ANDNPDrr(RS, RD) _SSEPDrr(X86_SSE_ANDN, RS, RD) +#define ANDNPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_ANDN, MD, MB, MI, MS, RD) + +#define ANDPSrr(RS, RD) _SSEPSrr(X86_SSE_AND, RS, RD) +#define ANDPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_AND, MD, MB, MI, MS, RD) +#define ANDPDrr(RS, RD) _SSEPDrr(X86_SSE_AND, RS, RD) +#define ANDPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_AND, MD, MB, MI, MS, RD) + +#define DIVPSrr(RS, RD) _SSEPSrr(X86_SSE_DIV, RS, RD) +#define DIVPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_DIV, MD, MB, MI, MS, RD) +#define DIVPDrr(RS, RD) _SSEPDrr(X86_SSE_DIV, RS, RD) +#define DIVPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_DIV, MD, MB, MI, MS, RD) + +#define DIVSSrr(RS, RD) _SSESSrr(X86_SSE_DIV, RS, RD) +#define DIVSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_DIV, MD, MB, MI, MS, RD) +#define DIVSDrr(RS, RD) _SSESDrr(X86_SSE_DIV, RS, RD) +#define DIVSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_DIV, MD, MB, MI, MS, RD) + +#define MAXPSrr(RS, RD) _SSEPSrr(X86_SSE_MAX, RS, RD) +#define MAXPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MAX, MD, MB, MI, MS, RD) +#define MAXPDrr(RS, RD) _SSEPDrr(X86_SSE_MAX, RS, RD) +#define MAXPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MAX, MD, MB, MI, MS, RD) + +#define MAXSSrr(RS, RD) _SSESSrr(X86_SSE_MAX, RS, RD) +#define MAXSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MAX, MD, MB, MI, MS, RD) +#define MAXSDrr(RS, RD) _SSESDrr(X86_SSE_MAX, RS, RD) +#define MAXSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MAX, MD, MB, MI, MS, RD) + +#define MINPSrr(RS, RD) _SSEPSrr(X86_SSE_MIN, RS, RD) +#define MINPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MIN, MD, MB, MI, MS, RD) +#define MINPDrr(RS, RD) _SSEPDrr(X86_SSE_MIN, RS, RD) +#define MINPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MIN, MD, MB, MI, MS, RD) + +#define MINSSrr(RS, RD) _SSESSrr(X86_SSE_MIN, RS, RD) +#define MINSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MIN, MD, MB, MI, MS, RD) +#define MINSDrr(RS, RD) _SSESDrr(X86_SSE_MIN, RS, RD) +#define MINSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MIN, MD, MB, MI, MS, RD) + +#define MULPSrr(RS, RD) _SSEPSrr(X86_SSE_MUL, RS, RD) +#define MULPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MUL, MD, MB, MI, MS, RD) +#define MULPDrr(RS, RD) _SSEPDrr(X86_SSE_MUL, RS, RD) +#define MULPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MUL, MD, MB, MI, MS, RD) + +#define MULSSrr(RS, RD) _SSESSrr(X86_SSE_MUL, RS, RD) +#define MULSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MUL, MD, MB, MI, MS, RD) +#define MULSDrr(RS, RD) _SSESDrr(X86_SSE_MUL, RS, RD) +#define MULSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MUL, MD, MB, MI, MS, RD) + +#define ORPSrr(RS, RD) _SSEPSrr(X86_SSE_OR, RS, RD) +#define ORPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_OR, MD, MB, MI, MS, RD) +#define ORPDrr(RS, RD) _SSEPDrr(X86_SSE_OR, RS, RD) +#define ORPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_OR, MD, MB, MI, MS, RD) + +#define RCPPSrr(RS, RD) _SSEPSrr(X86_SSE_RCP, RS, RD) +#define RCPPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_RCP, MD, MB, MI, MS, RD) +#define RCPSSrr(RS, RD) _SSESSrr(X86_SSE_RCP, RS, RD) +#define RCPSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_RCP, MD, MB, MI, MS, RD) + +#define RSQRTPSrr(RS, RD) _SSEPSrr(X86_SSE_RSQRT, RS, RD) +#define RSQRTPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_RSQRT, MD, MB, MI, MS, RD) +#define RSQRTSSrr(RS, RD) _SSESSrr(X86_SSE_RSQRT, RS, RD) +#define RSQRTSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_RSQRT, MD, MB, MI, MS, RD) + +#define SQRTPSrr(RS, RD) _SSEPSrr(X86_SSE_SQRT, RS, RD) +#define SQRTPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) +#define SQRTPDrr(RS, RD) _SSEPDrr(X86_SSE_SQRT, RS, RD) +#define SQRTPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) + +#define SQRTSSrr(RS, RD) _SSESSrr(X86_SSE_SQRT, RS, RD) +#define SQRTSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) +#define SQRTSDrr(RS, RD) _SSESDrr(X86_SSE_SQRT, RS, RD) +#define SQRTSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) + +#define SUBPSrr(RS, RD) _SSEPSrr(X86_SSE_SUB, RS, RD) +#define SUBPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_SUB, MD, MB, MI, MS, RD) +#define SUBPDrr(RS, RD) _SSEPDrr(X86_SSE_SUB, RS, RD) +#define SUBPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_SUB, MD, MB, MI, MS, RD) + +#define SUBSSrr(RS, RD) _SSESSrr(X86_SSE_SUB, RS, RD) +#define SUBSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_SUB, MD, MB, MI, MS, RD) +#define SUBSDrr(RS, RD) _SSESDrr(X86_SSE_SUB, RS, RD) +#define SUBSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_SUB, MD, MB, MI, MS, RD) + +#define XORPSrr(RS, RD) _SSEPSrr(X86_SSE_XOR, RS, RD) +#define XORPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_XOR, MD, MB, MI, MS, RD) +#define XORPDrr(RS, RD) _SSEPDrr(X86_SSE_XOR, RS, RD) +#define XORPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_XOR, MD, MB, MI, MS, RD) + +#define COMISSrr(RS, RD) _SSESSrr(X86_SSE_COMI, RS, RD) +#define COMISSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_COMI, MD, MB, MI, MS, RD) +#define COMISDrr(RS, RD) _SSESDrr(X86_SSE_COMI, RS, RD) +#define COMISDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_COMI, MD, MB, MI, MS, RD) + +#define UCOMISSrr(RS, RD) _SSESSrr(X86_SSE_UCOMI, RS, RD) +#define UCOMISSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_UCOMI, MD, MB, MI, MS, RD) +#define UCOMISDrr(RS, RD) _SSESDrr(X86_SSE_UCOMI, RS, RD) +#define UCOMISDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_UCOMI, MD, MB, MI, MS, RD) + +#define MOVAPSrr(RS, RD) _SSEPSrr(0x28, RS, RD) +#define MOVAPSmr(MD, MB, MI, MS, RD) _SSEPSmr(0x28, MD, MB, MI, MS, RD) +#define MOVAPSrm(RS, MD, MB, MI, MS) _SSEPSrm(0x29, RS, MD, MB, MI, MS) + +#define MOVAPDrr(RS, RD) _SSEPDrr(0x28, RS, RD) +#define MOVAPDmr(MD, MB, MI, MS, RD) _SSEPDmr(0x28, MD, MB, MI, MS, RD) +#define MOVAPDrm(RS, MD, MB, MI, MS) _SSEPDrm(0x29, RS, MD, MB, MI, MS) + +#define CVTPS2PIrr(RS, RD) __SSELrr( X86_SSE_CVTSI, RS,_rX, RD,_rM) +#define CVTPS2PImr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTSI, MD, MB, MI, MS, RD,_rM) +#define CVTPD2PIrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTSI, RS,_rX, RD,_rM) +#define CVTPD2PImr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_rM) + +#define CVTPI2PSrr(RS, RD) __SSELrr( X86_SSE_CVTIS, RS,_rM, RD,_rX) +#define CVTPI2PSmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX) +#define CVTPI2PDrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTIS, RS,_rM, RD,_rX) +#define CVTPI2PDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX) + +#define CVTPS2PDrr(RS, RD) __SSELrr( X86_SSE_CVTSD, RS,_rX, RD,_rX) +#define CVTPS2PDmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTSD, MD, MB, MI, MS, RD,_rX) +#define CVTPD2PSrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTSD, RS,_rX, RD,_rX) +#define CVTPD2PSmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTSD, MD, MB, MI, MS, RD,_rX) + +#define CVTSS2SDrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSD, RS,_rX, RD,_rX) +#define CVTSS2SDmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSD, MD, MB, MI, MS, RD,_rX) +#define CVTSD2SSrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSD, RS,_rX, RD,_rX) +#define CVTSD2SSmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSD, MD, MB, MI, MS, RD,_rX) + +#define CVTSS2SILrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSI, RS,_rX, RD,_r4) +#define CVTSS2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r4) +#define CVTSD2SILrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSI, RS,_rX, RD,_r4) +#define CVTSD2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r4) + +#define CVTSI2SSLrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTIS, RS,_r4, RD,_rX) +#define CVTSI2SSLmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX) +#define CVTSI2SDLrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTIS, RS,_r4, RD,_rX) +#define CVTSI2SDLmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX) + +#define CVTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSI, RS,_rX, RD,_r8) +#define CVTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r8) +#define CVTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSI, RS,_rX, RD,_r8) +#define CVTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r8) + +#define CVTSI2SSQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTIS, RS,_r8, RD,_rX) +#define CVTSI2SSQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX) +#define CVTSI2SDQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTIS, RS,_r8, RD,_rX) +#define CVTSI2SDQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX) + +#define MOVDLXrr(RS, RD) _SSELrr(0x66, 0x6e, RS,_r4, RD,_rX) +#define MOVDLXmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX) +#define MOVDQXrr(RS, RD) _SSEQrr(0x66, 0x6e, RS,_r8, RD,_rX) +#define MOVDQXmr(MD, MB, MI, MS, RD) _SSEQmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX) + +#define MOVDXLrr(RS, RD) _SSELrr(0x66, 0x7e, RS,_rX, RD,_r4) +#define MOVDXLrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS) +#define MOVDXQrr(RS, RD) _SSEQrr(0x66, 0x7e, RS,_rX, RD,_r8) +#define MOVDXQrm(RS, MD, MB, MI, MS) _SSEQrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS) + +#define MOVDLMrr(RS, RD) __SSELrr( 0x6e, RS,_r4, RD,_rM) +#define MOVDLMmr(MD, MB, MI, MS, RD) __SSELmr( 0x6e, MD, MB, MI, MS, RD,_rM) +#define MOVDQMrr(RS, RD) __SSEQrr( 0x6e, RS,_r8, RD,_rM) +#define MOVDQMmr(MD, MB, MI, MS, RD) __SSEQmr( 0x6e, MD, MB, MI, MS, RD,_rM) + +#define MOVDMLrr(RS, RD) __SSELrr( 0x7e, RS,_rM, RD,_r4) +#define MOVDMLrm(RS, MD, MB, MI, MS) __SSELrm( 0x7e, RS,_rM, MD, MB, MI, MS) +#define MOVDMQrr(RS, RD) __SSEQrr( 0x7e, RS,_rM, RD,_r8) +#define MOVDMQrm(RS, MD, MB, MI, MS) __SSEQrm( 0x7e, RS,_rM, MD, MB, MI, MS) + +#define MOVDQ2Qrr(RS, RD) _SSELrr(0xf2, 0xd6, RS,_rX, RD,_rM) +#define MOVHLPSrr(RS, RD) __SSELrr( 0x12, RS,_rX, RD,_rX) +#define MOVLHPSrr(RS, RD) __SSELrr( 0x16, RS,_rX, RD,_rX) + +#define MOVDQArr(RS, RD) _SSELrr(0x66, 0x6f, RS,_rX, RD,_rX) +#define MOVDQAmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x6f, MD, MB, MI, MS, RD,_rX) +#define MOVDQArm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x7f, RS,_rX, MD, MB, MI, MS) + +#define MOVDQUrr(RS, RD) _SSELrr(0xf3, 0x6f, RS,_rX, RD,_rX) +#define MOVDQUmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, 0x6f, MD, MB, MI, MS, RD,_rX) +#define MOVDQUrm(RS, MD, MB, MI, MS) _SSELrm(0xf3, 0x7f, RS,_rX, MD, MB, MI, MS) + +#define MOVHPDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x16, MD, MB, MI, MS, RD,_rX) +#define MOVHPDrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x17, RS,_rX, MD, MB, MI, MS) +#define MOVHPSmr(MD, MB, MI, MS, RD) __SSELmr( 0x16, MD, MB, MI, MS, RD,_rX) +#define MOVHPSrm(RS, MD, MB, MI, MS) __SSELrm( 0x17, RS,_rX, MD, MB, MI, MS) + +#define MOVLPDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x12, MD, MB, MI, MS, RD,_rX) +#define MOVLPDrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x13, RS,_rX, MD, MB, MI, MS) +#define MOVLPSmr(MD, MB, MI, MS, RD) __SSELmr( 0x12, MD, MB, MI, MS, RD,_rX) +#define MOVLPSrm(RS, MD, MB, MI, MS) __SSELrm( 0x13, RS,_rX, MD, MB, MI, MS) + + +/* --- FLoating-Point instructions ----------------------------------------- */ + +#define _ESCmi(D,B,I,S,OP) (_REXLrm(0,B,I), _O_r_X(0xd8|(OP & 7), (OP >> 3), D,B,I,S)) + +#define FLDr(R) _OOr(0xd9c0,_rN(R)) +#define FLDLm(D,B,I,S) _ESCmi(D,B,I,S,005) +#define FLDSm(D,B,I,S) _ESCmi(D,B,I,S,001) +#define FLDTm(D,B,I,S) _ESCmi(D,B,I,S,053) + +#define FSTr(R) _OOr(0xddd0,_rN(R)) +#define FSTSm(D,B,I,S) _ESCmi(D,B,I,S,021) +#define FSTLm(D,B,I,S) _ESCmi(D,B,I,S,025) + +#define FSTPr(R) _OOr(0xddd8,_rN(R)) +#define FSTPSm(D,B,I,S) _ESCmi(D,B,I,S,031) +#define FSTPLm(D,B,I,S) _ESCmi(D,B,I,S,035) +#define FSTPTm(D,B,I,S) _ESCmi(D,B,I,S,073) + +#define FADDr0(R) _OOr(0xd8c0,_rN(R)) +#define FADD0r(R) _OOr(0xdcc0,_rN(R)) +#define FADDP0r(R) _OOr(0xdec0,_rN(R)) +#define FADDSm(D,B,I,S) _ESCmi(D,B,I,S,000) +#define FADDLm(D,B,I,S) _ESCmi(D,B,I,S,004) + +#define FSUBSm(D,B,I,S) _ESCmi(D,B,I,S,040) +#define FSUBLm(D,B,I,S) _ESCmi(D,B,I,S,044) +#define FSUBr0(R) _OOr(0xd8e0,_rN(R)) +#define FSUB0r(R) _OOr(0xdce8,_rN(R)) +#define FSUBP0r(R) _OOr(0xdee8,_rN(R)) + +#define FSUBRr0(R) _OOr(0xd8e8,_rN(R)) +#define FSUBR0r(R) _OOr(0xdce0,_rN(R)) +#define FSUBRP0r(R) _OOr(0xdee0,_rN(R)) +#define FSUBRSm(D,B,I,S) _ESCmi(D,B,I,S,050) +#define FSUBRLm(D,B,I,S) _ESCmi(D,B,I,S,054) + +#define FMULr0(R) _OOr(0xd8c8,_rN(R)) +#define FMUL0r(R) _OOr(0xdcc8,_rN(R)) +#define FMULP0r(R) _OOr(0xdec8,_rN(R)) +#define FMULSm(D,B,I,S) _ESCmi(D,B,I,S,010) +#define FMULLm(D,B,I,S) _ESCmi(D,B,I,S,014) + +#define FDIVr0(R) _OOr(0xd8f0,_rN(R)) +#define FDIV0r(R) _OOr(0xdcf8,_rN(R)) +#define FDIVP0r(R) _OOr(0xdef8,_rN(R)) +#define FDIVSm(D,B,I,S) _ESCmi(D,B,I,S,060) +#define FDIVLm(D,B,I,S) _ESCmi(D,B,I,S,064) + +#define FDIVRr0(R) _OOr(0xd8f8,_rN(R)) +#define FDIVR0r(R) _OOr(0xdcf0,_rN(R)) +#define FDIVRP0r(R) _OOr(0xdef0,_rN(R)) +#define FDIVRSm(D,B,I,S) _ESCmi(D,B,I,S,070) +#define FDIVRLm(D,B,I,S) _ESCmi(D,B,I,S,074) + +#define FCMOVBr0(R) _OOr(0xdac0,_rN(R)) +#define FCMOVBEr0(R) _OOr(0xdad0,_rN(R)) +#define FCMOVEr0(R) _OOr(0xdac8,_rN(R)) +#define FCMOVNBr0(R) _OOr(0xdbc0,_rN(R)) +#define FCMOVNBEr0(R) _OOr(0xdbd0,_rN(R)) +#define FCMOVNEr0(R) _OOr(0xdbc8,_rN(R)) +#define FCMOVNUr0(R) _OOr(0xdbd8,_rN(R)) +#define FCMOVUr0(R) _OOr(0xdad8,_rN(R)) +#define FCOMIr0(R) _OOr(0xdbf0,_rN(R)) +#define FCOMIPr0(R) _OOr(0xdff0,_rN(R)) + +#define FCOMr(R) _OOr(0xd8d0,_rN(R)) +#define FCOMSm(D,B,I,S) _ESCmi(D,B,I,S,020) +#define FCOMLm(D,B,I,S) _ESCmi(D,B,I,S,024) + +#define FCOMPr(R) _OOr(0xd8d8,_rN(R)) +#define FCOMPSm(D,B,I,S) _ESCmi(D,B,I,S,030) +#define FCOMPLm(D,B,I,S) _ESCmi(D,B,I,S,034) + +#define FUCOMIr0(R) _OOr(0xdbe8,_rN(R)) +#define FUCOMIPr0(R) _OOr(0xdfe8,_rN(R)) +#define FUCOMPr(R) _OOr(0xdde8,_rN(R)) +#define FUCOMr(R) _OOr(0xdde0,_rN(R)) + +#define FIADDLm(D,B,I,S) _ESCmi(D,B,I,S,002) +#define FICOMLm(D,B,I,S) _ESCmi(D,B,I,S,022) +#define FICOMPLm(D,B,I,S) _ESCmi(D,B,I,S,032) +#define FIDIVLm(D,B,I,S) _ESCmi(D,B,I,S,062) +#define FIDIVRLm(D,B,I,S) _ESCmi(D,B,I,S,072) +#define FILDLm(D,B,I,S) _ESCmi(D,B,I,S,003) +#define FILDQm(D,B,I,S) _ESCmi(D,B,I,S,057) +#define FIMULLm(D,B,I,S) _ESCmi(D,B,I,S,012) +#define FISTLm(D,B,I,S) _ESCmi(D,B,I,S,023) +#define FISTPLm(D,B,I,S) _ESCmi(D,B,I,S,033) +#define FISTPQm(D,B,I,S) _ESCmi(D,B,I,S,077) +#define FISUBLm(D,B,I,S) _ESCmi(D,B,I,S,042) +#define FISUBRLm(D,B,I,S) _ESCmi(D,B,I,S,052) + +#define FREEr(R) _OOr(0xddc0,_rN(R)) +#define FXCHr(R) _OOr(0xd9c8,_rN(R)) + +#endif /* X86_RTASM_H */ diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu.h b/BasiliskII/src/uae_cpu_2021/compiler/compemu.h new file mode 100644 index 000000000..62ee94e44 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu.h @@ -0,0 +1,606 @@ +/* + * compiler/compemu.h - Public interface and definitions + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef COMPEMU_H +#define COMPEMU_H + +// #include "sysconfig.h" +#include "newcpu.h" + +#ifdef UAE +#ifdef CPU_64_BIT +typedef uae_u64 uintptr; +#else +typedef uae_u32 uintptr; +#endif +/* FIXME: cpummu.cpp also checks for USE_JIT, possibly others */ +#define USE_JIT +#endif + +#ifdef USE_JIT + +#ifdef JIT_DEBUG +/* dump some information (m68k block, x86 block addresses) about the compiler state */ +extern void compiler_dumpstate(void); +#endif + +/* Now that we do block chaining, and also have linked lists on each tag, + TAGMASK can be much smaller and still do its job. Saves several megs + of memory! */ +#define TAGMASK 0x0000ffff +#define TAGSIZE (TAGMASK+1) +#define MAXRUN 1024 +#define cacheline(x) (((uintptr)x)&TAGMASK) + +extern uae_u8* start_pc_p; +extern uae_u32 start_pc; + +struct blockinfo_t; + +struct cpu_history { + uae_u16* location; +#ifdef UAE + uae_u8 specmem; +#endif +}; + +union cacheline { + cpuop_func* handler; + blockinfo_t * bi; +}; + +/* Use new spill/reload strategy when calling external functions */ +#define USE_OPTIMIZED_CALLS 0 +#if USE_OPTIMIZED_CALLS +#error implementation in progress +#endif + +/* (gb) When on, this option can save save up to 30% compilation time + * when many lazy flushes occur (e.g. apps in MacOS 8.x). + */ +#define USE_SEPARATE_BIA 1 + +/* Use chain of checksum_info_t to compute the block checksum */ +#define USE_CHECKSUM_INFO 1 + +/* Use code inlining, aka follow-up of constant jumps */ +#define USE_INLINING 1 + +/* Inlining requires the chained checksuming information */ +#if USE_INLINING +#undef USE_CHECKSUM_INFO +#define USE_CHECKSUM_INFO 1 +#endif + +/* Does flush_icache_range() only check for blocks falling in the requested range? */ +#define LAZY_FLUSH_ICACHE_RANGE 0 + +#define USE_F_ALIAS 1 +#define USE_OFFSET 1 +#define COMP_DEBUG 1 + +#if COMP_DEBUG +#define Dif(x) if (x) +#else +#define Dif(x) if (0) +#endif + +#define SCALE 2 + +#define BYTES_PER_INST 10240 /* paranoid ;-) */ +#if defined(CPU_arm) +#define LONGEST_68K_INST 256 /* The number of bytes the longest possible + 68k instruction takes */ +#else +#define LONGEST_68K_INST 16 /* The number of bytes the longest possible + 68k instruction takes */ +#endif +#define MAX_CHECKSUM_LEN 2048 /* The maximum size we calculate checksums + for. Anything larger will be flushed + unconditionally even with SOFT_FLUSH */ +#define MAX_HOLD_BI 3 /* One for the current block, and up to two + for jump targets */ + +#define INDIVIDUAL_INST 0 +#ifdef WINUAE_ARANYM +#define FLAG_X 0x0010 +#define FLAG_N 0x0008 +#define FLAG_Z 0x0004 +#define FLAG_V 0x0002 +#define FLAG_C 0x0001 +#else +#define FLAG_C 0x0010 +#define FLAG_V 0x0008 +#define FLAG_Z 0x0004 +#define FLAG_N 0x0002 +#define FLAG_X 0x0001 +#endif +#define FLAG_CZNV (FLAG_C | FLAG_Z | FLAG_N | FLAG_V) +#define FLAG_ALL (FLAG_C | FLAG_Z | FLAG_N | FLAG_V | FLAG_X) +#define FLAG_ZNV (FLAG_Z | FLAG_N | FLAG_V) + +#define KILLTHERAT 1 /* Set to 1 to avoid some partial_rat_stalls */ + +#if defined(CPU_arm) +#define USE_DATA_BUFFER +#define N_REGS 13 /* really 16, but 13 to 15 are SP, LR, PC */ +#else +#if defined(CPU_x86_64) +#define N_REGS 16 /* really only 15, but they are numbered 0-3,5-15 */ +#else +#define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */ +#endif +#endif +#define N_FREGS 6 /* That leaves us two positions on the stack to play with */ + +/* 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_exit(void); +extern bool compiler_use_jit(void); +#endif +extern void flush(int save_regs); +void flush_reg(int reg); +extern void set_target(uae_u8* t); +extern uae_u8* get_target(void); +#ifdef UAE +extern void build_comp(void); +#endif +extern void set_cache_state(int enabled); +extern int get_cache_state(void); +extern uae_u32 get_jitted_size(void); +#ifdef JIT +extern void (*flush_icache)(void); +#endif +extern void alloc_cache(void); +extern int check_for_cache_miss(void); + +/* JIT FPU compilation */ +struct jit_disable_opcodes { + bool fbcc; + bool fdbcc; + bool fscc; + bool ftrapcc; + bool fsave; + bool frestore; + bool fmove; + bool fmovem; + bool fmovec; /* for move control register */ + bool fmovecr; /* for move from constant rom */ + bool fint; + bool fsinh; + bool fintrz; + bool fsqrt; + bool flognp1; + bool fetoxm1; + bool ftanh; + bool fatan; + bool fasin; + bool fatanh; + bool fsin; + bool ftan; + bool fetox; + bool ftwotox; + bool ftentox; + bool flogn; + bool flog10; + bool flog2; + bool fabs; + bool fcosh; + bool fneg; + bool facos; + bool fcos; + bool fgetexp; + bool fgetman; + bool fdiv; + bool fmod; + bool fadd; + bool fmul; + bool fsgldiv; + bool frem; + bool fscale; + bool fsglmul; + bool fsub; + bool fsincos; + bool fcmp; + bool ftst; +}; +extern struct jit_disable_opcodes jit_disable; + + +extern void comp_fpp_opp (uae_u32 opcode, uae_u16 extra); +extern void comp_fbcc_opp (uae_u32 opcode); +extern void comp_fscc_opp (uae_u32 opcode, uae_u16 extra); +void comp_fdbcc_opp (uae_u32 opcode, uae_u16 extra); +void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc); +void comp_fsave_opp (uae_u32 opcode); +void comp_frestore_opp (uae_u32 opcode); + +extern uae_u32 needed_flags; +extern uae_u8* comp_pc_p; +extern void* pushall_call_handler; + +#define VREGS 32 +#define VFREGS 16 + +#define INMEM 1 +#define CLEAN 2 +#define DIRTY 3 +#define UNDEF 4 +#define ISCONST 5 + +typedef struct { + uae_u32* mem; + uae_u32 val; + uae_u8 is_swapped; + uae_u8 status; + uae_s8 realreg; /* gb-- realreg can hold -1 */ + uae_u8 realind; /* The index in the holds[] array */ + uae_u8 needflush; + uae_u8 validsize; + uae_u8 dirtysize; + uae_u8 dummy; +} reg_status; + +typedef struct { + uae_u32* mem; + double val; + uae_u8 status; + uae_s8 realreg; /* gb-- realreg can hold -1 */ + uae_u8 realind; + uae_u8 needflush; +} freg_status; + +#define SP_REG 15 +#define PC_P 16 +#define FLAGX 17 +#define FLAGTMP 18 +#define NEXT_HANDLER 19 +#define S1 20 +#define S2 21 +#define S3 22 +#define S4 23 +#define S5 24 +#define S6 25 +#define S7 26 +#define S8 27 +#define S9 28 +#define S10 29 +#define S11 30 +#define S12 31 + +#define FP_RESULT 8 +#define FS1 9 +#define FS2 10 +#define FS3 11 + +typedef struct { + uae_u32 touched; + uae_s8 holds[VREGS]; + uae_u8 nholds; + uae_u8 canbyte; + uae_u8 canword; + uae_u8 locked; +} n_status; + +typedef struct { + uae_u32 touched; + uae_s8 holds[VFREGS]; + uae_u8 nholds; + uae_u8 locked; +} fn_status; + +/* For flag handling */ +#define NADA 1 +#define TRASH 2 +#define VALID 3 + +/* needflush values */ +#define NF_SCRATCH 0 +#define NF_TOMEM 1 +#define NF_HANDLER 2 + +typedef struct { + /* Integer part */ + reg_status state[VREGS]; + n_status nat[N_REGS]; + uae_u32 flags_on_stack; + uae_u32 flags_in_flags; + uae_u32 flags_are_important; + /* FPU part */ + freg_status fate[VFREGS]; + fn_status fat[N_FREGS]; + + /* x86 FPU part */ + uae_s8 spos[N_FREGS]; + uae_s8 onstack[6]; + uae_s8 tos; +} bigstate; + +typedef struct { + /* Integer part */ + uae_s8 virt[VREGS]; + uae_s8 nat[N_REGS]; +} smallstate; + +extern int touchcnt; + +#define IMM uae_s32 +#define RR1 uae_u32 +#define RR2 uae_u32 +#define RR4 uae_u32 +/* + R1, R2, R4 collides with ARM registers defined in ucontext +#define R1 uae_u32 +#define R2 uae_u32 +#define R4 uae_u32 +*/ +#define W1 uae_u32 +#define W2 uae_u32 +#define W4 uae_u32 +#define RW1 uae_u32 +#define RW2 uae_u32 +#define RW4 uae_u32 +#define MEMR uae_u32 +#define MEMW uae_u32 +#define MEMRW uae_u32 +#define MEMPTR uintptr +#define MEMPTRR MEMPTR +#define MEMPTRW MEMPTR +#define MEMPTRRW MEMPTR + +#define FW uae_u32 +#define FR uae_u32 +#define FRW uae_u32 + +#define MIDFUNC(nargs,func,args) void func args +#define COMPCALL(func) func + +#define LOWFUNC(flags,mem,nargs,func,args) static inline void func args + +/* What we expose to the outside */ +#define DECLARE_MIDFUNC(func) extern void func + +#if defined(CPU_arm) + +#include "compemu_midfunc_arm.h" + +#if defined(USE_JIT2) +#include "compemu_midfunc_arm2.h" +#endif +#endif + +#if defined(CPU_i386) || defined(CPU_x86_64) +#include "compemu_midfunc_x86.h" +#endif + +#undef DECLARE_MIDFUNC + +extern int failure; +#define FAIL(x) do { failure|=x; } while (0) + +/* Convenience functions exposed to gencomp */ +extern uae_u32 m68k_pc_offset; +extern void readbyte(int address, int dest, int tmp); +extern void readword(int address, int dest, int tmp); +extern void readlong(int address, int dest, int tmp); +extern void writebyte(int address, int source, int tmp); +extern void writeword(int address, int source, int tmp); +extern void writelong(int address, int source, int tmp); +extern void writeword_clobber(int address, int source, int tmp); +extern void writelong_clobber(int address, int source, int tmp); +extern void get_n_addr(int address, int dest, int tmp); +extern void get_n_addr_jmp(int address, int dest, int tmp); +extern void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp); +/* Set native Z flag only if register is zero */ +extern void set_zero(int r, int tmp); +extern int kill_rodent(int r); +#define SYNC_PC_OFFSET 100 +extern void sync_m68k_pc(void); +extern uae_u32 get_const(int r); +extern int is_const(int r); +extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); +void compemu_make_sr(int sr, int tmp); +void compemu_enter_super(int sr); +void compemu_exc_make_frame(int format, int sr, int currpc, int nr, int tmp); +void compemu_bkpt(void); +extern bool disasm_this_inst; + +#define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) +#define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) +#define comp_get_ilong(o) do_get_mem_long((uae_u32 *)(comp_pc_p + (o))) + +struct blockinfo_t; + +typedef struct dep_t { + uae_u32* jmp_off; + struct blockinfo_t* target; + struct blockinfo_t* source; + struct dep_t** prev_p; + struct dep_t* next; +} dependency; + +typedef struct checksum_info_t { + uae_u8 *start_p; + uae_u32 length; + struct checksum_info_t *next; +} checksum_info; + +typedef struct blockinfo_t { + uae_s32 count; + cpuop_func* direct_handler_to_use; + cpuop_func* handler_to_use; + /* The direct handler does not check for the correct address */ + + cpuop_func* handler; + cpuop_func* direct_handler; + + cpuop_func* direct_pen; + cpuop_func* direct_pcc; + +#ifdef UAE + uae_u8* nexthandler; +#endif + uae_u8* pc_p; + + uae_u32 c1; + uae_u32 c2; +#if USE_CHECKSUM_INFO + checksum_info *csi; +#else + uae_u32 len; + uae_u32 min_pcp; +#endif + + struct blockinfo_t* next_same_cl; + struct blockinfo_t** prev_same_cl_p; + struct blockinfo_t* next; + struct blockinfo_t** prev_p; + + uae_u8 optlevel; + uae_u8 needed_flags; + uae_u8 status; + uae_u8 havestate; + + dependency dep[2]; /* Holds things we depend on */ + dependency* deplist; /* List of things that depend on this */ + smallstate env; + +#ifdef JIT_DEBUG + /* (gb) size of the compiled block (direct handler) */ + uae_u32 direct_handler_size; +#endif +} blockinfo; + +#define BI_INVALID 0 +#define BI_ACTIVE 1 +#define BI_NEED_RECOMP 2 +#define BI_NEED_CHECK 3 +#define BI_CHECKING 4 +#define BI_COMPILING 5 +#define BI_FINALIZING 6 + +void execute_normal(void); +void exec_nostats(void); +void do_nothing(void); + +#else + +static inline void flush_icache(void) { } + +#endif /* !USE_JIT */ + +#ifdef UAE + +typedef struct { + uae_u8 type; + uae_u8 reg; + uae_u32 next; +} regacc; + +#define JIT_EXCEPTION_HANDLER +// #define JIT_ALWAYS_DISTRUST + +/* ARAnyM uses fpu_register name, used in scratch_t */ +/* FIXME: check that no ARAnyM code assumes different floating point type */ +typedef fptype fpu_register; + +extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles); + +#define MAXCYCLES (1000 * CYCLE_UNIT) +#define scaled_cycles(x) (currprefs.m68k_speed<0?(((x)/SCALE)?(((x)/SCALE (uintptr_t) 0xffffffff) { + jit_abort("JIT: 64-bit pointer (0x%llx) at %s:%d (fatal)", + (unsigned long long)address, file, line); + } + return (uae_u32) address; +} +#define uae_p32(x) (check_uae_p32((uintptr)(x), __FILE__, __LINE__)) +#else +#define uae_p32(x) ((uae_u32)(x)) +#endif + +#endif /* COMPEMU_H */ diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu_fpp.cpp b/BasiliskII/src/uae_cpu_2021/compiler/compemu_fpp.cpp new file mode 100644 index 000000000..d9a1e4921 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu_fpp.cpp @@ -0,0 +1,2089 @@ +/* + * compiler/compemu_fpp.cpp - Dynamic translation of FPU instructions + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * UAE - The Un*x Amiga Emulator + * + * MC68881 emulation + * + * Copyright 1996 Herman ten Brugge + * Adapted for JIT compilation (c) Bernd Meyer, 2000 + */ + +#ifdef USE_JIT + +#include "sysdeps.h" + +#include +#include +#include + +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#include "main.h" +#include "compiler/compemu.h" +#include "fpu/fpu.h" +#include "fpu/flags.h" +#include "fpu/exceptions.h" +#include "fpu/rounding.h" + +#define DEBUG 0 +#include "debug.h" + +struct jit_disable_opcodes jit_disable; + +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) +#define LD(x) x ## L +#else +#define LD(x) x +#endif + +// gb-- WARNING: get_fpcr() and set_fpcr() support is experimental +#define HANDLE_FPCR 0 + +// - IEEE-based fpu core must be used +#if defined(FPU_IEEE) +# define CAN_HANDLE_FPCR +#endif + +// - Generic rounding mode and precision modes are supported if set together +#if defined(FPU_USE_GENERIC_ROUNDING_MODE) && defined(FPU_USE_GENERIC_ROUNDING_PRECISION) +# define CAN_HANDLE_FPCR +#endif + +// - X86 rounding mode and precision modes are *not* supported but might work (?!) +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) +# define CAN_HANDLE_FPCR +#endif + +#if HANDLE_FPCR && !defined(CAN_HANDLE_FPCR) +# warning "Can't handle FPCR, will FAIL(1) at runtime" +# undef HANDLE_FPCR +# define HANDLE_FPCR 0 +#endif + +#define STATIC_INLINE static inline +#define MAKE_FPSR(r) do { fmov_rr(FP_RESULT,r); } while (0) + +#define delay nop() ;nop() +#define delay2 nop() ;nop() + +#define UNKNOWN_EXTRA 0xFFFFFFFF +#if 0 +static void fpuop_illg(uae_u32 opcode, uae_u32 /* extra */) +{ +/* + if (extra == UNKNOWN_EXTRA) + printf("FPU opcode %x, extra UNKNOWN_EXTRA\n",opcode & 0xFFFF); + else + printf("FPU opcode %x, extra %x\n",opcode & 0xFFFF,extra & 0xFFFF); +*/ + op_illg(opcode); +} +#endif + +uae_s32 temp_fp[4]; /* To convert between FP/integer */ + +/* return register number, or -1 for failure */ +STATIC_INLINE int get_fp_value(uae_u32 opcode, uae_u16 extra) +{ + int size; + int mode; + int reg; + uae_u32 ad = 0; + static int const sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; + static int const sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; + + if ((extra & 0x4000) == 0) + { + return ((extra >> 10) & 7); + } + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + switch (mode) + { + case 0: /* Dn */ + switch (size) + { + case 6: /* byte */ + sign_extend_8_rr(S1, reg); + mov_l_mr((uintptr) temp_fp, S1); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + return FS1; + case 4: /* word */ + sign_extend_16_rr(S1, reg); + mov_l_mr((uintptr) temp_fp, S1); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + return FS1; + case 0: /* long */ + mov_l_mr((uintptr) temp_fp, reg); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + return FS1; + case 1: /* single precision */ + mov_l_mr((uintptr) temp_fp, reg); + delay2; + fmovs_rm(FS1, (uintptr) temp_fp); + return FS1; + default: + return -1; + } + return -1; /* Should be unreachable */ + case 1: /* An */ + return -1; /* Genuine invalid instruction */ + default: + break; + } + + /* OK, we *will* have to load something from an address. Let's make + sure we know how to handle that, or quit early --- i.e. *before* + we do any postincrement/predecrement that we may regret */ + switch (size) + { + case 0: /* long */ + case 1: /* single precision */ + case 2: /* extended precision */ + case 4: /* word */ + case 5: /* double precision */ + case 6: /* byte */ + break; + case 3: /* packed decimal static */ + default: + return -1; + } + + switch (mode) + { + case 2: /* (An) */ + ad = S1; /* We will change it, anyway ;-) */ + mov_l_rr(ad, reg + 8); + break; + case 3: /* (An)+ */ + ad = S1; + mov_l_rr(ad, reg + 8); + lea_l_brr(reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size])); + break; + case 4: /* -(An) */ + ad = S1; + lea_l_brr(reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size])); + mov_l_rr(ad, reg + 8); + break; + case 5: /* d16(An) */ + { + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_rr(ad, reg + 8); + lea_l_brr(ad, ad, off); + } + break; + case 6: /* d8(An,Xn) */ + { + uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + calc_disp_ea_020(reg + 8, dp, ad, S2); + } + break; + case 7: + switch (reg) + { + case 0: /* abs.w */ + { + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, off); + } + break; + case 1: /* abs.l */ + { + uae_u32 off = comp_get_ilong((m68k_pc_offset += 4) - 4); + + ad = S1; + mov_l_ri(ad, off); + } + break; + case 2: /* d16(pc) */ + { + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, address + PC16off); + } + break; + case 3: /* d8(pc,Xn) */ + return -1; + case 4: /* #imm */ + { + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + + ad = S1; + // Immediate addressing mode && Operation Length == Byte -> + // Use the low-order byte of the extension word. + if (size == 6) + address++; + mov_l_ri(ad, address); + m68k_pc_offset += sz2[size]; + } + break; + default: + return -1; + } + } + + switch (size) + { + case 0: /* long */ + readlong(ad, S2, S3); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + break; + case 1: /* single precision */ + readlong(ad, S2, S3); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovs_rm(FS1, (uintptr) temp_fp); + break; + case 2: /* extended precision */ + readword(ad, S2, S3); + mov_w_mr(((uintptr) temp_fp) + 8, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + // always set the explicit integer bit. + or_l_ri(S2, 0x80000000); + mov_l_mr((uintptr) (temp_fp) + 4, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + delay2; + fmov_ext_rm(FS1, (uintptr) (temp_fp)); + break; + case 3: /* packed decimal static */ + return -1; /* Some silly "packed" stuff */ + case 4: /* word */ + readword(ad, S2, S3); + sign_extend_16_rr(S2, S2); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + break; + case 5: /* double precision */ + readlong(ad, S2, S3); + mov_l_mr(((uintptr) temp_fp) + 4, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + delay2; + fmov_rm(FS1, (uintptr) (temp_fp)); + break; + case 6: /* byte */ + readbyte(ad, S2, S3); + sign_extend_8_rr(S2, S2); + mov_l_mr((uintptr) temp_fp, S2); + delay2; + fmovi_rm(FS1, (uintptr) temp_fp); + break; + default: + return -1; + } + return FS1; +} + + +/* return of -1 means failure, >=0 means OK */ +STATIC_INLINE int put_fp_value(int val, uae_u32 opcode, uae_u16 extra) +{ + int size; + int mode; + int reg; + uae_u32 ad; + static int const sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; + static int const sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; + + if ((extra & 0x4000) == 0) + { + const int dest_reg = (extra >> 10) & 7; + + fmov_rr(dest_reg, val); + // gb-- status register is affected + MAKE_FPSR(dest_reg); + return 0; + } + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + ad = (uae_u32) -1; + switch (mode) + { + case 0: /* Dn */ + switch (size) + { + case 6: /* byte */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_b_rm(reg, (uintptr) temp_fp); + return 0; + case 4: /* word */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_w_rm(reg, (uintptr) temp_fp); + return 0; + case 0: /* long */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(reg, (uintptr) temp_fp); + return 0; + case 1: /* single precision */ + fmovs_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(reg, (uintptr) temp_fp); + return 0; + default: + return -1; + } + case 1: /* An */ + return -1; /* genuine invalid instruction */ + default: + break; + } + + /* Let's make sure we get out *before* doing something silly if + we can't handle the size */ + switch (size) + { + case 0: /* long */ + case 1: /* single precision */ + case 2: /* extended precision */ + case 4: /* word */ + case 5: /* double precision */ + case 6: /* byte */ + break; + case 3: /* packed decimal static */ + default: + return -1; + } + + switch (mode) + { + case 2: /* (An) */ + ad = S1; + mov_l_rr(ad, reg + 8); + break; + case 3: /* (An)+ */ + ad = S1; + mov_l_rr(ad, reg + 8); + lea_l_brr(reg + 8, reg + 8, (reg == 7 ? sz2[size] : sz1[size])); + break; + case 4: /* -(An) */ + ad = S1; + lea_l_brr(reg + 8, reg + 8, -(reg == 7 ? sz2[size] : sz1[size])); + mov_l_rr(ad, reg + 8); + break; + case 5: /* d16(An) */ + { + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_rr(ad, reg + 8); + add_l_ri(ad, off); + } + break; + case 6: /* d8(An,Xn) */ + { + uae_u32 dp = comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + calc_disp_ea_020(reg + 8, dp, ad, S2); + } + break; + case 7: + switch (reg) + { + case 0: /* abs.w */ + { + uae_u32 off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, off); + } + break; + case 1: /* abs.l */ + { + uae_u32 off = comp_get_ilong((m68k_pc_offset += 4) - 4); + + ad = S1; + mov_l_ri(ad, off); + } + break; + case 2: /* d16(pc) */ + { + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + uae_s32 PC16off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + + ad = S1; + mov_l_ri(ad, address + PC16off); + } + break; + case 3: /* d8(pc,Xn) */ + return -1; + case 4: /* #imm */ + { + uae_u32 address = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + + ad = S1; + mov_l_ri(ad, address); + m68k_pc_offset += sz2[size]; + } + break; + default: + return -1; + } + } + + switch (size) + { + case 0: /* long */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 1: /* single precision */ + fmovs_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 2: /* extended precision */ + fmov_ext_mr((uintptr) temp_fp, val); + delay; + mov_w_rm(S2, (uintptr) temp_fp + 8); + writeword_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 3: /* packed decimal static */ + return -1; /* Packed */ + case 4: /* word */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writeword_clobber(ad, S2, S3); + break; + case 5: /* double precision */ + fmov_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + break; + case 6: /* byte */ + fmovi_mr((uintptr) temp_fp, val); + delay; + mov_l_rm(S2, (uintptr) temp_fp); + writebyte(ad, S2, S3); + break; + default: + return -1; + } + return 0; +} + + +/* return -1 for failure, or register number for success */ +STATIC_INLINE int get_fp_ad(uae_u32 opcode) +{ + int mode; + int reg; + uae_s32 off; + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + switch (mode) + { + case 0: /* Dn */ + case 1: /* An */ + return -1; + case 2: /* (An) */ + case 3: /* (An)+ */ + case 4: /* -(An) */ + mov_l_rr(S1, 8 + reg); + return S1; + case 5: /* d16(An) */ + off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + mov_l_rr(S1, 8 + reg); + add_l_ri(S1, off); + return S1; + case 6: /* d8(An,Xn) */ + return -1; + break; + case 7: + switch (reg) + { + case 0: /* abs.w */ + off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + mov_l_ri(S1, off); + return S1; + case 1: /* abs.l */ + off = comp_get_ilong((m68k_pc_offset += 4) - 4); + mov_l_ri(S1, off); + return S1; + case 2: /* d16(pc) */ + off = start_pc + ((char *) comp_pc_p - (char *) start_pc_p) + m68k_pc_offset; + off += (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + mov_l_ri(S1, off); + return S1; + case 3: /* d8(pc,Xn) */ + return -1; + default: + return -1; + } + } + abort(); +} + + +/* return -1 for failure, or register number for success */ +void comp_fdbcc_opp (uae_u32 /* opcode */, uae_u16 /* extra */) +{ + if (jit_disable.fdbcc) + { + FAIL(1); + return; + } + FAIL(1); + return; +} + + +void comp_fscc_opp(uae_u32 opcode, uae_u16 extra) +{ + int reg; + + if (jit_disable.fscc) + { + FAIL(1); + return; + } + + if (extra & 0x20) + { /* only cc from 00 to 1f are defined */ + FAIL(1); + return; + } + if ((opcode & 0x38) != 0) + { /* We can only do to integer register */ + FAIL(1); + return; + } + + fflags_into_flags(S2); + reg = (opcode & 7); + + mov_l_ri(S1, 255); + mov_l_ri(S4, 0); + switch (extra & 0x0f) + { /* according to fpp.c, the 0x10 bit is ignored + */ + case 0: + break; /* set never */ + case 1: + mov_l_rr(S2, S4); + cmov_l_rr(S4, S1, 4); + cmov_l_rr(S4, S2, 10); + break; + case 2: + cmov_l_rr(S4, S1, 7); + break; + case 3: + cmov_l_rr(S4, S1, 3); + break; + case 4: + mov_l_rr(S2, S4); + cmov_l_rr(S4, S1, 2); + cmov_l_rr(S4, S2, 10); + break; + case 5: + mov_l_rr(S2, S4); + cmov_l_rr(S4, S1, 6); + cmov_l_rr(S4, S2, 10); + break; + case 6: + cmov_l_rr(S4, S1, 5); + break; + case 7: + cmov_l_rr(S4, S1, 11); + break; + case 8: + cmov_l_rr(S4, S1, 10); + break; + case 9: + cmov_l_rr(S4, S1, 4); + break; + case 10: + cmov_l_rr(S4, S1, 10); + cmov_l_rr(S4, S1, 7); + break; + case 11: + cmov_l_rr(S4, S1, 4); + cmov_l_rr(S4, S1, 3); + break; + case 12: + cmov_l_rr(S4, S1, 2); + break; + case 13: + cmov_l_rr(S4, S1, 6); + break; + case 14: + cmov_l_rr(S4, S1, 5); + cmov_l_rr(S4, S1, 10); + break; + case 15: + mov_l_rr(S4, S1); + break; + } + + if ((opcode & 0x38) == 0) + { + mov_b_rr(reg, S4); + } else + { + abort(); +#if 0 + int cc; + + if (get_fp_ad(opcode) < 0) + { + FAIL(1); + } else + { + put_byte(ad, cc ? 0xff : 0x00); + } +#endif + } +} + + +void comp_ftrapcc_opp (uae_u32 /* opcode */, uaecptr /* oldpc */) +{ + FAIL(1); + return; +} + + +void comp_fbcc_opp(uae_u32 opcode) +{ + uae_u32 start_68k_offset = m68k_pc_offset; + uae_u32 off; + uae_u32 v1; + uae_u32 v2; + int cc; + + // comp_pc_p is expected to be bound to 32-bit addresses + assert((uintptr) comp_pc_p <= 0xffffffffUL); + + if (jit_disable.fbcc) + { + FAIL(1); + return; + } + if (opcode & 0x20) + { /* only cc from 00 to 1f are defined */ + FAIL(1); + return; + } + if ((opcode & 0x40) == 0) + { + off = (uae_s32) (uae_s16) comp_get_iword((m68k_pc_offset += 2) - 2); + } else + { + off = comp_get_ilong((m68k_pc_offset += 4) - 4); + } + mov_l_ri(S1, (uintptr) (comp_pc_p + off - (m68k_pc_offset - start_68k_offset))); + mov_l_ri(PC_P, (uintptr) comp_pc_p); + + /* Now they are both constant. Might as well fold in m68k_pc_offset */ + add_l_ri(S1, m68k_pc_offset); + add_l_ri(PC_P, m68k_pc_offset); + m68k_pc_offset = 0; + + /* according to fpp.c, the 0x10 bit is ignored + (it handles exception handling, which we don't + do, anyway ;-) */ + cc = opcode & 0x0f; + v1 = get_const(PC_P); + v2 = get_const(S1); + fflags_into_flags(S2); + + switch (cc) + { + case 0: + break; /* jump never */ + case 1: + mov_l_rr(S2, PC_P); + cmov_l_rr(PC_P, S1, 4); + cmov_l_rr(PC_P, S2, 10); + break; + case 2: + register_branch(v1, v2, 7); + break; + case 3: + register_branch(v1, v2, 3); + break; + case 4: + mov_l_rr(S2, PC_P); + cmov_l_rr(PC_P, S1, 2); + cmov_l_rr(PC_P, S2, 10); + break; + case 5: + mov_l_rr(S2, PC_P); + cmov_l_rr(PC_P, S1, 6); + cmov_l_rr(PC_P, S2, 10); + break; + case 6: + register_branch(v1, v2, 5); + break; + case 7: + register_branch(v1, v2, 11); + break; + case 8: + register_branch(v1, v2, 10); + break; + case 9: + register_branch(v1, v2, 4); + break; + case 10: + cmov_l_rr(PC_P, S1, 10); + cmov_l_rr(PC_P, S1, 7); + break; + case 11: + cmov_l_rr(PC_P, S1, 4); + cmov_l_rr(PC_P, S1, 3); + break; + case 12: + register_branch(v1, v2, 2); + break; + case 13: + register_branch(v1, v2, 6); + break; + case 14: + cmov_l_rr(PC_P, S1, 5); + cmov_l_rr(PC_P, S1, 10); + break; + case 15: + mov_l_rr(PC_P, S1); + break; + } +} + + + /* Floating point conditions + The "NotANumber" part could be problematic; Howver, when NaN is + encountered, the ftst instruction sets bot N and Z to 1 on the x87, + so quite often things just fall into place. This is probably not + accurate wrt the 68k FPU, but it is *as* accurate as this was before. + However, some more thought should go into fixing this stuff up so + it accurately emulates the 68k FPU. +>==> 13) & 0x7) + { + case 1: /* illegal */ + break; + + case 3: /* FMOVE Fpn, */ + /* 2nd most common */ + if (jit_disable.fmove) + { + FAIL(1); + return; + } + + if (put_fp_value((extra >> 7) & 7, opcode, extra) < 0) + { + FAIL(1); + return; + } + return; + + case 6: /* FMOVEM , */ + case 7: /* FMOVEM , */ + if (jit_disable.fmovem) + { + FAIL(1); + return; + } + + { + int ad; + uae_u32 list = 0; + int incr = 0; + + if (extra & 0x2000) + { + /* FMOVEM FPP->memory */ + switch ((extra >> 11) & 3) + { /* Get out early if failure */ + case 0: /* static pred */ + case 2: /* static postinc */ + break; + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + default: + FAIL(1); + return; + } + if ((ad = get_fp_ad(opcode)) < 0) + { + FAIL(1); + return; + } + switch ((extra >> 11) & 3) + { + case 0: /* static pred */ + list = extra & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + abort(); + } + if (incr < 0) + { /* Predecrement */ + for (reg = 7; reg >= 0; reg--) + { + if (list & 0x80) + { + fmov_ext_mr((uintptr) temp_fp, reg); + delay; + sub_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + sub_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + sub_l_ri(ad, 4); + mov_w_rm(S2, (uintptr) temp_fp + 8); + writeword_clobber(ad, S2, S3); + } + list <<= 1; + } + } else + { /* Postincrement */ + for (reg = 0; reg < 8; reg++) + { + if (list & 0x80) + { + fmov_ext_mr((uintptr) temp_fp, reg); + delay; + mov_w_rm(S2, (uintptr) temp_fp + 8); + writeword_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp + 4); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + mov_l_rm(S2, (uintptr) temp_fp); + writelong_clobber(ad, S2, S3); + add_l_ri(ad, 4); + } + list <<= 1; + } + } + if ((opcode & 0x38) == 0x18) + mov_l_rr((opcode & 7) + 8, ad); + if ((opcode & 0x38) == 0x20) + mov_l_rr((opcode & 7) + 8, ad); + } else + { + /* FMOVEM memory->FPP */ + + int ad; + + switch ((extra >> 11) & 3) + { /* Get out early if failure */ + case 0: /* static pred */ + case 2: /* static postinc */ + break; + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + default: + FAIL(1); + return; + } + ad = get_fp_ad(opcode); + if (ad < 0) + { + D(bug("no ad\n")); + FAIL(1); + return; + } + switch ((extra >> 11) & 3) + { + case 0: /* static pred */ + list = extra & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 1: /* dynamic pred */ + case 3: /* dynamic postinc */ + abort(); + } + + if (incr < 0) + { + // not reached + for (reg = 7; reg >= 0; reg--) + { + if (list & 0x80) + { + sub_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + sub_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp) + 4, S2); + sub_l_ri(ad, 4); + readword(ad, S2, S3); + mov_w_mr(((uintptr) temp_fp) + 8, S2); + delay2; + fmov_ext_rm(reg, (uintptr) (temp_fp)); + } + list <<= 1; + } + } else + { + for (reg = 0; reg < 8; reg++) + { + if (list & 0x80) + { + readword(ad, S2, S3); + mov_w_mr(((uintptr) temp_fp) + 8, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp) + 4, S2); + add_l_ri(ad, 4); + readlong(ad, S2, S3); + mov_l_mr((uintptr) (temp_fp), S2); + add_l_ri(ad, 4); + delay2; + fmov_ext_rm(reg, (uintptr) (temp_fp)); + } + list <<= 1; + } + } + if ((opcode & 0x38) == 0x18) + mov_l_rr((opcode & 7) + 8, ad); + if ((opcode & 0x38) == 0x20) + mov_l_rr((opcode & 7) + 8, ad); + } + } + return; + + case 4: /* FMOVEM , */ + case 5: /* FMOVEM , */ + if (jit_disable.fmovec) + { + FAIL(1); + return; + } + + /* rare */ + if ((opcode & 0x30) == 0) + { + /* = Dn or An */ + if (extra & 0x2000) + { + if (extra & 0x1000) + { +#if HANDLE_FPCR + mov_l_rm(opcode & 15, (uintptr) & fpu.fpcr.rounding_mode); + or_l_rm(opcode & 15, (uintptr) & fpu.fpcr.rounding_precision); +#else + FAIL(1); + return; +#endif + } + if (extra & 0x0800) + { + FAIL(1); + return; + } + if (extra & 0x0400) + { + /* FPIAR: fixme; we cannot correctly return the address from compiled code */ + mov_l_rm(opcode & 15, (uintptr) & fpu.instruction_address); + return; + } + } else + { + // gb-- moved here so that we may FAIL() without generating any code + if (extra & 0x0800) + { + // set_fpsr(m68k_dreg (regs, opcode & 15)); + FAIL(1); + return; + } + if (extra & 0x1000) + { +#if HANDLE_FPCR +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) + FAIL(1); + return; +#endif + mov_l_rr(S1, opcode & 15); + mov_l_rr(S2, opcode & 15); + and_l_ri(S1, FPCR_ROUNDING_PRECISION); + and_l_ri(S2, FPCR_ROUNDING_MODE); + mov_l_mr((uintptr) & fpu.fpcr.rounding_precision, S1); + mov_l_mr((uintptr) & fpu.fpcr.rounding_mode, S2); +#else + FAIL(1); + return; +#endif + } + if (extra & 0x0400) + { + /* FPIAR: does that make sense at all? */ + mov_l_mr((uintptr) & fpu.instruction_address, opcode & 15); + } + return; + } + } else if ((opcode & 0x3f) == 0x3c) + { + /* = #imm */ + if ((extra & 0x2000) == 0) + { + // gb-- moved here so that we may FAIL() without generating any code + if (extra & 0x0800) + { + FAIL(1); + return; + } + if (extra & 0x1000) + { + comp_get_ilong((m68k_pc_offset += 4) - 4); +#if HANDLE_FPCR +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) + FAIL(1); + return; +#endif + // mov_l_mi((uintptr)®s.fpcr,val); + mov_l_ri(S1, val); + mov_l_ri(S2, val); + and_l_ri(S1, FPCR_ROUNDING_PRECISION); + and_l_ri(S2, FPCR_ROUNDING_MODE); + mov_l_mr((uintptr) & fpu.fpcr.rounding_precision, S1); + mov_l_mr((uintptr) & fpu.fpcr.rounding_mode, S2); +#else + FAIL(1); + return; +#endif + } + if (extra & 0x0400) + { + uae_u32 val = comp_get_ilong((m68k_pc_offset += 4) - 4); + + mov_l_mi((uintptr) & fpu.instruction_address, val); + } + return; + } + FAIL(1); + return; + } else if (extra & 0x2000) + { + FAIL(1); + return; + } else + { + FAIL(1); + return; + } + FAIL(1); + return; + + case 0: + case 2: /* Extremely common */ + reg = (extra >> 7) & 7; + if ((extra & 0xfc00) == 0x5c00) + { + if (jit_disable.fmovecr) + { + FAIL(1); + return; + } + + switch (extra & 0x7f) + { + case 0x00: + fmov_pi(reg); + break; + case 0x0b: + fmov_log10_2(reg); + break; + case 0x0c: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fmov_ext_rm(reg, (uintptr) & const_e); +#else + fmov_rm(reg, (uintptr) & const_e); +#endif + break; + case 0x0d: + fmov_log2_e(reg); + break; + case 0x0e: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fmov_ext_rm(reg, (uintptr) & const_log10_e); +#else + fmov_rm(reg, (uintptr) & const_log10_e); +#endif + break; + case 0x0f: + fmov_0(reg); + break; + case 0x30: + fmov_loge_2(reg); + break; + case 0x31: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fmov_ext_rm(reg, (uintptr) & const_loge_10); +#else + fmov_rm(reg, (uintptr) & const_loge_10); +#endif + break; + case 0x32: + fmov_1(reg); + break; + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + fmov_ext_rm(reg, (uintptr) (power10 + (extra & 0x7f) - 0x32)); +#else + fmov_rm(reg, (uintptr) (power10 + (extra & 0x7f) - 0x32)); +#endif + break; + default: + /* This is not valid, so we fail */ + FAIL(1); + return; + } + return; + } + + switch (extra & 0x7f) + { + case 0x00: /* FMOVE */ + case 0x40: /* FSMOVE: Explicit rounding. This is just a quick fix. Same + * for all other cases that have three choices */ + case 0x44: /* FDMOVE */ + if (jit_disable.fmove) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmov_rr(reg, src); + MAKE_FPSR(src); + break; + case 0x01: /* FINT */ + if (jit_disable.fint) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x02: /* FSINH */ + if (jit_disable.fsinh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x03: /* FINTRZ */ + if (jit_disable.fintrz) + { + FAIL(1); + return; + } +#ifdef USE_X86_FPUCW + /* If we have control over the CW, we can do this */ + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + mov_l_ri(S1, 16); /* Switch to "round to zero" mode */ + fldcw_m_indexed(S1, (uintptr) x86_fpucw); + + frndint_rr(reg, src); + + /* restore control word */ + mov_l_rm(S1, (uintptr) & regs.fpcr); + and_l_ri(S1, 0x000000f0); + fldcw_m_indexed(S1, (uintptr) x86_fpucw); + + MAKE_FPSR(reg); + break; +#endif + FAIL(1); + return; + break; + case 0x04: /* FSQRT */ + case 0x41: /* FSSQRT */ + case 0x45: /* FDSQRT */ + if (jit_disable.fsqrt) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fsqrt_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x06: /* FLOGNP1 */ + if (jit_disable.flognp1) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x08: /* FETOXM1 */ + if (jit_disable.fetoxm1) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x09: /* FTANH */ + if (jit_disable.ftanh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x0a: /* FATAN */ + if (jit_disable.fatan) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x0c: /* FASIN */ + if (jit_disable.fasin) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x0d: /* FATANH */ + if (jit_disable.fatanh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x0e: /* FSIN */ + if (jit_disable.fsin) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fsin_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x0f: /* FTAN */ + if (jit_disable.ftan) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x10: /* FETOX */ + if (jit_disable.fetox) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fetox_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x11: /* FTWOTOX */ + if (jit_disable.ftwotox) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + ftwotox_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x12: /* FTENTOX */ + if (jit_disable.ftentox) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x14: /* FLOGN */ + if (jit_disable.flogn) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x15: /* FLOG10 */ + if (jit_disable.flog10) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x16: /* FLOG2 */ + if (jit_disable.flog2) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + flog2_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x18: /* FABS */ + case 0x58: /* FSABS */ + case 0x5c: /* FDABS */ + if (jit_disable.fabs) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fabs_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x19: /* FCOSH */ + if (jit_disable.fcosh) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x1a: /* FNEG */ + case 0x5a: /* FSNEG */ + case 0x5e: /* FDNEG */ + if (jit_disable.fneg) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fneg_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x1c: /* FACOS */ + if (jit_disable.facos) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x1d: /* FCOS */ + if (jit_disable.fcos) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fcos_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x1e: /* FGETEXP */ + if (jit_disable.fgetexp) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x1f: /* FGETMAN */ + if (jit_disable.fgetman) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x20: /* FDIV */ + case 0x60: /* FSDIV */ + case 0x64: /* FDDIV */ + if (jit_disable.fdiv) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fdiv_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x21: /* FMOD */ + if (jit_disable.fmod) + { + FAIL(1); + return; + } + + // FIXME: the quotient byte must be computed + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + frem_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x22: /* FADD */ + case 0x62: /* FSADD */ + case 0x66: /* FDADD */ + if (jit_disable.fadd) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fadd_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x23: /* FMUL */ + case 0x63: /* FSMUL */ + case 0x67: /* FDMUL */ + if (jit_disable.fmul) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmul_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x24: /* FSGLDIV */ + if (jit_disable.fsgldiv) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fdiv_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x25: /* FREM */ + if (jit_disable.frem) + { + FAIL(1); + return; + } + // gb-- disabled because the quotient byte must be computed + // otherwise, free rotation in ClarisWorks doesn't work. + FAIL(1); + return; + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + frem1_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x26: /* FSCALE */ + if (jit_disable.fscale) + { + FAIL(1); + return; + } + + FAIL(1); + return; + break; + case 0x27: /* FSGLMUL */ + if (jit_disable.fsglmul) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmul_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x28: /* FSUB */ + case 0x68: /* FSSUB */ + case 0x6c: /* FDSUB */ + if (jit_disable.fsub) + { + FAIL(1); + return; + } + + dont_care_fflags(); + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fsub_rr(reg, src); + MAKE_FPSR(reg); + break; + case 0x30: /* FSINCOS */ + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + if (jit_disable.fsincos) + { + FAIL(1); + return; + } + + FAIL(1); + return; + dont_care_fflags(); + break; + case 0x38: /* FCMP */ + if (jit_disable.fcmp) + { + FAIL(1); + return; + } + + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmov_rr(FP_RESULT, reg); + fsub_rr(FP_RESULT, src); /* Right way? */ + break; + case 0x3a: /* FTST */ + if (jit_disable.ftst) + { + FAIL(1); + return; + } + + src = get_fp_value(opcode, extra); + if (src < 0) + { + FAIL(1); /* Illegal instruction */ + return; + } + fmov_rr(FP_RESULT, src); + break; + default: + FAIL(1); + return; + break; + } + return; + } + FAIL(1); +} + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu_midfunc_x86.cpp b/BasiliskII/src/uae_cpu_2021/compiler/compemu_midfunc_x86.cpp new file mode 100644 index 000000000..8d35c1b95 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu_midfunc_x86.cpp @@ -0,0 +1,2838 @@ +/* + * compiler/compemu_midfunc_arm.cpp - Native MIDFUNCS for IA-32 and AMD64 + * + * Copyright (c) 2014 Jens Heitmann of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * + * Adaptation for Basilisk II and improvements, copyright 2000-2002 + * Gwenole Beauchesne + * + * 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 + * + * Note: + * File is included by compemu_support.cpp + * + */ + +static int f_rmw(int r) +{ + int n; + + f_make_exclusive(r,0); + if (f_isinreg(r)) { + n=live.fate[r].realreg; + } + else + n=f_alloc_reg(r,0); + live.fate[r].status=DIRTY; + live.fat[n].locked++; + live.fat[n].touched=touchcnt++; + return n; +} + +static void fflags_into_flags_internal(uae_u32 tmp) +{ + int r; + + clobber_flags(); + r=f_readreg(FP_RESULT); + if (FFLAG_NREG_CLOBBER_CONDITION) { + int tmp2=tmp; + tmp=writereg_specific(tmp,4,FFLAG_NREG); + raw_fflags_into_flags(r); + unlock2(tmp); + forget_about(tmp2); + } + else + raw_fflags_into_flags(r); + f_unlock(r); + live_flags(); +} + + +/******************************************************************** + * CPU functions exposed to gencomp. Both CREATE and EMIT time * + ********************************************************************/ + + +/* + * RULES FOR HANDLING REGISTERS: + * + * * In the function headers, order the parameters + * - 1st registers written to + * - 2nd read/modify/write registers + * - 3rd registers read from + * * Before calling raw_*, you must call readreg, writereg or rmw for + * each register + * * The order for this is + * - 1st call remove_offset for all registers written to with size<4 + * - 2nd call readreg for all registers read without offset + * - 3rd call rmw for all rmw registers + * - 4th call readreg_offset for all registers that can handle offsets + * - 5th call get_offset for all the registers from the previous step + * - 6th call writereg for all written-to registers + * - 7th call raw_* + * - 8th unlock2 all registers that were locked + */ + +MIDFUNC(0,live_flags,(void)) +{ + live.flags_on_stack=TRASH; + live.flags_in_flags=VALID; + live.flags_are_important=1; +} + +MIDFUNC(0,dont_care_flags,(void)) +{ + live.flags_are_important=0; +} + +/* + * store the state of the x86 carry bit into regflags.x, + * into the position denoted by FLAGBIT_X + */ +MIDFUNC(0,duplicate_carry,(void)) +{ + evict(FLAGX); + make_flags_live_internal(); +#ifdef UAE + COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem + 1, NATIVE_CC_CS); +#else + COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem, NATIVE_CC_CS); +#endif + log_vwrite(FLAGX); +} + +MIDFUNC(3,setcc_for_cntzero,(RR4 /* cnt */, RR4 data, int size)) +{ + uae_u8 *branchadd; + uae_u8 *branchadd2; + + evict(FLAGX); + make_flags_live_internal(); + + raw_pushfl(); + /* + * shift count can only be in CL register; see shrl_b_rr + */ + raw_test_b_rr(X86_CL, X86_CL); + /* if zero, leave X unaffected; carry flag will already be cleared */ + raw_jz_b_oponly(); + branchadd = get_target(); + skip_byte(); + + /* shift count was non-zero; update also x-flag */ + raw_popfl(); +#ifdef UAE + COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem + 1, NATIVE_CC_CS); +#else + COMPCALL(setcc_m)((uintptr)live.state[FLAGX].mem, NATIVE_CC_CS); +#endif + log_vwrite(FLAGX); + raw_jmp_b_oponly(); + branchadd2 = get_target(); + skip_byte(); + *branchadd = (uintptr)get_target() - ((uintptr)branchadd + 1); + + /* shift count was zero; need to set Z & N flags since the native flags were unaffected */ + raw_popfl(); + data = readreg(data, size); + switch (size) + { + case 1: raw_test_b_rr(data, data); break; + case 2: raw_test_w_rr(data, data); break; + case 4: raw_test_l_rr(data, data); break; + } + unlock2(data); + *branchadd2 = (uintptr)get_target() - ((uintptr)branchadd2 + 1); +} + +/* + * Set the x86 carry flag from regflags.x, from the position + * denoted by FLAGBIT_X + */ +MIDFUNC(0,restore_carry,(void)) +{ + if (!have_rat_stall) { /* Not a P6 core, i.e. no partial stalls */ +#ifdef UAE + bt_l_ri_noclobber(FLAGX, FLAGBIT_X+8); +#else + bt_l_ri_noclobber(FLAGX, FLAGBIT_X); +#endif + } + else { /* Avoid the stall the above creates. + This is slow on non-P6, though. + */ +#if defined(UAE) || FLAGBIT_X >= 8 + COMPCALL(rol_w_ri(FLAGX, 16 - FLAGBIT_X)); +#else + COMPCALL(rol_b_ri(FLAGX, 8 - FLAGBIT_X)); +#endif + isclean(FLAGX); + } +} + +MIDFUNC(0,start_needflags,(void)) +{ + needflags=1; +} + +MIDFUNC(0,end_needflags,(void)) +{ + needflags=0; +} + +MIDFUNC(0,make_flags_live,(void)) +{ + make_flags_live_internal(); +} + +MIDFUNC(1,fflags_into_flags,(W2 tmp)) +{ + clobber_flags(); + fflags_into_flags_internal(tmp); +} + +MIDFUNC(2,bt_l_ri,(RR4 r, IMM i)) /* This is defined as only affecting C */ +{ + int size=4; + if (i<16) + size=2; + CLOBBER_BT; + r=readreg(r,size); + raw_bt_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,bt_l_rr,(RR4 r, RR4 b)) /* This is defined as only affecting C */ +{ + CLOBBER_BT; + r=readreg(r,4); + b=readreg(b,4); + raw_bt_l_rr(r,b); + unlock2(r); + unlock2(b); +} + +MIDFUNC(2,btc_l_ri,(RW4 r, IMM i)) +{ + int size=4; + if (i<16) + size=2; + CLOBBER_BT; + r=rmw(r,size,size); + raw_btc_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,btc_l_rr,(RW4 r, RR4 b)) +{ + CLOBBER_BT; + b=readreg(b,4); + r=rmw(r,4,4); + raw_btc_l_rr(r,b); + unlock2(r); + unlock2(b); +} + +MIDFUNC(2,btr_l_ri,(RW4 r, IMM i)) +{ + int size=4; + if (i<16) + size=2; + CLOBBER_BT; + r=rmw(r,size,size); + raw_btr_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,btr_l_rr,(RW4 r, RR4 b)) +{ + CLOBBER_BT; + b=readreg(b,4); + r=rmw(r,4,4); + raw_btr_l_rr(r,b); + unlock2(r); + unlock2(b); +} + +MIDFUNC(2,bts_l_ri,(RW4 r, IMM i)) +{ + int size=4; + if (i<16) + size=2; + CLOBBER_BT; + r=rmw(r,size,size); + raw_bts_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,bts_l_rr,(RW4 r, RR4 b)) +{ + CLOBBER_BT; + b=readreg(b,4); + r=rmw(r,4,4); + raw_bts_l_rr(r,b); + unlock2(r); + unlock2(b); +} + +MIDFUNC(2,mov_l_rm,(W4 d, IMM s)) +{ + CLOBBER_MOV; + d=writereg(d,4); + raw_mov_l_rm(d,s); + unlock2(d); +} + +MIDFUNC(1,call_r,(RR4 r)) /* Clobbering is implicit */ +{ + r=readreg(r,4); + raw_dec_sp(STACK_SHADOW_SPACE); + raw_call_r(r); + raw_inc_sp(STACK_SHADOW_SPACE); + unlock2(r); +} + +MIDFUNC(2,sub_l_mi,(IMM d, IMM s)) +{ + CLOBBER_SUB; + raw_sub_l_mi(d,s) ; +} + +MIDFUNC(2,mov_l_mi,(IMM d, IMM s)) +{ + CLOBBER_MOV; + raw_mov_l_mi(d,s) ; +} + +MIDFUNC(2,mov_w_mi,(IMM d, IMM s)) +{ + CLOBBER_MOV; + raw_mov_w_mi(d,s) ; +} + +MIDFUNC(2,mov_b_mi,(IMM d, IMM s)) +{ + CLOBBER_MOV; + raw_mov_b_mi(d,s) ; +} + +MIDFUNC(2,rol_b_ri,(RW1 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_ROL; + r=rmw(r,1,1); + raw_rol_b_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,rol_w_ri,(RW2 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_ROL; + r=rmw(r,2,2); + raw_rol_w_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,rol_l_ri,(RW4 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_ROL; + r=rmw(r,4,4); + raw_rol_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,rol_l_rr,(RW4 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(rol_l_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_ROL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,4,4); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in rol_l_rr",r); + } + raw_rol_l_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,rol_w_rr,(RW2 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(rol_w_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_ROL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,2,2); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in rol_w_rr",r); + } + raw_rol_w_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,rol_b_rr,(RW1 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(rol_b_ri)(d,(uae_u8)live.state[r].val); + return; + } + + CLOBBER_ROL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,1,1); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in rol_b_rr",r); + } + raw_rol_b_rr(d,r) ; + unlock2(r); + unlock2(d); +} + + +MIDFUNC(2,shll_l_rr,(RW4 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shll_l_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_SHLL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,4,4); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shll_l_rr",r); + } + raw_shll_l_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shll_w_rr,(RW2 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shll_w_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_SHLL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,2,2); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shll_w_rr",r); + } + raw_shll_w_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shll_b_rr,(RW1 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shll_b_ri)(d,(uae_u8)live.state[r].val); + return; + } + + CLOBBER_SHLL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,1,1); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shll_b_rr",r); + } + raw_shll_b_rr(d,r) ; + unlock2(r); + unlock2(d); +} + + +MIDFUNC(2,ror_b_ri,(RR1 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_ROR; + r=rmw(r,1,1); + raw_ror_b_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,ror_w_ri,(RR2 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_ROR; + r=rmw(r,2,2); + raw_ror_w_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,ror_l_ri,(RR4 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_ROR; + r=rmw(r,4,4); + raw_ror_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,ror_l_rr,(RR4 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(ror_l_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_ROR; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,4,4); + raw_ror_l_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,ror_w_rr,(RR2 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(ror_w_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_ROR; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,2,2); + raw_ror_w_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,ror_b_rr,(RR1 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(ror_b_ri)(d,(uae_u8)live.state[r].val); + return; + } + + CLOBBER_ROR; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,1,1); + raw_ror_b_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shrl_l_rr,(RW4 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shrl_l_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_SHRL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,4,4); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shrl_l_rr",r); + } + raw_shrl_l_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shrl_w_rr,(RW2 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shrl_w_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_SHRL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,2,2); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shrl_w_rr",r); + } + raw_shrl_w_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shrl_b_rr,(RW1 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shrl_b_ri)(d,(uae_u8)live.state[r].val); + return; + } + + CLOBBER_SHRL; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,1,1); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shrl_b_rr",r); + } + raw_shrl_b_rr(d,r) ; + unlock2(r); + unlock2(d); +} + + + +MIDFUNC(2,shll_l_ri,(RW4 r, IMM i)) +{ + if (!i && !needflags) + return; + if (isconst(r) && !needflags) { + live.state[r].val<<=i; + return; + } + CLOBBER_SHLL; + r=rmw(r,4,4); + raw_shll_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shll_w_ri,(RW2 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHLL; + r=rmw(r,2,2); + raw_shll_w_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shll_b_ri,(RW1 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHLL; + r=rmw(r,1,1); + raw_shll_b_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shrl_l_ri,(RW4 r, IMM i)) +{ + if (!i && !needflags) + return; + if (isconst(r) && !needflags) { + live.state[r].val>>=i; + return; + } + CLOBBER_SHRL; + r=rmw(r,4,4); + raw_shrl_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shrl_w_ri,(RW2 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHRL; + r=rmw(r,2,2); + raw_shrl_w_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shrl_b_ri,(RW1 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHRL; + r=rmw(r,1,1); + raw_shrl_b_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shra_l_ri,(RW4 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHRA; + r=rmw(r,4,4); + raw_shra_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shra_w_ri,(RW2 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHRA; + r=rmw(r,2,2); + raw_shra_w_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shra_b_ri,(RW1 r, IMM i)) +{ + if (!i && !needflags) + return; + CLOBBER_SHRA; + r=rmw(r,1,1); + raw_shra_b_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,shra_l_rr,(RW4 d, RR1 r)) +{ + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shra_l_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_SHRA; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,4,4); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shra_l_rr",r); + } + raw_shra_l_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shra_w_rr,(RW2 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shra_w_ri)(d,(uae_u8)live.state[r].val); + return; + } + CLOBBER_SHRA; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,2,2); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shra_w_rr",r); + } + raw_shra_w_rr(d,r) ; + unlock2(r); + unlock2(d); +} + +MIDFUNC(2,shra_b_rr,(RW1 d, RR1 r)) +{ /* Can only do this with r==1, i.e. cl */ + + if (isconst(r) && (uae_u8)live.state[r].val != 0) { + COMPCALL(shra_b_ri)(d,(uae_u8)live.state[r].val); + return; + } + + CLOBBER_SHRA; + r=readreg_specific(r,1,SHIFTCOUNT_NREG); + d=rmw(d,1,1); + Dif (r!=X86_CL) { + jit_abort("Illegal register %d in shra_b_rr",r); + } + raw_shra_b_rr(d,r) ; + unlock2(r); + unlock2(d); +} + + +MIDFUNC(2,setcc,(W1 d, IMM cc)) +{ + CLOBBER_SETCC; + d=writereg(d,1); + raw_setcc(d,cc); + unlock2(d); +} + +MIDFUNC(2,setcc_m,(IMM d, IMM cc)) +{ + CLOBBER_SETCC; + raw_setcc_m(d,cc); +} + +MIDFUNC(3,cmov_l_rr,(RW4 d, RR4 s, IMM cc)) +{ + if (d==s) + return; + CLOBBER_CMOV; + s=readreg(s,4); + d=rmw(d,4,4); + raw_cmov_l_rr(d,s,cc); + unlock2(s); + unlock2(d); +} + +MIDFUNC(3,cmov_l_rm,(RW4 d, IMM s, IMM cc)) +{ + CLOBBER_CMOV; + d=rmw(d,4,4); + raw_cmov_l_rm(d,s,cc); + unlock2(d); +} + +MIDFUNC(2,bsf_l_rr,(W4 d, RR4 s)) +{ + CLOBBER_BSF; + s = readreg(s, 4); + d = writereg(d, 4); + raw_bsf_l_rr(d, s); + unlock2(s); + unlock2(d); +} + +/* Set the Z flag depending on the value in s. Note that the + value has to be 0 or -1 (or, more precisely, for non-zero + values, bit 14 must be set)! */ +MIDFUNC(2,simulate_bsf,(W4 tmp, RW4 s)) +{ + CLOBBER_BSF; + s=rmw_specific(s,4,4,FLAG_NREG3); + tmp=writereg(tmp,4); + raw_flags_set_zero(s, tmp); + unlock2(tmp); + unlock2(s); +} + +MIDFUNC(2,imul_32_32,(RW4 d, RR4 s)) +{ + CLOBBER_MUL; + s=readreg(s,4); + d=rmw(d,4,4); + raw_imul_32_32(d,s); + unlock2(s); + unlock2(d); +} + +MIDFUNC(2,imul_64_32,(RW4 d, RW4 s)) +{ + CLOBBER_MUL; + s=rmw_specific(s,4,4,MUL_NREG2); + d=rmw_specific(d,4,4,MUL_NREG1); + raw_imul_64_32(d,s); + unlock2(s); + unlock2(d); +} + +MIDFUNC(2,mul_64_32,(RW4 d, RW4 s)) +{ + CLOBBER_MUL; + s=rmw_specific(s,4,4,MUL_NREG2); + d=rmw_specific(d,4,4,MUL_NREG1); + raw_mul_64_32(d,s); + unlock2(s); + unlock2(d); +} + +MIDFUNC(2,mul_32_32,(RW4 d, RR4 s)) +{ + CLOBBER_MUL; + s=readreg(s,4); + d=rmw(d,4,4); + raw_mul_32_32(d,s); + unlock2(s); + unlock2(d); +} + +#if SIZEOF_VOID_P == 8 +MIDFUNC(2,sign_extend_32_rr,(W4 d, RR2 s)) +{ + int isrmw; + + if (isconst(s)) { + set_const(d,(uae_s32)live.state[s].val); + return; + } + + CLOBBER_SE32; + isrmw=(s==d); + if (!isrmw) { + s=readreg(s,4); + d=writereg(d,4); + } + else { /* If we try to lock this twice, with different sizes, we + are int trouble! */ + s=d=rmw(s,4,4); + } + raw_sign_extend_32_rr(d,s); + if (!isrmw) { + unlock2(d); + unlock2(s); + } + else { + unlock2(s); + } +} +#endif + +MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s)) +{ + int isrmw; + + if (isconst(s)) { + set_const(d,(uae_s32)(uae_s16)live.state[s].val); + return; + } + + CLOBBER_SE16; + isrmw=(s==d); + if (!isrmw) { + s=readreg(s,2); + d=writereg(d,4); + } + else { /* If we try to lock this twice, with different sizes, we + are int trouble! */ + s=d=rmw(s,4,2); + } + raw_sign_extend_16_rr(d,s); + if (!isrmw) { + unlock2(d); + unlock2(s); + } + else { + unlock2(s); + } +} + +MIDFUNC(2,sign_extend_8_rr,(W4 d, RR1 s)) +{ + int isrmw; + + if (isconst(s)) { + set_const(d,(uae_s32)(uae_s8)live.state[s].val); + return; + } + + isrmw=(s==d); + CLOBBER_SE8; + if (!isrmw) { + s=readreg(s,1); + d=writereg(d,4); + } + else { /* If we try to lock this twice, with different sizes, we + are int trouble! */ + s=d=rmw(s,4,1); + } + + raw_sign_extend_8_rr(d,s); + + if (!isrmw) { + unlock2(d); + unlock2(s); + } + else { + unlock2(s); + } +} + + +MIDFUNC(2,zero_extend_16_rr,(W4 d, RR2 s)) +{ + int isrmw; + + if (isconst(s)) { + set_const(d,(uae_u32)(uae_u16)live.state[s].val); + return; + } + + isrmw=(s==d); + CLOBBER_ZE16; + if (!isrmw) { + s=readreg(s,2); + d=writereg(d,4); + } + else { /* If we try to lock this twice, with different sizes, we + are int trouble! */ + s=d=rmw(s,4,2); + } + raw_zero_extend_16_rr(d,s); + if (!isrmw) { + unlock2(d); + unlock2(s); + } + else { + unlock2(s); + } +} + +MIDFUNC(2,zero_extend_8_rr,(W4 d, RR1 s)) +{ + int isrmw; + if (isconst(s)) { + set_const(d,(uae_u32)(uae_u8)live.state[s].val); + return; + } + + isrmw=(s==d); + CLOBBER_ZE8; + if (!isrmw) { + s=readreg(s,1); + d=writereg(d,4); + } + else { /* If we try to lock this twice, with different sizes, we + are int trouble! */ + s=d=rmw(s,4,1); + } + + raw_zero_extend_8_rr(d,s); + + if (!isrmw) { + unlock2(d); + unlock2(s); + } + else { + unlock2(s); + } +} + +MIDFUNC(2,mov_b_rr,(W1 d, RR1 s)) +{ + if (d==s) + return; + if (isconst(s)) { + COMPCALL(mov_b_ri)(d,(uae_u8)live.state[s].val); + return; + } + + CLOBBER_MOV; + s=readreg(s,1); + d=writereg(d,1); + raw_mov_b_rr(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,mov_w_rr,(W2 d, RR2 s)) +{ + if (d==s) + return; + if (isconst(s)) { + COMPCALL(mov_w_ri)(d,(uae_u16)live.state[s].val); + return; + } + + CLOBBER_MOV; + s=readreg(s,2); + d=writereg(d,2); + raw_mov_w_rr(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(4,mov_l_rrm_indexed,(W4 d,RR4 baser, RR4 index, IMM factor)) +{ + CLOBBER_MOV; + baser=readreg(baser,4); + index=readreg(index,4); + d=writereg(d,4); + + raw_mov_l_rrm_indexed(d,baser,index,factor); + unlock2(d); + unlock2(baser); + unlock2(index); +} + +MIDFUNC(4,mov_w_rrm_indexed,(W2 d, RR4 baser, RR4 index, IMM factor)) +{ + CLOBBER_MOV; + baser=readreg(baser,4); + index=readreg(index,4); + d=writereg(d,2); + + raw_mov_w_rrm_indexed(d,baser,index,factor); + unlock2(d); + unlock2(baser); + unlock2(index); +} + +MIDFUNC(4,mov_b_rrm_indexed,(W1 d, RR4 baser, RR4 index, IMM factor)) +{ + CLOBBER_MOV; + baser=readreg(baser,4); + index=readreg(index,4); + d=writereg(d,1); + + raw_mov_b_rrm_indexed(d,baser,index,factor); + + unlock2(d); + unlock2(baser); + unlock2(index); +} + + +MIDFUNC(4,mov_l_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR4 s)) +{ + CLOBBER_MOV; + baser=readreg(baser,4); + index=readreg(index,4); + s=readreg(s,4); + + Dif (baser==s || index==s) + jit_abort("mov_l_mrr_indexed"); + + + raw_mov_l_mrr_indexed(baser,index,factor,s); + unlock2(s); + unlock2(baser); + unlock2(index); +} + +MIDFUNC(4,mov_w_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR2 s)) +{ + CLOBBER_MOV; + baser=readreg(baser,4); + index=readreg(index,4); + s=readreg(s,2); + + raw_mov_w_mrr_indexed(baser,index,factor,s); + unlock2(s); + unlock2(baser); + unlock2(index); +} + +MIDFUNC(4,mov_b_mrr_indexed,(RR4 baser, RR4 index, IMM factor, RR1 s)) +{ + CLOBBER_MOV; + s=readreg(s,1); + baser=readreg(baser,4); + index=readreg(index,4); + + raw_mov_b_mrr_indexed(baser,index,factor,s); + unlock2(s); + unlock2(baser); + unlock2(index); +} + + +MIDFUNC(5,mov_l_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s)) +{ + int basereg=baser; + int indexreg=index; + + CLOBBER_MOV; + s=readreg(s,4); + baser=readreg_offset(baser,4); + index=readreg_offset(index,4); + + base+=get_offset(basereg); + base+=factor*get_offset(indexreg); + + raw_mov_l_bmrr_indexed(base,baser,index,factor,s); + unlock2(s); + unlock2(baser); + unlock2(index); +} + +MIDFUNC(5,mov_w_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s)) +{ + int basereg=baser; + int indexreg=index; + + CLOBBER_MOV; + s=readreg(s,2); + baser=readreg_offset(baser,4); + index=readreg_offset(index,4); + + base+=get_offset(basereg); + base+=factor*get_offset(indexreg); + + raw_mov_w_bmrr_indexed(base,baser,index,factor,s); + unlock2(s); + unlock2(baser); + unlock2(index); +} + +MIDFUNC(5,mov_b_bmrr_indexed,(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s)) +{ + int basereg=baser; + int indexreg=index; + + CLOBBER_MOV; + s=readreg(s,1); + baser=readreg_offset(baser,4); + index=readreg_offset(index,4); + + base+=get_offset(basereg); + base+=factor*get_offset(indexreg); + + raw_mov_b_bmrr_indexed(base,baser,index,factor,s); + unlock2(s); + unlock2(baser); + unlock2(index); +} + + + +/* Read a long from base+baser+factor*index */ +MIDFUNC(5,mov_l_brrm_indexed,(W4 d, IMM base, RR4 baser, RR4 index, IMM factor)) +{ + int basereg=baser; + int indexreg=index; + + CLOBBER_MOV; + baser=readreg_offset(baser,4); + index=readreg_offset(index,4); + base+=get_offset(basereg); + base+=factor*get_offset(indexreg); + d=writereg(d,4); + raw_mov_l_brrm_indexed(d,base,baser,index,factor); + unlock2(d); + unlock2(baser); + unlock2(index); +} + + +MIDFUNC(5,mov_w_brrm_indexed,(W2 d, IMM base, RR4 baser, RR4 index, IMM factor)) +{ + int basereg=baser; + int indexreg=index; + + CLOBBER_MOV; + remove_offset(d,-1); + baser=readreg_offset(baser,4); + index=readreg_offset(index,4); + base+=get_offset(basereg); + base+=factor*get_offset(indexreg); + d=writereg(d,2); + raw_mov_w_brrm_indexed(d,base,baser,index,factor); + unlock2(d); + unlock2(baser); + unlock2(index); +} + + +MIDFUNC(5,mov_b_brrm_indexed,(W1 d, IMM base, RR4 baser, RR4 index, IMM factor)) +{ + int basereg=baser; + int indexreg=index; + + CLOBBER_MOV; + remove_offset(d,-1); + baser=readreg_offset(baser,4); + index=readreg_offset(index,4); + base+=get_offset(basereg); + base+=factor*get_offset(indexreg); + d=writereg(d,1); + raw_mov_b_brrm_indexed(d,base,baser,index,factor); + unlock2(d); + unlock2(baser); + unlock2(index); +} + +/* Read a long from base+factor*index */ +MIDFUNC(4,mov_l_rm_indexed,(W4 d, IMM base, RR4 index, IMM factor)) +{ + int indexreg=index; + + if (isconst(index)) { + COMPCALL(mov_l_rm)(d,base+factor*live.state[index].val); + return; + } + + CLOBBER_MOV; + index=readreg_offset(index,4); + base+=get_offset(indexreg)*factor; + d=writereg(d,4); + + raw_mov_l_rm_indexed(d,base,index,factor); + unlock2(index); + unlock2(d); +} + +/* read the long at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_l_rR,(W4 d, RR4 s, IMM offset)) +{ + if (isconst(s)) { + COMPCALL(mov_l_rm)(d,live.state[s].val+offset); + return; + } + CLOBBER_MOV; + s=readreg(s,4); + d=writereg(d,4); + + raw_mov_l_rR(d,s,offset); + unlock2(d); + unlock2(s); +} + +/* read the word at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_w_rR,(W2 d, RR4 s, IMM offset)) +{ + if (isconst(s)) { + COMPCALL(mov_w_rm)(d,live.state[s].val+offset); + return; + } + CLOBBER_MOV; + s=readreg(s,4); + d=writereg(d,2); + + raw_mov_w_rR(d,s,offset); + unlock2(d); + unlock2(s); +} + +/* read the word at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_b_rR,(W1 d, RR4 s, IMM offset)) +{ + if (isconst(s)) { + COMPCALL(mov_b_rm)(d,live.state[s].val+offset); + return; + } + CLOBBER_MOV; + s=readreg(s,4); + d=writereg(d,1); + + raw_mov_b_rR(d,s,offset); + unlock2(d); + unlock2(s); +} + +/* read the long at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_l_brR,(W4 d, RR4 s, IMM offset)) +{ + int sreg=s; + if (isconst(s)) { + COMPCALL(mov_l_rm)(d,live.state[s].val+offset); + return; + } + CLOBBER_MOV; + s=readreg_offset(s,4); + offset+=get_offset(sreg); + d=writereg(d,4); + + raw_mov_l_brR(d,s,offset); + unlock2(d); + unlock2(s); +} + +/* read the word at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_w_brR,(W2 d, RR4 s, IMM offset)) +{ + int sreg=s; + if (isconst(s)) { + COMPCALL(mov_w_rm)(d,live.state[s].val+offset); + return; + } + CLOBBER_MOV; + remove_offset(d,-1); + s=readreg_offset(s,4); + offset+=get_offset(sreg); + d=writereg(d,2); + + raw_mov_w_brR(d,s,offset); + unlock2(d); + unlock2(s); +} + +/* read the word at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_b_brR,(W1 d, RR4 s, IMM offset)) +{ + int sreg=s; + if (isconst(s)) { + COMPCALL(mov_b_rm)(d,live.state[s].val+offset); + return; + } + CLOBBER_MOV; + remove_offset(d,-1); + s=readreg_offset(s,4); + offset+=get_offset(sreg); + d=writereg(d,1); + + raw_mov_b_brR(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(3,mov_l_Ri,(RR4 d, IMM i, IMM offset)) +{ + int dreg=d; + if (isconst(d)) { + COMPCALL(mov_l_mi)(live.state[d].val+offset,i); + return; + } + + CLOBBER_MOV; + d=readreg_offset(d,4); + offset+=get_offset(dreg); + raw_mov_l_Ri(d,i,offset); + unlock2(d); +} + +MIDFUNC(3,mov_w_Ri,(RR4 d, IMM i, IMM offset)) +{ + int dreg=d; + if (isconst(d)) { + COMPCALL(mov_w_mi)(live.state[d].val+offset,i); + return; + } + + CLOBBER_MOV; + d=readreg_offset(d,4); + offset+=get_offset(dreg); + raw_mov_w_Ri(d,i,offset); + unlock2(d); +} + +MIDFUNC(3,mov_b_Ri,(RR4 d, IMM i, IMM offset)) +{ + int dreg=d; + if (isconst(d)) { + COMPCALL(mov_b_mi)(live.state[d].val+offset,i); + return; + } + + CLOBBER_MOV; + d=readreg_offset(d,4); + offset+=get_offset(dreg); + raw_mov_b_Ri(d,i,offset); + unlock2(d); +} + +/* Warning! OFFSET is byte sized only! */ +MIDFUNC(3,mov_l_Rr,(RR4 d, RR4 s, IMM offset)) +{ + if (isconst(d)) { + COMPCALL(mov_l_mr)(live.state[d].val+offset,s); + return; + } + if (isconst(s)) { + COMPCALL(mov_l_Ri)(d,live.state[s].val,offset); + return; + } + + CLOBBER_MOV; + s=readreg(s,4); + d=readreg(d,4); + + raw_mov_l_Rr(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(3,mov_w_Rr,(RR4 d, RR2 s, IMM offset)) +{ + if (isconst(d)) { + COMPCALL(mov_w_mr)(live.state[d].val+offset,s); + return; + } + if (isconst(s)) { + COMPCALL(mov_w_Ri)(d,(uae_u16)live.state[s].val,offset); + return; + } + + CLOBBER_MOV; + s=readreg(s,2); + d=readreg(d,4); + raw_mov_w_Rr(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(3,mov_b_Rr,(RR4 d, RR1 s, IMM offset)) +{ + if (isconst(d)) { + COMPCALL(mov_b_mr)(live.state[d].val+offset,s); + return; + } + if (isconst(s)) { + COMPCALL(mov_b_Ri)(d,(uae_u8)live.state[s].val,offset); + return; + } + + CLOBBER_MOV; + s=readreg(s,1); + d=readreg(d,4); + raw_mov_b_Rr(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(3,lea_l_brr,(W4 d, RR4 s, IMM offset)) +{ + if (isconst(s)) { + COMPCALL(mov_l_ri)(d,live.state[s].val+offset); + return; + } +#if USE_OFFSET + if (d==s) { + add_offset(d,offset); + return; + } +#endif + CLOBBER_LEA; + s=readreg(s,4); + d=writereg(d,4); + raw_lea_l_brr(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(5,lea_l_brr_indexed,(W4 d, RR4 s, RR4 index, IMM factor, IMM offset)) +{ + if (!offset) { + COMPCALL(lea_l_rr_indexed)(d,s,index,factor); + return; + } + CLOBBER_LEA; + s=readreg(s,4); + index=readreg(index,4); + d=writereg(d,4); + + raw_lea_l_brr_indexed(d,s,index,factor,offset); + unlock2(d); + unlock2(index); + unlock2(s); +} + +MIDFUNC(4,lea_l_rr_indexed,(W4 d, RR4 s, RR4 index, IMM factor)) +{ + CLOBBER_LEA; + s=readreg(s,4); + index=readreg(index,4); + d=writereg(d,4); + + raw_lea_l_rr_indexed(d,s,index,factor); + unlock2(d); + unlock2(index); + unlock2(s); +} + +/* write d to the long at the address contained in s+offset */ +MIDFUNC(3,mov_l_bRr,(RR4 d, RR4 s, IMM offset)) +{ + int dreg=d; + if (isconst(d)) { + COMPCALL(mov_l_mr)(live.state[d].val+offset,s); + return; + } + + CLOBBER_MOV; + s=readreg(s,4); + d=readreg_offset(d,4); + offset+=get_offset(dreg); + + raw_mov_l_bRr(d,s,offset); + unlock2(d); + unlock2(s); +} + +/* write the word at the address contained in s+offset and store in d */ +MIDFUNC(3,mov_w_bRr,(RR4 d, RR2 s, IMM offset)) +{ + int dreg=d; + + if (isconst(d)) { + COMPCALL(mov_w_mr)(live.state[d].val+offset,s); + return; + } + + CLOBBER_MOV; + s=readreg(s,2); + d=readreg_offset(d,4); + offset+=get_offset(dreg); + raw_mov_w_bRr(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(3,mov_b_bRr,(RR4 d, RR1 s, IMM offset)) +{ + int dreg=d; + if (isconst(d)) { + COMPCALL(mov_b_mr)(live.state[d].val+offset,s); + return; + } + + CLOBBER_MOV; + s=readreg(s,1); + d=readreg_offset(d,4); + offset+=get_offset(dreg); + raw_mov_b_bRr(d,s,offset); + unlock2(d); + unlock2(s); +} + +MIDFUNC(1,mid_bswap_32,(RW4 r)) +{ + + if (isconst(r)) { + uae_u32 oldv=live.state[r].val; + live.state[r].val=reverse32(oldv); + return; + } + + CLOBBER_SW32; + r=rmw(r,4,4); + raw_bswap_32(r); + unlock2(r); +} + +MIDFUNC(1,mid_bswap_16,(RW2 r)) +{ + if (isconst(r)) { + uae_u32 oldv=live.state[r].val; + live.state[r].val=((oldv>>8)&0xff) | ((oldv<<8)&0xff00) | (oldv&0xffff0000); + return; + } + + CLOBBER_SW16; + r=rmw(r,2,2); + + raw_bswap_16(r); + unlock2(r); +} + + + +MIDFUNC(2,mov_l_rr,(W4 d, RR4 s)) +{ + int olds; + + if (d==s) { /* How pointless! */ + return; + } + if (isconst(s)) { + COMPCALL(mov_l_ri)(d,live.state[s].val); + return; + } + olds=s; + disassociate(d); + s=readreg_offset(s,4); + live.state[d].realreg=s; + live.state[d].realind=live.nat[s].nholds; + live.state[d].val=live.state[olds].val; + live.state[d].validsize=4; + live.state[d].dirtysize=4; + set_status(d,DIRTY); + + live.nat[s].holds[live.nat[s].nholds]=d; + live.nat[s].nholds++; + log_clobberreg(d); + jit_log2("Added %d to nreg %d(%d), now holds %d regs", d,s,live.state[d].realind,live.nat[s].nholds); + unlock2(s); +} + +MIDFUNC(2,mov_l_mr,(IMM d, RR4 s)) +{ + if (isconst(s)) { + COMPCALL(mov_l_mi)(d,live.state[s].val); + return; + } + CLOBBER_MOV; + s=readreg(s,4); + + raw_mov_l_mr(d,s); + unlock2(s); +} + + +MIDFUNC(2,mov_w_mr,(IMM d, RR2 s)) +{ + if (isconst(s)) { + COMPCALL(mov_w_mi)(d,(uae_u16)live.state[s].val); + return; + } + CLOBBER_MOV; + s=readreg(s,2); + + raw_mov_w_mr(d,s); + unlock2(s); +} + +MIDFUNC(2,mov_w_rm,(W2 d, IMM s)) +{ + CLOBBER_MOV; + d=writereg(d,2); + + raw_mov_w_rm(d,s); + unlock2(d); +} + +MIDFUNC(2,mov_b_mr,(IMM d, RR1 s)) +{ + if (isconst(s)) { + COMPCALL(mov_b_mi)(d,(uae_u8)live.state[s].val); + return; + } + + CLOBBER_MOV; + s=readreg(s,1); + + raw_mov_b_mr(d,s); + unlock2(s); +} + +MIDFUNC(2,mov_b_rm,(W1 d, IMM s)) +{ + CLOBBER_MOV; + d=writereg(d,1); + + raw_mov_b_rm(d,s); + unlock2(d); +} + +MIDFUNC(2,mov_l_ri,(W4 d, IMM s)) +{ + set_const(d,s); + return; +} + +MIDFUNC(2,mov_w_ri,(W2 d, IMM s)) +{ + CLOBBER_MOV; + d=writereg(d,2); + + raw_mov_w_ri(d,s); + unlock2(d); +} + +MIDFUNC(2,mov_b_ri,(W1 d, IMM s)) +{ + CLOBBER_MOV; + d=writereg(d,1); + + raw_mov_b_ri(d,s); + unlock2(d); +} + +MIDFUNC(2,add_l_mi,(IMM d, IMM s)) +{ + CLOBBER_ADD; + raw_add_l_mi(d,s); +} + +MIDFUNC(2,add_w_mi,(IMM d, IMM s)) +{ + CLOBBER_ADD; + raw_add_w_mi(d,s); +} + +MIDFUNC(2,add_b_mi,(IMM d, IMM s)) +{ + CLOBBER_ADD; + raw_add_b_mi(d,s); +} + +MIDFUNC(2,test_l_ri,(RR4 d, IMM i)) +{ + CLOBBER_TEST; + d=readreg(d,4); + + raw_test_l_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,test_l_rr,(RR4 d, RR4 s)) +{ + CLOBBER_TEST; + d=readreg(d,4); + s=readreg(s,4); + + raw_test_l_rr(d,s);; + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,test_w_rr,(RR2 d, RR2 s)) +{ + CLOBBER_TEST; + d=readreg(d,2); + s=readreg(s,2); + + raw_test_w_rr(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,test_b_rr,(RR1 d, RR1 s)) +{ + CLOBBER_TEST; + d=readreg(d,1); + s=readreg(s,1); + + raw_test_b_rr(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,test_b_mi,(IMM d, IMM s)) +{ + CLOBBER_TEST; + raw_test_b_mi(d,s); +} + +MIDFUNC(2,and_l_ri,(RW4 d, IMM i)) +{ + if (isconst(d) && !needflags) { + live.state[d].val &= i; + return; + } + + CLOBBER_AND; + d=rmw(d,4,4); + + raw_and_l_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,and_l,(RW4 d, RR4 s)) +{ + CLOBBER_AND; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_and_l(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,and_w,(RW2 d, RR2 s)) +{ + CLOBBER_AND; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_and_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,and_b,(RW1 d, RR1 s)) +{ + CLOBBER_AND; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_and_b(d,s); + unlock2(d); + unlock2(s); +} + +// gb-- used for making an fpcr value in compemu_fpp.cpp +MIDFUNC(2,or_l_rm,(RW4 d, IMM s)) +{ + CLOBBER_OR; + d=rmw(d,4,4); + + raw_or_l_rm(d,s); + unlock2(d); +} + +MIDFUNC(2,or_l_ri,(RW4 d, IMM i)) +{ + if (isconst(d) && !needflags) { + live.state[d].val|=i; + return; + } + CLOBBER_OR; + d=rmw(d,4,4); + + raw_or_l_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,or_l,(RW4 d, RR4 s)) +{ + if (isconst(d) && isconst(s) && !needflags) { + live.state[d].val|=live.state[s].val; + return; + } + CLOBBER_OR; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_or_l(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,or_w,(RW2 d, RR2 s)) +{ + CLOBBER_OR; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_or_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,or_b,(RW1 d, RR1 s)) +{ + CLOBBER_OR; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_or_b(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,adc_l,(RW4 d, RR4 s)) +{ + CLOBBER_ADC; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_adc_l(d,s); + + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,adc_w,(RW2 d, RR2 s)) +{ + CLOBBER_ADC; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_adc_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,adc_b,(RW1 d, RR1 s)) +{ + CLOBBER_ADC; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_adc_b(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,add_l,(RW4 d, RR4 s)) +{ + if (isconst(s)) { + COMPCALL(add_l_ri)(d,live.state[s].val); + return; + } + + CLOBBER_ADD; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_add_l(d,s); + + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,add_w,(RW2 d, RR2 s)) +{ + if (isconst(s)) { + COMPCALL(add_w_ri)(d,(uae_u16)live.state[s].val); + return; + } + + CLOBBER_ADD; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_add_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,add_b,(RW1 d, RR1 s)) +{ + if (isconst(s)) { + COMPCALL(add_b_ri)(d,(uae_u8)live.state[s].val); + return; + } + + CLOBBER_ADD; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_add_b(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,sub_l_ri,(RW4 d, IMM i)) +{ + if (!i && !needflags) + return; + if (isconst(d) && !needflags) { + live.state[d].val-=i; + return; + } +#if USE_OFFSET + if (!needflags) { + add_offset(d,-i); + return; + } +#endif + + CLOBBER_SUB; + d=rmw(d,4,4); + + raw_sub_l_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,sub_w_ri,(RW2 d, IMM i)) +{ + if (!i && !needflags) + return; + + CLOBBER_SUB; + d=rmw(d,2,2); + + raw_sub_w_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,sub_b_ri,(RW1 d, IMM i)) +{ + if (!i && !needflags) + return; + + CLOBBER_SUB; + d=rmw(d,1,1); + + raw_sub_b_ri(d,i); + + unlock2(d); +} + +MIDFUNC(2,add_l_ri,(RW4 d, IMM i)) +{ + if (!i && !needflags) + return; + if (isconst(d) && !needflags) { + live.state[d].val+=i; + return; + } +#if USE_OFFSET + if (!needflags) { + add_offset(d,i); + return; + } +#endif + CLOBBER_ADD; + d=rmw(d,4,4); + raw_add_l_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,add_w_ri,(RW2 d, IMM i)) +{ + if (!i && !needflags) + return; + + CLOBBER_ADD; + d=rmw(d,2,2); + + raw_add_w_ri(d,i); + unlock2(d); +} + +MIDFUNC(2,add_b_ri,(RW1 d, IMM i)) +{ + if (!i && !needflags) + return; + + CLOBBER_ADD; + d=rmw(d,1,1); + + raw_add_b_ri(d,i); + + unlock2(d); +} + +MIDFUNC(2,sbb_l,(RW4 d, RR4 s)) +{ + CLOBBER_SBB; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_sbb_l(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,sbb_w,(RW2 d, RR2 s)) +{ + CLOBBER_SBB; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_sbb_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,sbb_b,(RW1 d, RR1 s)) +{ + CLOBBER_SBB; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_sbb_b(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,sub_l,(RW4 d, RR4 s)) +{ + if (isconst(s)) { + COMPCALL(sub_l_ri)(d,live.state[s].val); + return; + } + + CLOBBER_SUB; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_sub_l(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,sub_w,(RW2 d, RR2 s)) +{ + if (isconst(s)) { + COMPCALL(sub_w_ri)(d,(uae_u16)live.state[s].val); + return; + } + + CLOBBER_SUB; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_sub_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,sub_b,(RW1 d, RR1 s)) +{ + if (isconst(s)) { + COMPCALL(sub_b_ri)(d,(uae_u8)live.state[s].val); + return; + } + + CLOBBER_SUB; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_sub_b(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,cmp_l,(RR4 d, RR4 s)) +{ + CLOBBER_CMP; + s=readreg(s,4); + d=readreg(d,4); + + raw_cmp_l(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,cmp_l_ri,(RR4 r, IMM i)) +{ + CLOBBER_CMP; + r=readreg(r,4); + + raw_cmp_l_ri(r,i); + unlock2(r); +} + +MIDFUNC(2,cmp_w,(RR2 d, RR2 s)) +{ + CLOBBER_CMP; + s=readreg(s,2); + d=readreg(d,2); + + raw_cmp_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,cmp_b,(RR1 d, RR1 s)) +{ + CLOBBER_CMP; + s=readreg(s,1); + d=readreg(d,1); + + raw_cmp_b(d,s); + unlock2(d); + unlock2(s); +} + + +MIDFUNC(2,xor_l,(RW4 d, RR4 s)) +{ + CLOBBER_XOR; + s=readreg(s,4); + d=rmw(d,4,4); + + raw_xor_l(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,xor_w,(RW2 d, RR2 s)) +{ + CLOBBER_XOR; + s=readreg(s,2); + d=rmw(d,2,2); + + raw_xor_w(d,s); + unlock2(d); + unlock2(s); +} + +MIDFUNC(2,xor_b,(RW1 d, RR1 s)) +{ + CLOBBER_XOR; + s=readreg(s,1); + d=rmw(d,1,1); + + raw_xor_b(d,s); + unlock2(d); + unlock2(s); +} + +#ifdef UAE +MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize)) +{ + clobber_flags(); + remove_all_offsets(); + if (osize==4) { + if (out1!=in1 && out1!=r) { + COMPCALL(forget_about)(out1); + } + } + else { + tomem_c(out1); + } + + in1=readreg_specific(in1,isize,REG_PAR1); + r=readreg(r,4); + prepare_for_call_1(); /* This should ensure that there won't be + any need for swapping nregs in prepare_for_call_2 + */ +#if USE_NORMAL_CALLING_CONVENTION + raw_push_l_r(in1); +#endif + unlock2(in1); + unlock2(r); + + prepare_for_call_2(); + raw_dec_sp(STACK_SHADOW_SPACE); + raw_call_r(r); + raw_inc_sp(STACK_SHADOW_SPACE); + +#if USE_NORMAL_CALLING_CONVENTION + raw_inc_sp(4); +#endif + + + live.nat[REG_RESULT].holds[0]=out1; + live.nat[REG_RESULT].nholds=1; + live.nat[REG_RESULT].touched=touchcnt++; + + live.state[out1].realreg=REG_RESULT; + live.state[out1].realind=0; + live.state[out1].val=0; + live.state[out1].validsize=osize; + live.state[out1].dirtysize=osize; + set_status(out1,DIRTY); +} +#endif + +#if defined(UAE) +MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2)) +{ + clobber_flags(); + remove_all_offsets(); + in1=readreg_specific(in1,isize1,REG_PAR1); + in2=readreg_specific(in2,isize2,REG_PAR2); + r=readreg(r,4); + prepare_for_call_1(); /* This should ensure that there won't be + any need for swapping nregs in prepare_for_call_2 + */ +#if USE_NORMAL_CALLING_CONVENTION + raw_push_l_r(in2); + raw_push_l_r(in1); +#endif + unlock2(r); + unlock2(in1); + unlock2(in2); + prepare_for_call_2(); + raw_dec_sp(STACK_SHADOW_SPACE); + raw_call_r(r); + raw_inc_sp(STACK_SHADOW_SPACE); +#if USE_NORMAL_CALLING_CONVENTION + raw_inc_sp(8); +#endif +} +#endif + +/* forget_about() takes a mid-layer register */ +MIDFUNC(1,forget_about,(W4 r)) +{ + if (isinreg(r)) + disassociate(r); + live.state[r].val=0; + set_status(r,UNDEF); +} + +MIDFUNC(0,nop,(void)) +{ + raw_emit_nop(); +} + +MIDFUNC(1,f_forget_about,(FW r)) +{ + if (f_isinreg(r)) + f_disassociate(r); + live.fate[r].status=UNDEF; +} + +MIDFUNC(1,fmov_pi,(FW r)) +{ + r=f_writereg(r); + raw_fmov_pi(r); + f_unlock(r); +} + +MIDFUNC(1,fmov_log10_2,(FW r)) +{ + r=f_writereg(r); + raw_fmov_log10_2(r); + f_unlock(r); +} + +MIDFUNC(1,fmov_log2_e,(FW r)) +{ + r=f_writereg(r); + raw_fmov_log2_e(r); + f_unlock(r); +} + +MIDFUNC(1,fmov_loge_2,(FW r)) +{ + r=f_writereg(r); + raw_fmov_loge_2(r); + f_unlock(r); +} + +MIDFUNC(1,fmov_1,(FW r)) +{ + r=f_writereg(r); + raw_fmov_1(r); + f_unlock(r); +} + +MIDFUNC(1,fmov_0,(FW r)) +{ + r=f_writereg(r); + raw_fmov_0(r); + f_unlock(r); +} + +MIDFUNC(2,fmov_rm,(FW r, MEMPTRR m)) +{ + r=f_writereg(r); + raw_fmov_rm(r,m); + f_unlock(r); +} + +MIDFUNC(2,fmovi_rm,(FW r, MEMPTRR m)) +{ + r=f_writereg(r); + raw_fmovi_rm(r,m); + f_unlock(r); +} + +MIDFUNC(2,fmovi_mr,(MEMPTRW m, FR r)) +{ + r=f_readreg(r); + raw_fmovi_mr(m,r); + f_unlock(r); +} + +MIDFUNC(3,fmovi_mrb,(MEMPTRW m, FR r, double *bounds)) +{ + r=f_readreg(r); + raw_fmovi_mrb(m,r,bounds); + f_unlock(r); +} + +MIDFUNC(2,fmovs_rm,(FW r, MEMPTRR m)) +{ + r=f_writereg(r); + raw_fmovs_rm(r,m); + f_unlock(r); +} + +MIDFUNC(2,fmovs_mr,(MEMPTRW m, FR r)) +{ + r=f_readreg(r); + raw_fmovs_mr(m,r); + f_unlock(r); +} + +MIDFUNC(1,fcuts_r,(FRW r)) +{ + r=f_rmw(r); + raw_fcuts_r(r); + f_unlock(r); +} + +MIDFUNC(1,fcut_r,(FRW r)) +{ + r=f_rmw(r); + raw_fcut_r(r); + f_unlock(r); +} + +MIDFUNC(2,fmov_ext_mr,(MEMPTRW m, FR r)) +{ + r=f_readreg(r); + raw_fmov_ext_mr(m,r); + f_unlock(r); +} + +MIDFUNC(2,fmov_mr,(MEMPTRW m, FR r)) +{ + r=f_readreg(r); + raw_fmov_mr(m,r); + f_unlock(r); +} + +MIDFUNC(2,fmov_ext_rm,(FW r, MEMPTRR m)) +{ + r=f_writereg(r); + raw_fmov_ext_rm(r,m); + f_unlock(r); +} + +MIDFUNC(2,fmov_rr,(FW d, FR s)) +{ + if (d==s) { /* How pointless! */ + return; + } +#if USE_F_ALIAS + f_disassociate(d); + s=f_readreg(s); + live.fate[d].realreg=s; + live.fate[d].realind=live.fat[s].nholds; + live.fate[d].status=DIRTY; + live.fat[s].holds[live.fat[s].nholds]=d; + live.fat[s].nholds++; + f_unlock(s); +#else + s=f_readreg(s); + d=f_writereg(d); + raw_fmov_rr(d,s); + f_unlock(s); + f_unlock(d); +#endif +} + +MIDFUNC(2,fldcw_m_indexed,(RR4 index, IMM base)) +{ + index=readreg(index,4); + + raw_fldcw_m_indexed(index,base); + unlock2(index); +} + +MIDFUNC(1,ftst_r,(FR r)) +{ + r=f_readreg(r); + raw_ftst_r(r); + f_unlock(r); +} + +MIDFUNC(0,dont_care_fflags,(void)) +{ + f_disassociate(FP_RESULT); +} + +MIDFUNC(2,fsqrt_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fsqrt_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fabs_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fabs_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fgetexp_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fgetexp_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fgetman_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fgetman_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fsin_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fsin_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fcos_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fcos_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,ftan_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_ftan_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) +{ + s=f_readreg(s); /* s for source */ + d=f_writereg(d); /* d for sine */ + c=f_writereg(c); /* c for cosine */ + raw_fsincos_rr(d,c,s); + f_unlock(s); + f_unlock(d); + f_unlock(c); +} + +MIDFUNC(2,fscale_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_fscale_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,ftwotox_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_ftwotox_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fetox_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fetox_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,frndint_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_frndint_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fetoxM1_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fetoxM1_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,ftentox_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_ftentox_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,flog2_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_flog2_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,flogN_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_flogN_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,flogNP1_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_flogNP1_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,flog10_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_flog10_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fasin_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fasin_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,facos_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_facos_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fatan_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fatan_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fatanh_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fatanh_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fsinh_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fsinh_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fcosh_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fcosh_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,ftanh_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_ftanh_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fneg_rr,(FW d, FR s)) +{ + s=f_readreg(s); + d=f_writereg(d); + raw_fneg_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fadd_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_fadd_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fsub_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_fsub_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fcmp_rr,(FR d, FR s)) +{ + d=f_readreg(d); + s=f_readreg(s); + raw_fcmp_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fdiv_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_fdiv_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,frem_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_frem_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,frem1_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_frem1_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +MIDFUNC(2,fmul_rr,(FRW d, FR s)) +{ + s=f_readreg(s); + d=f_rmw(d); + raw_fmul_rr(d,s); + f_unlock(s); + f_unlock(d); +} + +#ifdef __GNUC__ + +static inline void mfence(void) +{ +#ifdef CPU_i386 + if (!cpuinfo.x86_has_xmm2) + __asm__ __volatile__("lock; addl $0,0(%%esp)":::"memory"); + else +#endif + __asm__ __volatile__("mfence":::"memory"); +} + +static inline void clflush(volatile void *__p) +{ + __asm__ __volatile__("clflush %0" : "+m" (*(volatile char *)__p)); +} + +static inline void flush_cpu_icache(void *start, void *stop) +{ + mfence(); + if (cpuinfo.x86_clflush_size != 0) + { + volatile char *vaddr = (volatile char *)(((uintptr)start / cpuinfo.x86_clflush_size) * cpuinfo.x86_clflush_size); + volatile char *vend = (volatile char *)((((uintptr)stop + cpuinfo.x86_clflush_size - 1) / cpuinfo.x86_clflush_size) * cpuinfo.x86_clflush_size); + while (vaddr < vend) + { + clflush(vaddr); + vaddr += cpuinfo.x86_clflush_size; + } + } + mfence(); +} + +#else + +static inline void flush_cpu_icache(void *start, void *stop) +{ + UNUSED(start); + UNUSED(stop); +} + +#endif + +static inline void write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a) { + uintptr rel = (uintptr) a - ((uintptr) jmpaddr + 4); + *(jmpaddr) = (uae_u32) rel; + flush_cpu_icache((void *) jmpaddr, (void *) &jmpaddr[1]); +} + +static inline void emit_jmp_target(uae_u32 a) { + emit_long(a-((uintptr)target+4)); +} + + +void compemu_bkpt(void) +{ + emit_byte(0xcc); +} diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu_midfunc_x86.h b/BasiliskII/src/uae_cpu_2021/compiler/compemu_midfunc_x86.h new file mode 100644 index 000000000..82b75415b --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu_midfunc_x86.h @@ -0,0 +1,254 @@ +/* + * compiler/compemu_midfunc_x86.h - Native MIDFUNCS for IA-32 and AMD64 + * + * Copyright (c) 2014 Jens Heitmann of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * + * Adaptation for Basilisk II and improvements, copyright 2000-2002 + * Gwenole Beauchesne + * + * 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 + * + * Note: + * File is included by compemu.h + * + */ + +DECLARE_MIDFUNC(bt_l_ri(RR4 r, IMM i)); +DECLARE_MIDFUNC(bt_l_rr(RR4 r, RR4 b)); +DECLARE_MIDFUNC(btc_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(btc_l_rr(RW4 r, RR4 b)); +DECLARE_MIDFUNC(bts_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(bts_l_rr(RW4 r, RR4 b)); +DECLARE_MIDFUNC(btr_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(btr_l_rr(RW4 r, RR4 b)); +DECLARE_MIDFUNC(mov_l_rm(W4 d, IMM s)); +DECLARE_MIDFUNC(call_r(RR4 r)); +DECLARE_MIDFUNC(sub_l_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(mov_l_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(mov_w_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(mov_b_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(rol_b_ri(RW1 r, IMM i)); +DECLARE_MIDFUNC(rol_w_ri(RW2 r, IMM i)); +DECLARE_MIDFUNC(rol_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(rol_l_rr(RW4 d, RR1 r)); +DECLARE_MIDFUNC(rol_w_rr(RW2 d, RR1 r)); +DECLARE_MIDFUNC(rol_b_rr(RW1 d, RR1 r)); +DECLARE_MIDFUNC(shll_l_rr(RW4 d, RR1 r)); +DECLARE_MIDFUNC(shll_w_rr(RW2 d, RR1 r)); +DECLARE_MIDFUNC(shll_b_rr(RW1 d, RR1 r)); +DECLARE_MIDFUNC(ror_b_ri(RR1 r, IMM i)); +DECLARE_MIDFUNC(ror_w_ri(RR2 r, IMM i)); +DECLARE_MIDFUNC(ror_l_ri(RR4 r, IMM i)); +DECLARE_MIDFUNC(ror_l_rr(RR4 d, RR1 r)); +DECLARE_MIDFUNC(ror_w_rr(RR2 d, RR1 r)); +DECLARE_MIDFUNC(ror_b_rr(RR1 d, RR1 r)); +DECLARE_MIDFUNC(shrl_l_rr(RW4 d, RR1 r)); +DECLARE_MIDFUNC(shrl_w_rr(RW2 d, RR1 r)); +DECLARE_MIDFUNC(shrl_b_rr(RW1 d, RR1 r)); +DECLARE_MIDFUNC(shra_l_rr(RW4 d, RR1 r)); +DECLARE_MIDFUNC(shra_w_rr(RW2 d, RR1 r)); +DECLARE_MIDFUNC(shra_b_rr(RW1 d, RR1 r)); +DECLARE_MIDFUNC(shll_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(shll_w_ri(RW2 r, IMM i)); +DECLARE_MIDFUNC(shll_b_ri(RW1 r, IMM i)); +DECLARE_MIDFUNC(shrl_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(shrl_w_ri(RW2 r, IMM i)); +DECLARE_MIDFUNC(shrl_b_ri(RW1 r, IMM i)); +DECLARE_MIDFUNC(shra_l_ri(RW4 r, IMM i)); +DECLARE_MIDFUNC(shra_w_ri(RW2 r, IMM i)); +DECLARE_MIDFUNC(shra_b_ri(RW1 r, IMM i)); +DECLARE_MIDFUNC(setcc(W1 d, IMM cc)); +DECLARE_MIDFUNC(setcc_m(IMM d, IMM cc)); +DECLARE_MIDFUNC(cmov_l_rr(RW4 d, RR4 s, IMM cc)); +DECLARE_MIDFUNC(cmov_l_rm(RW4 d, IMM s, IMM cc)); +DECLARE_MIDFUNC(bsf_l_rr(W4 d, RR4 s)); +DECLARE_MIDFUNC(pop_m(IMM d)); +DECLARE_MIDFUNC(push_m(IMM d)); +DECLARE_MIDFUNC(pop_l(W4 d)); +DECLARE_MIDFUNC(push_l_i(IMM i)); +DECLARE_MIDFUNC(push_l(RR4 s)); +DECLARE_MIDFUNC(clear_16(RW4 r)); +DECLARE_MIDFUNC(clear_8(RW4 r)); +DECLARE_MIDFUNC(sign_extend_32_rr(W4 d, RR2 s)); +DECLARE_MIDFUNC(sign_extend_16_rr(W4 d, RR2 s)); +DECLARE_MIDFUNC(sign_extend_8_rr(W4 d, RR1 s)); +DECLARE_MIDFUNC(zero_extend_16_rr(W4 d, RR2 s)); +DECLARE_MIDFUNC(zero_extend_8_rr(W4 d, RR1 s)); +DECLARE_MIDFUNC(imul_64_32(RW4 d, RW4 s)); +DECLARE_MIDFUNC(mul_64_32(RW4 d, RW4 s)); +DECLARE_MIDFUNC(simulate_bsf(W4 tmp, RW4 s)); +DECLARE_MIDFUNC(imul_32_32(RW4 d, RR4 s)); +DECLARE_MIDFUNC(mul_32_32(RW4 d, RR4 s)); +DECLARE_MIDFUNC(mov_b_rr(W1 d, RR1 s)); +DECLARE_MIDFUNC(mov_w_rr(W2 d, RR2 s)); +DECLARE_MIDFUNC(mov_l_rrm_indexed(W4 d,RR4 baser, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_w_rrm_indexed(W2 d, RR4 baser, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_b_rrm_indexed(W1 d, RR4 baser, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_l_mrr_indexed(RR4 baser, RR4 index, IMM factor, RR4 s)); +DECLARE_MIDFUNC(mov_w_mrr_indexed(RR4 baser, RR4 index, IMM factor, RR2 s)); +DECLARE_MIDFUNC(mov_b_mrr_indexed(RR4 baser, RR4 index, IMM factor, RR1 s)); +DECLARE_MIDFUNC(mov_l_bmrr_indexed(IMM base, RR4 baser, RR4 index, IMM factor, RR4 s)); +DECLARE_MIDFUNC(mov_w_bmrr_indexed(IMM base, RR4 baser, RR4 index, IMM factor, RR2 s)); +DECLARE_MIDFUNC(mov_b_bmrr_indexed(IMM base, RR4 baser, RR4 index, IMM factor, RR1 s)); +DECLARE_MIDFUNC(mov_l_brrm_indexed(W4 d, IMM base, RR4 baser, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_w_brrm_indexed(W2 d, IMM base, RR4 baser, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_b_brrm_indexed(W1 d, IMM base, RR4 baser, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_l_rm_indexed(W4 d, IMM base, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_l_rR(W4 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_w_rR(W2 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_b_rR(W1 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_l_brR(W4 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_w_brR(W2 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_b_brR(W1 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_l_Ri(RR4 d, IMM i, IMM offset)); +DECLARE_MIDFUNC(mov_w_Ri(RR4 d, IMM i, IMM offset)); +DECLARE_MIDFUNC(mov_b_Ri(RR4 d, IMM i, IMM offset)); +DECLARE_MIDFUNC(mov_l_Rr(RR4 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_w_Rr(RR4 d, RR2 s, IMM offset)); +DECLARE_MIDFUNC(mov_b_Rr(RR4 d, RR1 s, IMM offset)); +DECLARE_MIDFUNC(lea_l_brr(W4 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(lea_l_brr_indexed(W4 d, RR4 s, RR4 index, IMM factor, IMM offset)); +DECLARE_MIDFUNC(lea_l_rr_indexed(W4 d, RR4 s, RR4 index, IMM factor)); +DECLARE_MIDFUNC(mov_l_bRr(RR4 d, RR4 s, IMM offset)); +DECLARE_MIDFUNC(mov_w_bRr(RR4 d, RR2 s, IMM offset)); +DECLARE_MIDFUNC(mov_b_bRr(RR4 d, RR1 s, IMM offset)); +DECLARE_MIDFUNC(mid_bswap_32(RW4 r)); +DECLARE_MIDFUNC(mid_bswap_16(RW2 r)); +DECLARE_MIDFUNC(mov_l_rr(W4 d, RR4 s)); +DECLARE_MIDFUNC(mov_l_mr(IMM d, RR4 s)); +DECLARE_MIDFUNC(mov_w_mr(IMM d, RR2 s)); +DECLARE_MIDFUNC(mov_w_rm(W2 d, IMM s)); +DECLARE_MIDFUNC(mov_b_mr(IMM d, RR1 s)); +DECLARE_MIDFUNC(mov_b_rm(W1 d, IMM s)); +DECLARE_MIDFUNC(mov_l_ri(W4 d, IMM s)); +DECLARE_MIDFUNC(mov_w_ri(W2 d, IMM s)); +DECLARE_MIDFUNC(mov_b_ri(W1 d, IMM s)); +DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(test_l_ri(RR4 d, IMM i)); +DECLARE_MIDFUNC(test_l_rr(RR4 d, RR4 s)); +DECLARE_MIDFUNC(test_w_rr(RR2 d, RR2 s)); +DECLARE_MIDFUNC(test_b_rr(RR1 d, RR1 s)); +DECLARE_MIDFUNC(test_b_mi(IMM d, IMM s)); +DECLARE_MIDFUNC(and_l_ri(RW4 d, IMM i)); +DECLARE_MIDFUNC(and_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(and_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(and_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(or_l_rm(RW4 d, IMM s)); +DECLARE_MIDFUNC(or_l_ri(RW4 d, IMM i)); +DECLARE_MIDFUNC(or_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(or_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(or_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(adc_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(adc_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(adc_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(add_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(add_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(add_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(sub_l_ri(RW4 d, IMM i)); +DECLARE_MIDFUNC(sub_w_ri(RW2 d, IMM i)); +DECLARE_MIDFUNC(sub_b_ri(RW1 d, IMM i)); +DECLARE_MIDFUNC(add_l_ri(RW4 d, IMM i)); +DECLARE_MIDFUNC(add_w_ri(RW2 d, IMM i)); +DECLARE_MIDFUNC(add_b_ri(RW1 d, IMM i)); +DECLARE_MIDFUNC(sbb_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(sbb_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(sbb_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(sub_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(sub_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(sub_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(cmp_l(RR4 d, RR4 s)); +DECLARE_MIDFUNC(cmp_l_ri(RR4 r, IMM i)); +DECLARE_MIDFUNC(cmp_w(RR2 d, RR2 s)); +DECLARE_MIDFUNC(cmp_b(RR1 d, RR1 s)); +DECLARE_MIDFUNC(xor_l(RW4 d, RR4 s)); +DECLARE_MIDFUNC(xor_w(RW2 d, RR2 s)); +DECLARE_MIDFUNC(xor_b(RW1 d, RR1 s)); +DECLARE_MIDFUNC(live_flags(void)); +DECLARE_MIDFUNC(dont_care_flags(void)); +DECLARE_MIDFUNC(duplicate_carry(void)); +DECLARE_MIDFUNC(setcc_for_cntzero(RR4 d, RR4 data, int size)); +DECLARE_MIDFUNC(restore_carry(void)); +DECLARE_MIDFUNC(start_needflags(void)); +DECLARE_MIDFUNC(end_needflags(void)); +DECLARE_MIDFUNC(make_flags_live(void)); +DECLARE_MIDFUNC(call_r_11(RR4 r, W4 out1, RR4 in1, IMM osize, IMM isize)); +DECLARE_MIDFUNC(call_r_02(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2)); +DECLARE_MIDFUNC(forget_about(W4 r)); +DECLARE_MIDFUNC(nop(void)); + +DECLARE_MIDFUNC(f_forget_about(FW r)); +DECLARE_MIDFUNC(fmov_pi(FW r)); +DECLARE_MIDFUNC(fmov_log10_2(FW r)); +DECLARE_MIDFUNC(fmov_log2_e(FW r)); +DECLARE_MIDFUNC(fmov_loge_2(FW r)); +DECLARE_MIDFUNC(fmov_1(FW r)); +DECLARE_MIDFUNC(fmov_0(FW r)); +DECLARE_MIDFUNC(fmov_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmov_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fmovi_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmovi_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fmovi_mrb(MEMPTRW m, FR r, double *bounds)); +DECLARE_MIDFUNC(fmovs_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmovs_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fcuts_r(FRW r)); +DECLARE_MIDFUNC(fcut_r(FRW r)); +DECLARE_MIDFUNC(fmov_ext_mr(MEMPTRW m, FR r)); +DECLARE_MIDFUNC(fmov_ext_rm(FW r, MEMPTRR m)); +DECLARE_MIDFUNC(fmov_rr(FW d, FR s)); +DECLARE_MIDFUNC(fldcw_m_indexed(RR4 index, IMM base)); +DECLARE_MIDFUNC(ftst_r(FR r)); +DECLARE_MIDFUNC(dont_care_fflags(void)); +DECLARE_MIDFUNC(fsqrt_rr(FW d, FR s)); +DECLARE_MIDFUNC(fabs_rr(FW d, FR s)); +DECLARE_MIDFUNC(frndint_rr(FW d, FR s)); +DECLARE_MIDFUNC(fgetexp_rr(FW d, FR s)); +DECLARE_MIDFUNC(fgetman_rr(FW d, FR s)); +DECLARE_MIDFUNC(fsin_rr(FW d, FR s)); +DECLARE_MIDFUNC(fcos_rr(FW d, FR s)); +DECLARE_MIDFUNC(ftan_rr(FW d, FR s)); +DECLARE_MIDFUNC(fsincos_rr(FW d, FW c, FR s)); +DECLARE_MIDFUNC(fscale_rr(FRW d, FR s)); +DECLARE_MIDFUNC(ftwotox_rr(FW d, FR s)); +DECLARE_MIDFUNC(fetox_rr(FW d, FR s)); +DECLARE_MIDFUNC(fetoxM1_rr(FW d, FR s)); +DECLARE_MIDFUNC(ftentox_rr(FW d, FR s)); +DECLARE_MIDFUNC(flog2_rr(FW d, FR s)); +DECLARE_MIDFUNC(flogN_rr(FW d, FR s)); +DECLARE_MIDFUNC(flogNP1_rr(FW d, FR s)); +DECLARE_MIDFUNC(flog10_rr(FW d, FR s)); +DECLARE_MIDFUNC(fasin_rr(FW d, FR s)); +DECLARE_MIDFUNC(facos_rr(FW d, FR s)); +DECLARE_MIDFUNC(fatan_rr(FW d, FR s)); +DECLARE_MIDFUNC(fatanh_rr(FW d, FR s)); +DECLARE_MIDFUNC(fsinh_rr(FW d, FR s)); +DECLARE_MIDFUNC(fcosh_rr(FW d, FR s)); +DECLARE_MIDFUNC(ftanh_rr(FW d, FR s)); +DECLARE_MIDFUNC(fneg_rr(FW d, FR s)); +DECLARE_MIDFUNC(fadd_rr(FRW d, FR s)); +DECLARE_MIDFUNC(fsub_rr(FRW d, FR s)); +DECLARE_MIDFUNC(fmul_rr(FRW d, FR s)); +DECLARE_MIDFUNC(frem_rr(FRW d, FR s)); +DECLARE_MIDFUNC(frem1_rr(FRW d, FR s)); +DECLARE_MIDFUNC(fdiv_rr(FRW d, FR s)); +DECLARE_MIDFUNC(fcmp_rr(FR d, FR s)); +DECLARE_MIDFUNC(fflags_into_flags(W2 tmp)); diff --git a/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp b/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp new file mode 100644 index 000000000..c44fd730c --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/compemu_support.cpp @@ -0,0 +1,5492 @@ +/* + * compiler/compemu_support.cpp - Core dynamic translation engine + * + * Copyright (c) 2001-2009 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 / ARM + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef USE_JIT + +#ifdef UAE + +#define writemem_special writemem +#define readmem_special readmem + +#else +//#if !FIXED_ADDRESSING +//#error "Only Fixed Addressing is supported with the JIT Compiler" +//#endif + +#if defined(X86_ASSEMBLY) && !SAHF_SETO_PROFITABLE +#error "Only [LS]AHF scheme to [gs]et flags is supported with the JIT Compiler" +#endif + +/* NOTE: support for AMD64 assumes translation cache and other code + * buffers are allocated into a 32-bit address space because (i) B2/JIT + * code is not 64-bit clean and (ii) it's faster to resolve branches + * that way. + */ +#if !defined(CPU_i386) && !defined(CPU_x86_64) && !defined(CPU_arm) +#error "Only IA-32, X86-64 and ARM v6 targets are supported with the JIT Compiler" +#endif +#endif + +#define USE_MATCH 0 + +/* kludge for Brian, so he can compile under MSVC++ */ +#define USE_NORMAL_CALLING_CONVENTION 0 + +// #include "sysconfig.h" +#include "sysdeps.h" + +#ifdef JIT + +#ifdef UAE +#include "options.h" +#include "events.h" +#include "uae/memory.h" +#include "custom.h" +#else +#include "cpu_emulation.h" +#include "main.h" +#include "prefs.h" +#include "vm_alloc.h" + +#include "m68k.h" +#include "memory.h" +#include "readcpu.h" +#endif +#include "newcpu.h" +#include "comptbl.h" +#ifdef UAE +#include "compemu.h" +#ifdef FSUAE +#include "codegen_udis86.h" +#endif +#else +#include "compiler/compemu.h" +#include "fpu/fpu.h" +#include "fpu/flags.h" +// #include "parameters.h" +static void build_comp(void); +#endif +// #include "verify.h" + +// #define jit_log(format, ...) \ +// uae_log("JIT: " format "\n", ##__VA_ARGS__); +#define D2 D + +#ifdef UAE +#ifdef FSUAE +#include "uae/fs.h" +#endif +#include "uae/log.h" + +#if defined(__pie__) || defined (__PIE__) +#error Position-independent code (PIE) cannot be used with JIT +#endif + +#include "uae/vm.h" +#define VM_PAGE_READ UAE_VM_READ +#define VM_PAGE_WRITE UAE_VM_WRITE +#define VM_PAGE_EXECUTE UAE_VM_EXECUTE +#define VM_MAP_FAILED UAE_VM_ALLOC_FAILED +#define VM_MAP_DEFAULT 1 +#define VM_MAP_32BIT 1 +#define vm_protect(address, size, protect) uae_vm_protect(address, size, protect) +#define vm_release(address, size) uae_vm_free(address, size) + +static inline void *vm_acquire(size_t size, int options = VM_MAP_DEFAULT) +{ + assert(options == (VM_MAP_DEFAULT | VM_MAP_32BIT)); + return uae_vm_alloc(size, UAE_VM_32BIT, UAE_VM_READ_WRITE); +} + +#define UNUSED(x) +#include "uae.h" +#include "uae/log.h" +#define jit_log(format, ...) \ + uae_log("JIT: " format "\n", ##__VA_ARGS__); +#define jit_log2(format, ...) + +#define MEMBaseDiff uae_p32(NATMEM_OFFSET) + +#ifdef NATMEM_OFFSET +#define FIXED_ADDRESSING 1 +#endif + +#define SAHF_SETO_PROFITABLE + +// %%% BRIAN KING WAS HERE %%% +extern bool canbang; + +#include "compemu_prefs.cpp" + +#define uint32 uae_u32 +#define uint8 uae_u8 + +static inline int distrust_check(int value) +{ +#ifdef JIT_ALWAYS_DISTRUST + return 1; +#else + int distrust = value; +#ifdef FSUAE + switch (value) { + case 0: distrust = 0; break; + case 1: distrust = 1; break; + case 2: distrust = ((start_pc & 0xF80000) == 0xF80000); break; + case 3: distrust = !have_done_picasso; break; + default: abort(); + } +#endif + return distrust; +#endif +} + +static inline int distrust_byte(void) +{ + return distrust_check(currprefs.comptrustbyte); +} + +static inline int distrust_word(void) +{ + return distrust_check(currprefs.comptrustword); +} + +static inline int distrust_long(void) +{ + return distrust_check(currprefs.comptrustlong); +} + +static inline int distrust_addr(void) +{ + return distrust_check(currprefs.comptrustnaddr); +} + +#else +#define DEBUG 0 +#include "debug.h" + +#define NATMEM_OFFSET MEMBaseDiff +#define canbang 1 +#define op_illg op_illg_1 + +#ifdef WINUAE_ARANYM +void jit_abort(const char *format, ...) +{ + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + abort(); +} +#endif + +#if DEBUG +#define PROFILE_COMPILE_TIME 1 +#define PROFILE_UNTRANSLATED_INSNS 1 +#endif +#endif + +# include +# include +# include +# include + +#if defined(CPU_x86_64) && 0 +#define RECORD_REGISTER_USAGE 1 +#endif + +#ifdef JIT_DEBUG +#undef abort +#define abort() do { \ + fprintf(stderr, "Abort in file %s at line %d\n", __FILE__, __LINE__); \ + compiler_dumpstate(); \ + exit(EXIT_FAILURE); \ +} while (0) +#endif + +#ifdef RECORD_REGISTER_USAGE +static uint64 reg_count[16]; +static uint64 reg_count_local[16]; + +static int reg_count_compare(const void *ap, const void *bp) +{ + const int a = *((int *)ap); + const int b = *((int *)bp); + return reg_count[b] - reg_count[a]; +} +#endif + +#ifdef PROFILE_COMPILE_TIME +#include +static uae_u32 compile_count = 0; +static clock_t compile_time = 0; +static clock_t emul_start_time = 0; +static clock_t emul_end_time = 0; +#endif + +#ifdef PROFILE_UNTRANSLATED_INSNS +static const int untranslated_top_ten = 50; +static uae_u32 raw_cputbl_count[65536] = { 0, }; +static uae_u16 opcode_nums[65536]; + + +static int untranslated_compfn(const void *e1, const void *e2) +{ + return raw_cputbl_count[*(const uae_u16 *)e1] < raw_cputbl_count[*(const uae_u16 *)e2]; +} +#endif + +static compop_func *compfunctbl[65536]; +static compop_func *nfcompfunctbl[65536]; +#ifdef NOFLAGS_SUPPORT +static cpuop_func *nfcpufunctbl[65536]; +#endif +uae_u8* comp_pc_p; + +#ifdef UAE +/* defined in uae.h */ +#else +// External variables +// newcpu.cpp +extern int quit_program; +#endif + +// gb-- Extra data for Basilisk II/JIT +#ifdef JIT_DEBUG +static bool JITDebug = false; // Enable runtime disassemblers through mon? +// #define JITDebug bx_options.jit.jitdebug // Enable runtime disassemblers through mon? +#else +const bool JITDebug = false; +// #define JITDebug false // Don't use JIT debug mode at all +#endif +#if USE_INLINING +#ifdef UAE +#define follow_const_jumps (currprefs.comp_constjump != 0) +#else +static bool follow_const_jumps = true; // Flag: translation through constant jumps +#endif +#else +const bool follow_const_jumps = false; +#endif + +const uae_u32 MIN_CACHE_SIZE = 1024; // Minimal translation cache size (1 MB) +static uae_u32 cache_size = 0; // Size of total cache allocated for compiled blocks +static uae_u32 current_cache_size = 0; // Cache grows upwards: how much has been consumed already +static bool lazy_flush = true; // Flag: lazy translation cache invalidation +// Flag: compile FPU instructions ? +#ifdef UAE +#ifdef USE_JIT_FPU +#define avoid_fpu (!currprefs.compfpu) +#else +#define avoid_fpu (true) +#endif +#else +static bool avoid_fpu = true; // Flag: compile FPU instructions ? +// #ifdef USE_JIT_FPU +// #define avoid_fpu (!bx_options.jit.jitfpu) +// #else +// #define avoid_fpu (true) +// #endif +#endif +static bool have_cmov = false; // target has CMOV instructions ? +static bool have_rat_stall = true; // target has partial register stalls ? +const bool tune_alignment = true; // Tune code alignments for running CPU ? +const bool tune_nop_fillers = true; // Tune no-op fillers for architecture +static bool setzflg_uses_bsf = false; // setzflg virtual instruction can use native BSF instruction correctly? +static int align_loops = 32; // Align the start of loops +static int align_jumps = 32; // Align the start of jumps +static int optcount[10] = { +#ifdef UAE + 4, // How often a block has to be executed before it is translated +#else + 10, // How often a block has to be executed before it is translated +#endif + 0, // How often to use naive translation + 0, 0, 0, 0, + -1, -1, -1, -1 +}; + +#ifdef UAE +/* FIXME: op_properties is currently in compemu.h */ + +op_properties prop[65536]; + +static inline bool is_const_jump(uae_u32 opcode) +{ + return prop[opcode].is_const_jump != 0; +} +#else +struct op_properties { + uae_u8 use_flags; + uae_u8 set_flags; + uae_u8 is_addx; + uae_u8 cflow; +}; +static op_properties prop[65536]; + +static inline int end_block(uae_u32 opcode) +{ + return (prop[opcode].cflow & fl_end_block); +} + +static inline bool is_const_jump(uae_u32 opcode) +{ + return (prop[opcode].cflow == fl_const_jump); +} + +#if 0 +static inline bool may_trap(uae_u32 opcode) +{ + return (prop[opcode].cflow & fl_trap); +} +#endif + +#endif + +static inline unsigned int cft_map (unsigned int f) +{ +#ifdef UAE + return f; +#else +#if !defined(HAVE_GET_WORD_UNSWAPPED) || defined(FULLMMU) + return f; +#else + return ((f >> 8) & 255) | ((f & 255) << 8); +#endif +#endif +} + +uae_u8* start_pc_p; +uae_u32 start_pc; +uae_u32 current_block_pc_p; +static uintptr current_block_start_target; +uae_u32 needed_flags; +static uintptr next_pc_p; +static uintptr taken_pc_p; +static int branch_cc; +static int redo_current_block; + +#ifdef UAE +int segvcount=0; +#endif +static uae_u8* current_compile_p=NULL; +static uae_u8* max_compile_start; +static uae_u8* compiled_code=NULL; +static uae_s32 reg_alloc_run; +const int POPALLSPACE_SIZE = 2048; /* That should be enough space */ +static uae_u8 *popallspace=NULL; + +void* pushall_call_handler=NULL; +static void* popall_do_nothing=NULL; +static void* popall_exec_nostats=NULL; +static void* popall_execute_normal=NULL; +static void* popall_cache_miss=NULL; +static void* popall_recompile_block=NULL; +static void* popall_check_checksum=NULL; + +/* The 68k only ever executes from even addresses. So right now, we + * waste half the entries in this array + * UPDATE: We now use those entries to store the start of the linked + * lists that we maintain for each hash result. + */ +static cacheline cache_tags[TAGSIZE]; +static int cache_enabled=0; +static blockinfo* hold_bi[MAX_HOLD_BI]; +static blockinfo* active; +static blockinfo* dormant; + +#ifdef NOFLAGS_SUPPORT +/* 68040 */ +extern const struct cputbl op_smalltbl_0_nf[]; +#endif +extern const struct comptbl op_smalltbl_0_comp_nf[]; +extern const struct comptbl op_smalltbl_0_comp_ff[]; + +#ifdef NOFLAGS_SUPPORT +/* 68020 + 68881 */ +extern const struct cputbl op_smalltbl_1_nf[]; +/* 68020 */ +extern const struct cputbl op_smalltbl_2_nf[]; +/* 68010 */ +extern const struct cputbl op_smalltbl_3_nf[]; +/* 68000 */ +extern const struct cputbl op_smalltbl_4_nf[]; +/* 68000 slow but compatible. */ +extern const struct cputbl op_smalltbl_5_nf[]; +#endif + +static void flush_icache_hard(void); +static void flush_icache_lazy(void); +static void flush_icache_none(void); +void (*flush_icache)(void) = flush_icache_none; + +static bigstate live; +static smallstate empty_ss; +static smallstate default_ss; +static int optlev; + +static int writereg(int r, int size); +static void unlock2(int r); +static void setlock(int r); +static int readreg_specific(int r, int size, int spec); +static int writereg_specific(int r, int size, int spec); + +static void inline write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a); + +uae_u32 m68k_pc_offset; + +/* Some arithmetic operations can be optimized away if the operands + * are known to be constant. But that's only a good idea when the + * side effects they would have on the flags are not important. This + * variable indicates whether we need the side effects or not + */ +static uae_u32 needflags=0; + +/* Flag handling is complicated. + * + * x86 instructions create flags, which quite often are exactly what we + * want. So at times, the "68k" flags are actually in the x86 flags. + * + * Then again, sometimes we do x86 instructions that clobber the x86 + * flags, but don't represent a corresponding m68k instruction. In that + * case, we have to save them. + * + * We used to save them to the stack, but now store them back directly + * into the regflags.cznv of the traditional emulation. Thus some odd + * names. + * + * So flags can be in either of two places (used to be three; boy were + * things complicated back then!); And either place can contain either + * valid flags or invalid trash (and on the stack, there was also the + * option of "nothing at all", now gone). A couple of variables keep + * track of the respective states. + * + * To make things worse, we might or might not be interested in the flags. + * by default, we are, but a call to dont_care_flags can change that + * until the next call to live_flags. If we are not, pretty much whatever + * is in the register and/or the native flags is seen as valid. + */ + +static inline blockinfo* get_blockinfo(uae_u32 cl) +{ + return cache_tags[cl+1].bi; +} + +static inline blockinfo* get_blockinfo_addr(void* addr) +{ + blockinfo* bi=get_blockinfo(cacheline(addr)); + + while (bi) { + if (bi->pc_p==addr) + return bi; + bi=bi->next_same_cl; + } + return NULL; +} + +#ifdef WINUAE_ARANYM +/******************************************************************* + * Disassembler support * + *******************************************************************/ + +#define TARGET_M68K 0 +#define TARGET_POWERPC 1 +#define TARGET_X86 2 +#define TARGET_X86_64 3 +#define TARGET_ARM 4 +#if defined(CPU_i386) +#define TARGET_NATIVE TARGET_X86 +#endif +#if defined(CPU_powerpc) +#define TARGET_NATIVE TARGET_POWERPC +#endif +#if defined(CPU_x86_64) +#define TARGET_NATIVE TARGET_X86_64 +#endif +#if defined(CPU_arm) +#define TARGET_NATIVE TARGET_ARM +#endif +// #include "disasm-glue.h" + +bool disasm_this_inst; + +#if defined(JIT_DEBUG) || (defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K)) +static void disasm_block(int disasm_target, const uint8 *start, size_t length) +{ + UNUSED(start); + UNUSED(length); + switch (disasm_target) + { + case TARGET_M68K: +#if defined(HAVE_DISASM_M68K) + { + char buf[256]; + + disasm_info.memory_vma = ((memptr)((uintptr_t)(start) - MEMBaseDiff)); + while (length > 0) + { + int isize = m68k_disasm_to_buf(&disasm_info, buf, 1); + bug("%s", buf); + if (isize < 0) + break; + if ((uintptr)isize > length) + break; + length -= isize; + } + } +#endif + break; + case TARGET_X86: + case TARGET_X86_64: +#if defined(HAVE_DISASM_X86) + { + const uint8 *end = start + length; + char buf[256]; + + while (start < end) + { + start = x86_disasm(start, buf, 1); + bug("%s", buf); + } + } +#endif + break; + case TARGET_ARM: +#if defined(HAVE_DISASM_ARM) + { + const uint8 *end = start + length; + char buf[256]; + + while (start < end) + { + start = arm_disasm(start, buf, 1); + bug("%s", buf); + } + } +#endif + break; + } +} + +static inline void disasm_native_block(const uint8 *start, size_t length) +{ + disasm_block(TARGET_NATIVE, start, length); +} + +static inline void disasm_m68k_block(const uint8 *start, size_t length) +{ + disasm_block(TARGET_M68K, start, length); +} +#endif +#endif /* WINUAE_ARANYM */ + + +/******************************************************************* + * All sorts of list related functions for all of the lists * + *******************************************************************/ + +static inline void remove_from_cl_list(blockinfo* bi) +{ + uae_u32 cl=cacheline(bi->pc_p); + + if (bi->prev_same_cl_p) + *(bi->prev_same_cl_p)=bi->next_same_cl; + if (bi->next_same_cl) + bi->next_same_cl->prev_same_cl_p=bi->prev_same_cl_p; + if (cache_tags[cl+1].bi) + cache_tags[cl].handler=cache_tags[cl+1].bi->handler_to_use; + else + cache_tags[cl].handler=(cpuop_func*)popall_execute_normal; +} + +static inline void remove_from_list(blockinfo* bi) +{ + if (bi->prev_p) + *(bi->prev_p)=bi->next; + if (bi->next) + bi->next->prev_p=bi->prev_p; +} + +#if 0 +static inline void remove_from_lists(blockinfo* bi) +{ + remove_from_list(bi); + remove_from_cl_list(bi); +} +#endif + +static inline void add_to_cl_list(blockinfo* bi) +{ + uae_u32 cl=cacheline(bi->pc_p); + + if (cache_tags[cl+1].bi) + cache_tags[cl+1].bi->prev_same_cl_p=&(bi->next_same_cl); + bi->next_same_cl=cache_tags[cl+1].bi; + + cache_tags[cl+1].bi=bi; + bi->prev_same_cl_p=&(cache_tags[cl+1].bi); + + cache_tags[cl].handler=bi->handler_to_use; +} + +static inline void raise_in_cl_list(blockinfo* bi) +{ + remove_from_cl_list(bi); + add_to_cl_list(bi); +} + +static inline void add_to_active(blockinfo* bi) +{ + if (active) + active->prev_p=&(bi->next); + bi->next=active; + + active=bi; + bi->prev_p=&active; +} + +static inline void add_to_dormant(blockinfo* bi) +{ + if (dormant) + dormant->prev_p=&(bi->next); + bi->next=dormant; + + dormant=bi; + bi->prev_p=&dormant; +} + +static inline void remove_dep(dependency* d) +{ + if (d->prev_p) + *(d->prev_p)=d->next; + if (d->next) + d->next->prev_p=d->prev_p; + d->prev_p=NULL; + d->next=NULL; +} + +/* This block's code is about to be thrown away, so it no longer + depends on anything else */ +static inline void remove_deps(blockinfo* bi) +{ + remove_dep(&(bi->dep[0])); + remove_dep(&(bi->dep[1])); +} + +static inline void adjust_jmpdep(dependency* d, cpuop_func* a) +{ + write_jmp_target(d->jmp_off, a); +} + +/******************************************************************** + * Soft flush handling support functions * + ********************************************************************/ + +static inline void set_dhtu(blockinfo* bi, cpuop_func *dh) +{ + jit_log2("bi is %p",bi); + if (dh!=bi->direct_handler_to_use) { + dependency* x=bi->deplist; + jit_log2("bi->deplist=%p",bi->deplist); + while (x) { + jit_log2("x is %p",x); + jit_log2("x->next is %p",x->next); + jit_log2("x->prev_p is %p",x->prev_p); + + if (x->jmp_off) { + adjust_jmpdep(x,dh); + } + x=x->next; + } + bi->direct_handler_to_use=dh; + } +} + +static inline void invalidate_block(blockinfo* bi) +{ + int i; + + bi->optlevel=0; + bi->count=optcount[0]-1; + bi->handler=NULL; + bi->handler_to_use=(cpuop_func*)popall_execute_normal; + bi->direct_handler=NULL; + set_dhtu(bi,bi->direct_pen); + bi->needed_flags=0xff; + bi->status=BI_INVALID; + for (i=0;i<2;i++) { + bi->dep[i].jmp_off=NULL; + bi->dep[i].target=NULL; + } + remove_deps(bi); +} + +static inline void create_jmpdep(blockinfo* bi, int i, uae_u32* jmpaddr, uae_u32 target) +{ + blockinfo* tbi=get_blockinfo_addr((void*)(uintptr)target); + + Dif(!tbi) { + jit_abort("Could not create jmpdep!"); + } + bi->dep[i].jmp_off=jmpaddr; + bi->dep[i].source=bi; + bi->dep[i].target=tbi; + bi->dep[i].next=tbi->deplist; + if (bi->dep[i].next) + bi->dep[i].next->prev_p=&(bi->dep[i].next); + bi->dep[i].prev_p=&(tbi->deplist); + tbi->deplist=&(bi->dep[i]); +} + +static inline void block_need_recompile(blockinfo * bi) +{ + uae_u32 cl = cacheline(bi->pc_p); + + set_dhtu(bi, bi->direct_pen); + bi->direct_handler = bi->direct_pen; + + bi->handler_to_use = (cpuop_func *)popall_execute_normal; + bi->handler = (cpuop_func *)popall_execute_normal; + if (bi == cache_tags[cl + 1].bi) + cache_tags[cl].handler = (cpuop_func *)popall_execute_normal; + bi->status = BI_NEED_RECOMP; +} + +#if USE_MATCH +static inline void mark_callers_recompile(blockinfo * bi) +{ + dependency *x = bi->deplist; + + while (x) { + dependency *next = x->next; /* This disappears when we mark for + * recompilation and thus remove the + * blocks from the lists */ + if (x->jmp_off) { + blockinfo *cbi = x->source; + + Dif(cbi->status == BI_INVALID) { + jit_log("invalid block in dependency list"); // FIXME? + // abort(); + } + if (cbi->status == BI_ACTIVE || cbi->status == BI_NEED_CHECK) { + block_need_recompile(cbi); + mark_callers_recompile(cbi); + } + else if (cbi->status == BI_COMPILING) { + redo_current_block = 1; + } + else if (cbi->status == BI_NEED_RECOMP) { + /* nothing */ + } + else { + jit_log2("Status %d in mark_callers",cbi->status); // FIXME? + } + } + x = next; + } +} +#endif + +static inline blockinfo* get_blockinfo_addr_new(void* addr, int /* setstate */) +{ + blockinfo* bi=get_blockinfo_addr(addr); + int i; + + if (!bi) { + for (i=0;ipc_p=(uae_u8*)addr; + invalidate_block(bi); + add_to_active(bi); + add_to_cl_list(bi); + + } + } + } + if (!bi) { + jit_abort("Looking for blockinfo, can't find free one"); + } + return bi; +} + +static void prepare_block(blockinfo* bi); + +/* Managment of blockinfos. + + A blockinfo struct is allocated whenever a new block has to be + compiled. If the list of free blockinfos is empty, we allocate a new + pool of blockinfos and link the newly created blockinfos altogether + into the list of free blockinfos. Otherwise, we simply pop a structure + of the free list. + + Blockinfo are lazily deallocated, i.e. chained altogether in the + list of free blockinfos whenvever a translation cache flush (hard or + soft) request occurs. +*/ + +template< class T > +class LazyBlockAllocator +{ + enum { + kPoolSize = 1 + (16384 - sizeof(T) - sizeof(void *)) / sizeof(T) + }; + struct Pool { + T chunk[kPoolSize]; + Pool * next; + }; + Pool * mPools; + T * mChunks; +public: + LazyBlockAllocator() : mPools(0), mChunks(0) { } +#ifdef UAE +#else + ~LazyBlockAllocator(); +#endif + T * acquire(); + void release(T * const); +}; + +#ifdef UAE +/* uae_vm_release may do logging, which isn't safe to do when the application + * is shutting down. Better to release memory manually with a function call + * to a release_all method on shutdown, or even simpler, just let the OS + * handle it (we're shutting down anyway). */ +#else +template< class T > +LazyBlockAllocator::~LazyBlockAllocator() +{ + Pool * currentPool = mPools; + while (currentPool) { + Pool * deadPool = currentPool; + currentPool = currentPool->next; + vm_release(deadPool, sizeof(Pool)); + } +} +#endif + +template< class T > +T * LazyBlockAllocator::acquire() +{ + if (!mChunks) { + // There is no chunk left, allocate a new pool and link the + // chunks into the free list + Pool * newPool = (Pool *)vm_acquire(sizeof(Pool), VM_MAP_DEFAULT | VM_MAP_32BIT); + if (newPool == VM_MAP_FAILED) { + jit_abort("Could not allocate block pool!"); + } + for (T * chunk = &newPool->chunk[0]; chunk < &newPool->chunk[kPoolSize]; chunk++) { + chunk->next = mChunks; + mChunks = chunk; + } + newPool->next = mPools; + mPools = newPool; + } + T * chunk = mChunks; + mChunks = chunk->next; + return chunk; +} + +template< class T > +void LazyBlockAllocator::release(T * const chunk) +{ + chunk->next = mChunks; + mChunks = chunk; +} + +template< class T > +class HardBlockAllocator +{ +public: + T * acquire() { + T * data = (T *)current_compile_p; + current_compile_p += sizeof(T); + return data; + } + + void release(T * const ) { + // Deallocated on invalidation + } +}; + +#if USE_SEPARATE_BIA +static LazyBlockAllocator BlockInfoAllocator; +static LazyBlockAllocator ChecksumInfoAllocator; +#else +static HardBlockAllocator BlockInfoAllocator; +static HardBlockAllocator ChecksumInfoAllocator; +#endif + +static inline checksum_info *alloc_checksum_info(void) +{ + checksum_info *csi = ChecksumInfoAllocator.acquire(); + csi->next = NULL; + return csi; +} + +static inline void free_checksum_info(checksum_info *csi) +{ + csi->next = NULL; + ChecksumInfoAllocator.release(csi); +} + +static inline void free_checksum_info_chain(checksum_info *csi) +{ + while (csi != NULL) { + checksum_info *csi2 = csi->next; + free_checksum_info(csi); + csi = csi2; + } +} + +static inline blockinfo *alloc_blockinfo(void) +{ + blockinfo *bi = BlockInfoAllocator.acquire(); +#if USE_CHECKSUM_INFO + bi->csi = NULL; +#endif + return bi; +} + +static inline void free_blockinfo(blockinfo *bi) +{ +#if USE_CHECKSUM_INFO + free_checksum_info_chain(bi->csi); + bi->csi = NULL; +#endif + BlockInfoAllocator.release(bi); +} + +static inline void alloc_blockinfos(void) +{ + int i; + blockinfo* bi; + + for (i=0;i>24)&0xff) | ((v>>8)&0xff00) | ((v<<8)&0xff0000) | ((v<<24)&0xff000000); +#endif +} + +void set_target(uae_u8* t) +{ + target=t; +} + +static inline uae_u8* get_target_noopt(void) +{ + return target; +} + +inline uae_u8* get_target(void) +{ + return get_target_noopt(); +} + +/******************************************************************** + * New version of data buffer: interleave data and code * + ********************************************************************/ +#if defined(USE_DATA_BUFFER) + +#define DATA_BUFFER_SIZE 1024 // Enlarge POPALLSPACE_SIZE if this value is greater than 768 +#define DATA_BUFFER_MAXOFFSET 4096 - 32 // max range between emit of data and use of data +static uae_u8* data_writepos = 0; +static uae_u8* data_endpos = 0; +#if DEBUG +static long data_wasted = 0; +#endif + +static inline void compemu_raw_branch(IMM d); + +static inline void data_check_end(long n, long codesize) +{ + if(data_writepos + n > data_endpos || get_target_noopt() + codesize - data_writepos > DATA_BUFFER_MAXOFFSET) + { + // Start new buffer +#if DEBUG + if(data_writepos < data_endpos) + data_wasted += data_endpos - data_writepos; +#endif + compemu_raw_branch(DATA_BUFFER_SIZE); + data_writepos = get_target_noopt(); + data_endpos = data_writepos + DATA_BUFFER_SIZE; + set_target(get_target_noopt() + DATA_BUFFER_SIZE); + } +} + +static inline long data_word_offs(uae_u16 x) +{ + data_check_end(4, 4); +#ifdef WORDS_BIGENDIAN + *((uae_u16*)data_writepos)=x; + data_writepos += 2; + *((uae_u16*)data_writepos)=0; + data_writepos += 2; +#else + *((uae_u32*)data_writepos)=x; + data_writepos += 4; +#endif + return (long)data_writepos - (long)get_target_noopt() - 12; +} + +static inline long data_long(uae_u32 x, long codesize) +{ + data_check_end(4, codesize); + *((uae_u32*)data_writepos)=x; + data_writepos += 4; + return (long)data_writepos - 4; +} + +static inline long data_long_offs(uae_u32 x) +{ + data_check_end(4, 4); + *((uae_u32*)data_writepos)=x; + data_writepos += 4; + return (long)data_writepos - (long)get_target_noopt() - 12; +} + +static inline long get_data_offset(long t) +{ + return t - (long)get_target_noopt() - 8; +} + +static inline void reset_data_buffer(void) +{ + data_writepos = 0; + data_endpos = 0; +} + +#endif +/******************************************************************** + * Getting the information about the target CPU * + ********************************************************************/ + +#if defined(CPU_arm) +#include "codegen_arm.cpp" +#endif +#if defined(CPU_i386) || defined(CPU_x86_64) +#include "codegen_x86.cpp" +#endif + + +/******************************************************************** + * Flags status handling. EMIT TIME! * + ********************************************************************/ + +static void bt_l_ri_noclobber(RR4 r, IMM i); + +static void make_flags_live_internal(void) +{ + if (live.flags_in_flags==VALID) + return; + Dif (live.flags_on_stack==TRASH) { + jit_abort("Want flags, got something on stack, but it is TRASH"); + } + if (live.flags_on_stack==VALID) { + int tmp; + tmp=readreg_specific(FLAGTMP,4,FLAG_NREG2); + raw_reg_to_flags(tmp); + unlock2(tmp); + + live.flags_in_flags=VALID; + return; + } + jit_abort("Huh? live.flags_in_flags=%d, live.flags_on_stack=%d, but need to make live", + live.flags_in_flags,live.flags_on_stack); +} + +static void flags_to_stack(void) +{ + if (live.flags_on_stack==VALID) + return; + if (!live.flags_are_important) { + live.flags_on_stack=VALID; + return; + } + Dif (live.flags_in_flags!=VALID) + jit_abort("flags_to_stack != VALID"); + else { + int tmp; + tmp=writereg_specific(FLAGTMP,4,FLAG_NREG1); + raw_flags_to_reg(tmp); + unlock2(tmp); + } + live.flags_on_stack=VALID; +} + +static inline void clobber_flags(void) +{ + if (live.flags_in_flags==VALID && live.flags_on_stack!=VALID) + flags_to_stack(); + live.flags_in_flags=TRASH; +} + +/* Prepare for leaving the compiled stuff */ +static inline void flush_flags(void) +{ + flags_to_stack(); + return; +} + +int touchcnt; + +/******************************************************************** + * Partial register flushing for optimized calls * + ********************************************************************/ + +struct regusage { + uae_u16 rmask; + uae_u16 wmask; +}; + +#if 0 +static inline void ru_set(uae_u16 *mask, int reg) +{ +#if USE_OPTIMIZED_CALLS + *mask |= 1 << reg; +#else + UNUSED(mask); + UNUSED(reg); +#endif +} + +static inline bool ru_get(const uae_u16 *mask, int reg) +{ +#if USE_OPTIMIZED_CALLS + return (*mask & (1 << reg)); +#else + UNUSED(mask); + UNUSED(reg); + /* Default: instruction reads & write to register */ + return true; +#endif +} + +static inline void ru_set_read(regusage *ru, int reg) +{ + ru_set(&ru->rmask, reg); +} + +static inline void ru_set_write(regusage *ru, int reg) +{ + ru_set(&ru->wmask, reg); +} + +static inline bool ru_read_p(const regusage *ru, int reg) +{ + return ru_get(&ru->rmask, reg); +} + +static inline bool ru_write_p(const regusage *ru, int reg) +{ + return ru_get(&ru->wmask, reg); +} + +static void ru_fill_ea(regusage *ru, int reg, amodes mode, + wordsizes size, int write_mode) +{ + switch (mode) { + case Areg: + reg += 8; + /* fall through */ + case Dreg: + ru_set(write_mode ? &ru->wmask : &ru->rmask, reg); + break; + case Ad16: + /* skip displacment */ + m68k_pc_offset += 2; + case Aind: + case Aipi: + case Apdi: + ru_set_read(ru, reg+8); + break; + case Ad8r: + ru_set_read(ru, reg+8); + /* fall through */ + case PC8r: { + uae_u16 dp = comp_get_iword((m68k_pc_offset+=2)-2); + reg = (dp >> 12) & 15; + ru_set_read(ru, reg); + if (dp & 0x100) + m68k_pc_offset += (((dp & 0x30) >> 3) & 7) + ((dp & 3) * 2); + break; + } + case PC16: + case absw: + case imm0: + case imm1: + m68k_pc_offset += 2; + break; + case absl: + case imm2: + m68k_pc_offset += 4; + break; + case immi: + m68k_pc_offset += (size == sz_long) ? 4 : 2; + break; + } +} + +/* TODO: split into a static initialization part and a dynamic one + (instructions depending on extension words) */ + +static void ru_fill(regusage *ru, uae_u32 opcode) +{ + m68k_pc_offset += 2; + + /* Default: no register is used or written to */ + ru->rmask = 0; + ru->wmask = 0; + + uae_u32 real_opcode = cft_map(opcode); + struct instr *dp = &table68k[real_opcode]; + + bool rw_dest = true; + bool handled = false; + + /* Handle some instructions specifically */ + uae_u16 ext; + switch (dp->mnemo) { + case i_BFCHG: + case i_BFCLR: + case i_BFEXTS: + case i_BFEXTU: + case i_BFFFO: + case i_BFINS: + case i_BFSET: + case i_BFTST: + ext = comp_get_iword((m68k_pc_offset+=2)-2); + if (ext & 0x800) ru_set_read(ru, (ext >> 6) & 7); + if (ext & 0x020) ru_set_read(ru, ext & 7); + ru_fill_ea(ru, dp->dreg, (amodes)dp->dmode, (wordsizes)dp->size, 1); + if (dp->dmode == Dreg) + ru_set_read(ru, dp->dreg); + switch (dp->mnemo) { + case i_BFEXTS: + case i_BFEXTU: + case i_BFFFO: + ru_set_write(ru, (ext >> 12) & 7); + break; + case i_BFINS: + ru_set_read(ru, (ext >> 12) & 7); + /* fall through */ + case i_BFCHG: + case i_BFCLR: + case i_BSET: + if (dp->dmode == Dreg) + ru_set_write(ru, dp->dreg); + break; + } + handled = true; + rw_dest = false; + break; + + case i_BTST: + rw_dest = false; + break; + + case i_CAS: + { + ext = comp_get_iword((m68k_pc_offset+=2)-2); + int Du = ext & 7; + ru_set_read(ru, Du); + int Dc = (ext >> 6) & 7; + ru_set_read(ru, Dc); + ru_set_write(ru, Dc); + break; + } + case i_CAS2: + { + int Dc1, Dc2, Du1, Du2, Rn1, Rn2; + ext = comp_get_iword((m68k_pc_offset+=2)-2); + Rn1 = (ext >> 12) & 15; + Du1 = (ext >> 6) & 7; + Dc1 = ext & 7; + ru_set_read(ru, Rn1); + ru_set_read(ru, Du1); + ru_set_read(ru, Dc1); + ru_set_write(ru, Dc1); + ext = comp_get_iword((m68k_pc_offset+=2)-2); + Rn2 = (ext >> 12) & 15; + Du2 = (ext >> 6) & 7; + Dc2 = ext & 7; + ru_set_read(ru, Rn2); + ru_set_read(ru, Du2); + ru_set_write(ru, Dc2); + break; + } + case i_DIVL: case i_MULL: + m68k_pc_offset += 2; + break; + case i_LEA: + case i_MOVE: case i_MOVEA: case i_MOVE16: + rw_dest = false; + break; + case i_PACK: case i_UNPK: + rw_dest = false; + m68k_pc_offset += 2; + break; + case i_TRAPcc: + m68k_pc_offset += (dp->size == sz_long) ? 4 : 2; + break; + case i_RTR: + /* do nothing, just for coverage debugging */ + break; + /* TODO: handle EXG instruction */ + } + + /* Handle A-Traps better */ + if ((real_opcode & 0xf000) == 0xa000) { + handled = true; + } + + /* Handle EmulOps better */ + if ((real_opcode & 0xff00) == 0x7100) { + handled = true; + ru->rmask = 0xffff; + ru->wmask = 0; + } + + if (dp->suse && !handled) + ru_fill_ea(ru, dp->sreg, (amodes)dp->smode, (wordsizes)dp->size, 0); + + if (dp->duse && !handled) + ru_fill_ea(ru, dp->dreg, (amodes)dp->dmode, (wordsizes)dp->size, 1); + + if (rw_dest) + ru->rmask |= ru->wmask; + + handled = handled || dp->suse || dp->duse; + + /* Mark all registers as used/written if the instruction may trap */ + if (may_trap(opcode)) { + handled = true; + ru->rmask = 0xffff; + ru->wmask = 0xffff; + } + + if (!handled) { + jit_abort("ru_fill: %04x = { %04x, %04x }", + real_opcode, ru->rmask, ru->wmask); + } +} +#endif + +/******************************************************************** + * register allocation per block logging * + ********************************************************************/ + +static uae_s8 vstate[VREGS]; +static uae_s8 vwritten[VREGS]; +static uae_s8 nstate[N_REGS]; + +#define L_UNKNOWN -127 +#define L_UNAVAIL -1 +#define L_NEEDED -2 +#define L_UNNEEDED -3 + +#if USE_MATCH +static inline void big_to_small_state(bigstate * /* b */, smallstate * s) +{ + int i; + + for (i = 0; i < VREGS; i++) + s->virt[i] = vstate[i]; + for (i = 0; i < N_REGS; i++) + s->nat[i] = nstate[i]; +} + +static inline int callers_need_recompile(bigstate * /* b */, smallstate * s) +{ + int i; + int reverse = 0; + + for (i = 0; i < VREGS; i++) { + if (vstate[i] != L_UNNEEDED && s->virt[i] == L_UNNEEDED) + return 1; + if (vstate[i] == L_UNNEEDED && s->virt[i] != L_UNNEEDED) + reverse++; + } + for (i = 0; i < N_REGS; i++) { + if (nstate[i] >= 0 && nstate[i] != s->nat[i]) + return 1; + if (nstate[i] < 0 && s->nat[i] >= 0) + reverse++; + } + if (reverse >= 2 && USE_MATCH) + return 1; /* In this case, it might be worth recompiling the + * callers */ + return 0; +} +#endif + +static inline void log_startblock(void) +{ + int i; + + for (i = 0; i < VREGS; i++) { + vstate[i] = L_UNKNOWN; + vwritten[i] = 0; + } + for (i = 0; i < N_REGS; i++) + nstate[i] = L_UNKNOWN; +} + +/* Using an n-reg for a temp variable */ +static inline void log_isused(int n) +{ + if (nstate[n] == L_UNKNOWN) + nstate[n] = L_UNAVAIL; +} + +static inline void log_visused(int r) +{ + if (vstate[r] == L_UNKNOWN) + vstate[r] = L_NEEDED; +} + +static inline void do_load_reg(int n, int r) +{ + if (r == FLAGTMP) + raw_load_flagreg(n); + else if (r == FLAGX) + raw_load_flagx(n); + else + compemu_raw_mov_l_rm(n, (uintptr) live.state[r].mem); +} + +#if 0 +static inline void check_load_reg(int n, int r) +{ + compemu_raw_mov_l_rm(n, (uintptr) live.state[r].mem); +} +#endif + +static inline void log_vwrite(int r) +{ + vwritten[r] = 1; +} + +/* Using an n-reg to hold a v-reg */ +static inline void log_isreg(int n, int r) +{ + if (nstate[n] == L_UNKNOWN && r < 16 && !vwritten[r] && USE_MATCH) + nstate[n] = r; + else { + do_load_reg(n, r); + if (nstate[n] == L_UNKNOWN) + nstate[n] = L_UNAVAIL; + } + if (vstate[r] == L_UNKNOWN) + vstate[r] = L_NEEDED; +} + +static inline void log_clobberreg(int r) +{ + if (vstate[r] == L_UNKNOWN) + vstate[r] = L_UNNEEDED; +} + +/* This ends all possibility of clever register allocation */ + +static inline void log_flush(void) +{ + int i; + + for (i = 0; i < VREGS; i++) + if (vstate[i] == L_UNKNOWN) + vstate[i] = L_NEEDED; + for (i = 0; i < N_REGS; i++) + if (nstate[i] == L_UNKNOWN) + nstate[i] = L_UNAVAIL; +} + +static inline void log_dump(void) +{ + int i; + + return; + + jit_log("----------------------"); + for (i = 0; i < N_REGS; i++) { + switch (nstate[i]) { + case L_UNKNOWN: + jit_log("Nat %d : UNKNOWN", i); + break; + case L_UNAVAIL: + jit_log("Nat %d : UNAVAIL", i); + break; + default: + jit_log("Nat %d : %d", i, nstate[i]); + break; + } + } + for (i = 0; i < VREGS; i++) { + if (vstate[i] == L_UNNEEDED) { + jit_log("Virt %d: UNNEEDED", i); + } + } +} + +/******************************************************************** + * register status handling. EMIT TIME! * + ********************************************************************/ + +static inline void set_status(int r, int status) +{ + if (status == ISCONST) + log_clobberreg(r); + live.state[r].status=status; +} + +static inline int isinreg(int r) +{ + return live.state[r].status==CLEAN || live.state[r].status==DIRTY; +} + +static inline void adjust_nreg(int r, uae_u32 val) +{ + if (!val) + return; + compemu_raw_lea_l_brr(r,r,val); +} + +static void tomem(int r) +{ + int rr=live.state[r].realreg; + + if (isinreg(r)) { + if (live.state[r].val && live.nat[rr].nholds==1 + && !live.nat[rr].locked) { + jit_log2("RemovingA offset %x from reg %d (%d) at %p", live.state[r].val,r,rr,target); + adjust_nreg(rr,live.state[r].val); + live.state[r].val=0; + live.state[r].dirtysize=4; + set_status(r,DIRTY); + } + } + + if (live.state[r].status==DIRTY) { + switch (live.state[r].dirtysize) { + case 1: compemu_raw_mov_b_mr((uintptr)live.state[r].mem,rr); break; + case 2: compemu_raw_mov_w_mr((uintptr)live.state[r].mem,rr); break; + case 4: compemu_raw_mov_l_mr((uintptr)live.state[r].mem,rr); break; + default: abort(); + } + log_vwrite(r); + set_status(r,CLEAN); + live.state[r].dirtysize=0; + } +} + +static inline int isconst(int r) +{ + return live.state[r].status==ISCONST; +} + +int is_const(int r) +{ + return isconst(r); +} + +static inline void writeback_const(int r) +{ + if (!isconst(r)) + return; + Dif (live.state[r].needflush==NF_HANDLER) { + jit_abort("Trying to write back constant NF_HANDLER!"); + } + + compemu_raw_mov_l_mi((uintptr)live.state[r].mem,live.state[r].val); + log_vwrite(r); + live.state[r].val=0; + set_status(r,INMEM); +} + +static inline void tomem_c(int r) +{ + if (isconst(r)) { + writeback_const(r); + } + else + tomem(r); +} + +static void evict(int r) +{ + int rr; + + if (!isinreg(r)) + return; + tomem(r); + rr=live.state[r].realreg; + + Dif (live.nat[rr].locked && + live.nat[rr].nholds==1) { + jit_abort("register %d in nreg %d is locked!",r,live.state[r].realreg); + } + + live.nat[rr].nholds--; + if (live.nat[rr].nholds!=live.state[r].realind) { /* Was not last */ + int topreg=live.nat[rr].holds[live.nat[rr].nholds]; + int thisind=live.state[r].realind; + + live.nat[rr].holds[thisind]=topreg; + live.state[topreg].realind=thisind; + } + live.state[r].realreg=-1; + set_status(r,INMEM); +} + +static inline void free_nreg(int r) +{ + int i=live.nat[r].nholds; + + while (i) { + int vr; + + --i; + vr=live.nat[r].holds[i]; + evict(vr); + } + Dif (live.nat[r].nholds!=0) { + jit_abort("Failed to free nreg %d, nholds is %d",r,live.nat[r].nholds); + } +} + +/* Use with care! */ +static inline void isclean(int r) +{ + if (!isinreg(r)) + return; + live.state[r].validsize=4; + live.state[r].dirtysize=0; + live.state[r].val=0; + set_status(r,CLEAN); +} + +static inline void disassociate(int r) +{ + isclean(r); + evict(r); +} + +/* XXFIXME: val may be 64bit address for PC_P */ +static inline void set_const(int r, uae_u32 val) +{ + disassociate(r); + live.state[r].val=val; + set_status(r,ISCONST); +} + +static inline uae_u32 get_offset(int r) +{ + return live.state[r].val; +} + +static int alloc_reg_hinted(int r, int size, int willclobber, int hint) +{ + int bestreg; + uae_s32 when; + int i; + uae_s32 badness=0; /* to shut up gcc */ + bestreg=-1; + when=2000000000; + + /* XXX use a regalloc_order table? */ + for (i=0;i0) { + free_nreg(bestreg); + } + if (isinreg(r)) { + int rr=live.state[r].realreg; + /* This will happen if we read a partially dirty register at a + bigger size */ + Dif (willclobber || live.state[r].validsize>=size) + jit_abort("willclobber || live.state[r].validsize>=size"); + Dif (live.nat[rr].nholds!=1) + jit_abort("live.nat[rr].nholds!=1"); + if (size==4 && live.state[r].validsize==2) { + log_isused(bestreg); + log_visused(r); + compemu_raw_mov_l_rm(bestreg,(uintptr)live.state[r].mem); + compemu_raw_bswap_32(bestreg); + compemu_raw_zero_extend_16_rr(rr,rr); + compemu_raw_zero_extend_16_rr(bestreg,bestreg); + compemu_raw_bswap_32(bestreg); + compemu_raw_lea_l_rr_indexed(rr, rr, bestreg, 1); + live.state[r].validsize=4; + live.nat[rr].touched=touchcnt++; + return rr; + } + if (live.state[r].validsize==1) { + /* Nothing yet */ + } + evict(r); + } + + if (!willclobber) { + if (live.state[r].status!=UNDEF) { + if (isconst(r)) { + compemu_raw_mov_l_ri(bestreg,live.state[r].val); + live.state[r].val=0; + live.state[r].dirtysize=4; + set_status(r,DIRTY); + log_isused(bestreg); + } + else { + log_isreg(bestreg, r); /* This will also load it! */ + live.state[r].dirtysize=0; + set_status(r,CLEAN); + } + } + else { + live.state[r].val=0; + live.state[r].dirtysize=0; + set_status(r,CLEAN); + log_isused(bestreg); + } + live.state[r].validsize=4; + } + else { /* this is the easiest way, but not optimal. FIXME! */ + /* Now it's trickier, but hopefully still OK */ + if (!isconst(r) || size==4) { + live.state[r].validsize=size; + live.state[r].dirtysize=size; + live.state[r].val=0; + set_status(r,DIRTY); + if (size == 4) { + log_clobberreg(r); + log_isused(bestreg); + } + else { + log_visused(r); + log_isused(bestreg); + } + } + else { + if (live.state[r].status!=UNDEF) + compemu_raw_mov_l_ri(bestreg,live.state[r].val); + live.state[r].val=0; + live.state[r].validsize=4; + live.state[r].dirtysize=4; + set_status(r,DIRTY); + log_isused(bestreg); + } + } + live.state[r].realreg=bestreg; + live.state[r].realind=live.nat[bestreg].nholds; + live.nat[bestreg].touched=touchcnt++; + live.nat[bestreg].holds[live.nat[bestreg].nholds]=r; + live.nat[bestreg].nholds++; + + return bestreg; +} + +/* +static int alloc_reg(int r, int size, int willclobber) +{ + return alloc_reg_hinted(r,size,willclobber,-1); +} +*/ + +static void unlock2(int r) +{ + Dif (!live.nat[r].locked) + jit_abort("unlock2 %d not locked", r); + live.nat[r].locked--; +} + +static void setlock(int r) +{ + live.nat[r].locked++; +} + + +static void mov_nregs(int d, int s) +{ + int nd=live.nat[d].nholds; + int i; + + if (s==d) + return; + + if (nd>0) + free_nreg(d); + + log_isused(d); + compemu_raw_mov_l_rr(d,s); + + for (i=0;i=size) { + n=live.state[r].realreg; + switch(size) { + case 1: + if (live.nat[n].canbyte || spec>=0) { + answer=n; + } + break; + case 2: + if (live.nat[n].canword || spec>=0) { + answer=n; + } + break; + case 4: + answer=n; + break; + default: abort(); + } + if (answer<0) + evict(r); + } + /* either the value was in memory to start with, or it was evicted and + is in memory now */ + if (answer<0) { + answer=alloc_reg_hinted(r,spec>=0?4:size,0,spec); + } + + if (spec>=0 && spec!=answer) { + /* Too bad */ + mov_nregs(spec,answer); + answer=spec; + } + live.nat[answer].locked++; + live.nat[answer].touched=touchcnt++; + return answer; +} + + + +static int readreg(int r, int size) +{ + return readreg_general(r,size,-1,0); +} + +static int readreg_specific(int r, int size, int spec) +{ + return readreg_general(r,size,spec,0); +} + +static int readreg_offset(int r, int size) +{ + return readreg_general(r,size,-1,1); +} + +/* writereg_general(r, size, spec) + * + * INPUT + * - r : mid-layer register + * - size : requested size (1/2/4) + * - spec : -1 if find or make a register free, otherwise specifies + * the physical register to use in any case + * + * OUTPUT + * - hard (physical, x86 here) register allocated to virtual register r + */ +static inline int writereg_general(int r, int size, int spec) +{ + int n; + int answer=-1; + + record_register(r); + if (size<4) { + remove_offset(r,spec); + } + + make_exclusive(r,size,spec); + if (isinreg(r)) { + int nvsize=size>live.state[r].validsize?size:live.state[r].validsize; + int ndsize=size>live.state[r].dirtysize?size:live.state[r].dirtysize; + n=live.state[r].realreg; + + Dif (live.nat[n].nholds!=1) + jit_abort("live.nat[%d].nholds!=1", n); + switch(size) { + case 1: + if (live.nat[n].canbyte || spec>=0) { + live.state[r].dirtysize=ndsize; + live.state[r].validsize=nvsize; + answer=n; + } + break; + case 2: + if (live.nat[n].canword || spec>=0) { + live.state[r].dirtysize=ndsize; + live.state[r].validsize=nvsize; + answer=n; + } + break; + case 4: + live.state[r].dirtysize=ndsize; + live.state[r].validsize=nvsize; + answer=n; + break; + default: abort(); + } + if (answer<0) + evict(r); + } + /* either the value was in memory to start with, or it was evicted and + is in memory now */ + if (answer<0) { + answer=alloc_reg_hinted(r,size,1,spec); + } + if (spec>=0 && spec!=answer) { + mov_nregs(spec,answer); + answer=spec; + } + if (live.state[r].status==UNDEF) + live.state[r].validsize=4; + live.state[r].dirtysize=size>live.state[r].dirtysize?size:live.state[r].dirtysize; + live.state[r].validsize=size>live.state[r].validsize?size:live.state[r].validsize; + + live.nat[answer].locked++; + live.nat[answer].touched=touchcnt++; + if (size==4) { + live.state[r].val=0; + } + else { + Dif (live.state[r].val) { + jit_abort("Problem with val"); + } + } + set_status(r,DIRTY); + return answer; +} + +static int writereg(int r, int size) +{ + return writereg_general(r,size,-1); +} + +static int writereg_specific(int r, int size, int spec) +{ + return writereg_general(r,size,spec); +} + +static inline int rmw_general(int r, int wsize, int rsize, int spec) +{ + int n; + int answer=-1; + + record_register(r); + if (live.state[r].status==UNDEF) { + jit_log("WARNING: Unexpected read of undefined register %d",r); + } + remove_offset(r,spec); + make_exclusive(r,0,spec); + + Dif (wsize=rsize) { + n=live.state[r].realreg; + Dif (live.nat[n].nholds!=1) + jit_abort("live.nat[%d].nholds!=1", n); + + switch(rsize) { + case 1: + if (live.nat[n].canbyte || spec>=0) { + answer=n; + } + break; + case 2: + if (live.nat[n].canword || spec>=0) { + answer=n; + } + break; + case 4: + answer=n; + break; + default: abort(); + } + if (answer<0) + evict(r); + } + /* either the value was in memory to start with, or it was evicted and + is in memory now */ + if (answer<0) { + answer=alloc_reg_hinted(r,spec>=0?4:rsize,0,spec); + } + + if (spec>=0 && spec!=answer) { + /* Too bad */ + mov_nregs(spec,answer); + answer=spec; + } + if (wsize>live.state[r].dirtysize) + live.state[r].dirtysize=wsize; + if (wsize>live.state[r].validsize) + live.state[r].validsize=wsize; + set_status(r,DIRTY); + + live.nat[answer].locked++; + live.nat[answer].touched=touchcnt++; + + Dif (live.state[r].val) { + jit_abort("Problem with val(rmw)"); + } + return answer; +} + +static int rmw(int r, int wsize, int rsize) +{ + return rmw_general(r,wsize,rsize,-1); +} + +static int rmw_specific(int r, int wsize, int rsize, int spec) +{ + return rmw_general(r,wsize,rsize,spec); +} + + +/* needed for restoring the carry flag on non-P6 cores */ +static void bt_l_ri_noclobber(RR4 r, IMM i) +{ + int size=4; + if (i<16) + size=2; + r=readreg(r,size); + compemu_raw_bt_l_ri(r,i); + unlock2(r); +} + +/******************************************************************** + * FPU register status handling. EMIT TIME! * + ********************************************************************/ + +static void f_tomem(int r) +{ + if (live.fate[r].status==DIRTY) { +#if defined(USE_LONG_DOUBLE) + raw_fmov_ext_mr((uintptr)live.fate[r].mem,live.fate[r].realreg); +#else + raw_fmov_mr((uintptr)live.fate[r].mem,live.fate[r].realreg); +#endif + live.fate[r].status=CLEAN; + } +} + +static void f_tomem_drop(int r) +{ + if (live.fate[r].status==DIRTY) { +#if defined(USE_LONG_DOUBLE) + raw_fmov_ext_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg); +#else + raw_fmov_mr_drop((uintptr)live.fate[r].mem,live.fate[r].realreg); +#endif + live.fate[r].status=INMEM; + } +} + + +static inline int f_isinreg(int r) +{ + return live.fate[r].status==CLEAN || live.fate[r].status==DIRTY; +} + +static void f_evict(int r) +{ + int rr; + + if (!f_isinreg(r)) + return; + rr=live.fate[r].realreg; + if (live.fat[rr].nholds==1) + f_tomem_drop(r); + else + f_tomem(r); + + Dif (live.fat[rr].locked && + live.fat[rr].nholds==1) { + jit_abort("FPU register %d in nreg %d is locked!",r,live.fate[r].realreg); + } + + live.fat[rr].nholds--; + if (live.fat[rr].nholds!=live.fate[r].realind) { /* Was not last */ + int topreg=live.fat[rr].holds[live.fat[rr].nholds]; + int thisind=live.fate[r].realind; + live.fat[rr].holds[thisind]=topreg; + live.fate[topreg].realind=thisind; + } + live.fate[r].status=INMEM; + live.fate[r].realreg=-1; +} + +static inline void f_free_nreg(int r) +{ + int i=live.fat[r].nholds; + + while (i) { + int vr; + + --i; + vr=live.fat[r].holds[i]; + f_evict(vr); + } + Dif (live.fat[r].nholds!=0) { + jit_abort("Failed to free nreg %d, nholds is %d",r,live.fat[r].nholds); + } +} + + +/* Use with care! */ +static inline void f_isclean(int r) +{ + if (!f_isinreg(r)) + return; + live.fate[r].status=CLEAN; +} + +static inline void f_disassociate(int r) +{ + f_isclean(r); + f_evict(r); +} + + + +static int f_alloc_reg(int r, int willclobber) +{ + int bestreg; + uae_s32 when; + int i; + uae_s32 badness; + bestreg=-1; + when=2000000000; + for (i=N_FREGS;i--;) { + badness=live.fat[i].touched; + if (live.fat[i].nholds==0) + badness=0; + + if (!live.fat[i].locked && badness0) { + f_free_nreg(bestreg); + } + if (f_isinreg(r)) { + f_evict(r); + } + + if (!willclobber) { + if (live.fate[r].status!=UNDEF) { +#if defined(USE_LONG_DOUBLE) + raw_fmov_ext_rm(bestreg,(uintptr)live.fate[r].mem); +#else + raw_fmov_rm(bestreg,(uintptr)live.fate[r].mem); +#endif + } + live.fate[r].status=CLEAN; + } + else { + live.fate[r].status=DIRTY; + } + live.fate[r].realreg=bestreg; + live.fate[r].realind=live.fat[bestreg].nholds; + live.fat[bestreg].touched=touchcnt++; + live.fat[bestreg].holds[live.fat[bestreg].nholds]=r; + live.fat[bestreg].nholds++; + + return bestreg; +} + +static void f_unlock(int r) +{ + Dif (!live.fat[r].locked) + jit_abort ("unlock %d", r); + live.fat[r].locked--; +} + +static void f_setlock(int r) +{ + live.fat[r].locked++; +} + +static inline int f_readreg(int r) +{ + int n; + int answer=-1; + + if (f_isinreg(r)) { + n=live.fate[r].realreg; + answer=n; + } + /* either the value was in memory to start with, or it was evicted and + is in memory now */ + if (answer<0) + answer=f_alloc_reg(r,0); + + live.fat[answer].locked++; + live.fat[answer].touched=touchcnt++; + return answer; +} + +static inline void f_make_exclusive(int r, int clobber) +{ + freg_status oldstate; + int rr=live.fate[r].realreg; + int nr; + int nind; + int ndirt=0; + int i; + + if (!f_isinreg(r)) + return; + if (live.fat[rr].nholds==1) + return; + for (i=0;i= uae_p32(kickmem_bank.baseaddr) && + addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536)); +#else + return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize)); +#endif +} + +#if defined(UAE) || defined(FLIGHT_RECORDER) +static void flush_all(void) +{ + int i; + + log_flush(); + for (i=0;i0) + free_nreg(i); + + for (i=0;i0) + f_free_nreg(i); + + live.flags_in_flags=TRASH; /* Note: We assume we already rescued the + flags at the very start of the call_r + functions! */ +} +#endif + +#if defined(CPU_arm) +#include "compemu_midfunc_arm.cpp" + +#if defined(USE_JIT2) +#include "compemu_midfunc_arm2.cpp" +#endif +#endif + +#if defined(CPU_i386) || defined(CPU_x86_64) +#include "compemu_midfunc_x86.cpp" +#endif + + +/******************************************************************** + * Support functions exposed to gencomp. CREATE time * + ********************************************************************/ + +void set_zero(int r, int tmp) +{ + if (setzflg_uses_bsf) + bsf_l_rr(r,r); + else + simulate_bsf(tmp,r); +} + +int kill_rodent(int r) +{ + return KILLTHERAT && + have_rat_stall && + (live.state[r].status==INMEM || + live.state[r].status==CLEAN || + live.state[r].status==ISCONST || + live.state[r].dirtysize==4); +} + +uae_u32 get_const(int r) +{ + Dif (!isconst(r)) { + jit_abort("Register %d should be constant, but isn't",r); + } + return live.state[r].val; +} + +void sync_m68k_pc(void) +{ + if (m68k_pc_offset) { + add_l_ri(PC_P,m68k_pc_offset); + comp_pc_p+=m68k_pc_offset; + m68k_pc_offset=0; + } +} + +/* for building exception frames */ +void compemu_exc_make_frame(int format, int sr, int ret, int nr, int tmp) +{ + lea_l_brr(SP_REG, SP_REG, -2); + mov_l_ri(tmp, (format << 12) + (nr * 4)); /* format | vector */ + writeword(SP_REG, tmp, tmp); + + lea_l_brr(SP_REG, SP_REG, -4); + writelong(SP_REG, ret, tmp); + + lea_l_brr(SP_REG, SP_REG, -2); + writeword_clobber(SP_REG, sr, tmp); + remove_offset(SP_REG, -1); + if (isinreg(SP_REG)) + evict(SP_REG); + else + flush_reg(SP_REG); +} + +void compemu_make_sr(int sr, int tmp) +{ + flush_flags(); /* low level */ + flush_reg(FLAGX); + +#ifdef OPTIMIZED_FLAGS + + /* + * x86 EFLAGS: (!SAHF_SETO_PROFITABLE) + * FEDCBA98 76543210 + * ----V--- NZ-----C + * + * <--AH--> <--AL--> (SAHF_SETO_PROFITABLE) + * FEDCBA98 76543210 + * NZxxxxxC xxxxxxxV + * + * arm RFLAGS: + * FEDCBA98 76543210 FEDCBA98 76543210 + * NZCV---- -------- -------- -------- + * + * -> m68k SR: + * --S--III ---XNZVC + * + * Master-Bit and traceflags are ignored here, + * since they are not emulated in JIT code + */ + mov_l_rm(sr, uae_p32(live.state[FLAGTMP].mem)); + mov_l_ri(tmp, FLAGVAL_N|FLAGVAL_Z|FLAGVAL_V|FLAGVAL_C); + and_l(sr, tmp); + mov_l_rr(tmp, sr); + +#if (defined(CPU_i386) && defined(X86_ASSEMBLY)) || (defined(CPU_x86_64) && defined(X86_64_ASSEMBLY)) +#ifndef SAHF_SETO_PROFITABLE + ror_b_ri(sr, FLAGBIT_N - 3); /* move NZ into position; C->4 */ + shrl_w_ri(tmp, FLAGBIT_V - 1); /* move V into position in tmp */ + or_l(sr, tmp); /* or V flag to SR */ + mov_l_rr(tmp, sr); + shrl_b_ri(tmp, (8 - (FLAGBIT_N - 3)) - FLAGBIT_C); /* move C into position in tmp */ + or_l(sr, tmp); /* or C flag to SR */ +#else + ror_w_ri(sr, FLAGBIT_N - 3); /* move NZ in position; V->4, C->12 */ + shrl_w_ri(tmp, (16 - (FLAGBIT_N - 3)) - FLAGBIT_V - 1); /* move V into position in tmp; C->9 */ + or_l(sr, tmp); /* or V flag to SR */ + shrl_w_ri(tmp, FLAGBIT_C + FLAGBIT_V - 1); /* move C into position in tmp */ + or_l(sr, tmp); /* or C flag to SR */ +#endif + mov_l_ri(tmp, 0x0f); + and_l(sr, tmp); + + mov_b_rm(tmp, uae_p32(®flags.x)); + and_l_ri(tmp, FLAGVAL_X); + shll_l_ri(tmp, 4); + or_l(sr, tmp); + +#elif defined(CPU_arm) && defined(ARM_ASSEMBLY) + shrl_l_ri(sr, FLAGBIT_N - 3); /* move NZ into position */ + ror_l_ri(tmp, FLAGBIT_C - 1); /* move C into position in tmp; V->31 */ + and_l_ri(sr, 0xc); + or_l(sr, tmp); /* or C flag to SR */ + shrl_l_ri(tmp, 31); /* move V into position in tmp */ + or_l(sr, tmp); /* or V flag to SR */ + + mov_b_rm(tmp, uae_p32(®flags.x)); + and_l_ri(tmp, FLAGVAL_X); + shrl_l_ri(tmp, FLAGBIT_X - 4); + or_l(sr, tmp); + +#else +#error "unknown CPU" +#endif + +#else + + xor_l(sr, sr); + xor_l(tmp, tmp); + mov_b_rm(tmp, uae_p32(®s.c)); + shll_l_ri(tmp, 0); + or_l(sr, tmp); + mov_b_rm(tmp, uae_p32(®s.v)); + shll_l_ri(tmp, 1); + or_l(sr, tmp); + mov_b_rm(tmp, uae_p32(®s.z)); + shll_l_ri(tmp, 2); + or_l(sr, tmp); + mov_b_rm(tmp, uae_p32(®s.n)); + shll_l_ri(tmp, 3); + or_l(sr, tmp); + +#endif /* OPTIMIZED_FLAGS */ + + mov_b_rm(tmp, uae_p32(®s.s)); + shll_l_ri(tmp, 13); + or_l(sr, tmp); + mov_l_rm(tmp, uae_p32(®s.intmask)); + shll_l_ri(tmp, 8); + or_l(sr, tmp); + and_l_ri(sr, 0x271f); + mov_w_mr(uae_p32(®s.sr), sr); +} + +void compemu_enter_super(int sr) +{ +#if 0 + fprintf(stderr, "enter_super: isinreg=%d rr=%d nholds=%d\n", isinreg(SP_REG), live.state[SP_REG].realreg, isinreg(SP_REG) ? live.nat[live.state[SP_REG].realreg].nholds : -1); +#endif + remove_offset(SP_REG, -1); + if (isinreg(SP_REG)) + evict(SP_REG); + else + flush_reg(SP_REG); + /* + * equivalent to: + * if (!regs.s) + * { + * regs.usp = m68k_areg(regs, 7); + * m68k_areg(regs, 7) = regs.isp; + * regs.s = 1; + * mmu_set_super(1); + * } + */ + test_l_ri(sr, 0x2000); +#if defined(CPU_i386) || defined(CPU_x86_64) + compemu_raw_jnz_b_oponly(); + uae_u8 *branchadd = get_target(); + skip_byte(); +#elif defined(CPU_arm) + compemu_raw_jnz_b_oponly(); + uae_u8 *branchadd = get_target(); + skip_byte(); +#endif + mov_l_mr((uintptr)®s.usp, SP_REG); + mov_l_rm(SP_REG, uae_p32(®s.isp)); + mov_b_mi(uae_p32(®s.s), 1); +#if defined(CPU_i386) || defined(CPU_x86_64) + *branchadd = get_target() - (branchadd + 1); +#elif defined(CPU_arm) + *((uae_u32 *)branchadd - 3) = get_target() - (branchadd + 1); +#endif +} + +/******************************************************************** + * Scratch registers management * + ********************************************************************/ + +struct scratch_t { + uae_u32 regs[VREGS]; + fpu_register fregs[VFREGS]; +}; + +static scratch_t scratch; + +/******************************************************************** + * Support functions exposed to newcpu * + ********************************************************************/ + +static inline const char *str_on_off(bool b) +{ + return b ? "on" : "off"; +} + +#ifdef UAE +static +#endif +void compiler_init(void) +{ + static bool initialized = false; + if (initialized) + return; + +#ifdef UAE +#else +#ifdef JIT_DEBUG + // JIT debug mode ? + JITDebug = PrefsFindBool("jitdebug"); +#endif + jit_log(" : enable runtime disassemblers : %s", JITDebug ? "yes" : "no"); + +#ifdef USE_JIT_FPU + // Use JIT compiler for FPU instructions ? + avoid_fpu = !PrefsFindBool("jitfpu"); +#else + // JIT FPU is always disabled + avoid_fpu = true; +#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"); + jit_log(" : alignment for loops, jumps are %d, %d", align_loops, align_jumps); +#if defined(CPU_i386) || defined(CPU_x86_64) + jit_log(" : target processor has SSE2 instructions : %s", cpuinfo.x86_has_xmm2 ? "yes" : "no"); + jit_log(" : cache linesize is %lu", (unsigned long)cpuinfo.x86_clflush_size); +#endif + + // Translation cache flush mechanism + lazy_flush = PrefsFindBool("jitlazyflush"); + jit_log(" : lazy translation cache invalidation : %s", str_on_off(lazy_flush)); + flush_icache = lazy_flush ? flush_icache_lazy : flush_icache_hard; + + // Compiler features + jit_log(" : register aliasing : %s", str_on_off(1)); + jit_log(" : FP register aliasing : %s", str_on_off(USE_F_ALIAS)); + jit_log(" : lazy constant offsetting : %s", str_on_off(USE_OFFSET)); +#if USE_INLINING + follow_const_jumps = PrefsFindBool("jitinline"); +#endif + jit_log(" : block inlining : %s", str_on_off(follow_const_jumps)); + jit_log(" : separate blockinfo allocation : %s", str_on_off(USE_SEPARATE_BIA)); + + // Build compiler tables + init_table68k (); + build_comp(); +#endif + + initialized = true; + +#ifdef PROFILE_UNTRANSLATED_INSNS + jit_log(" : gather statistics on untranslated insns count"); +#endif + +#ifdef PROFILE_COMPILE_TIME + jit_log(" : gather statistics on translation time"); + emul_start_time = clock(); +#endif +} + +#ifdef UAE +static +#endif +void compiler_exit(void) +{ +#ifdef PROFILE_COMPILE_TIME + emul_end_time = clock(); +#endif + +#ifdef UAE +#else +#if DEBUG +#if defined(USE_DATA_BUFFER) + 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 + jit_log("### Compile Block statistics"); + jit_log("Number of calls to compile_block : %d", compile_count); + uae_u32 emul_time = emul_end_time - emul_start_time; + jit_log("Total emulation time : %.1f sec", double(emul_time)/double(CLOCKS_PER_SEC)); + jit_log("Total compilation time : %.1f sec (%.1f%%)", double(compile_time)/double(CLOCKS_PER_SEC), 100.0*double(compile_time)/double(emul_time)); +#endif + +#ifdef PROFILE_UNTRANSLATED_INSNS + uae_u64 untranslated_count = 0; + for (int i = 0; i < 65536; i++) { + opcode_nums[i] = i; + untranslated_count += raw_cputbl_count[i]; + } + bug("Sorting out untranslated instructions count..."); + qsort(opcode_nums, 65536, sizeof(uae_u16), untranslated_compfn); + jit_log("Rank Opc Count Name"); + for (int i = 0; i < untranslated_top_ten; i++) { + uae_u32 count = raw_cputbl_count[opcode_nums[i]]; + struct instr *dp; + struct mnemolookup *lookup; + if (!count) + break; + dp = table68k + opcode_nums[i]; + for (lookup = lookuptab; lookup->mnemo != (instrmnem)dp->mnemo; lookup++) + ; + bug("%03d: %04x %10u %s", i, opcode_nums[i], count, lookup->name); + } +#endif + +#ifdef RECORD_REGISTER_USAGE + int reg_count_ids[16]; + uint64 tot_reg_count = 0; + for (int i = 0; i < 16; i++) { + reg_count_ids[i] = i; + tot_reg_count += reg_count[i]; + } + qsort(reg_count_ids, 16, sizeof(int), reg_count_compare); + uint64 cum_reg_count = 0; + for (int i = 0; i < 16; i++) { + int r = reg_count_ids[i]; + cum_reg_count += reg_count[r]; + jit_log("%c%d : %16ld %2.1f%% [%2.1f]", r < 8 ? 'D' : 'A', r % 8, + reg_count[r], + 100.0*double(reg_count[r])/double(tot_reg_count), + 100.0*double(cum_reg_count)/double(tot_reg_count)); + } +#endif + + // exit_table68k(); +} + +#ifdef UAE +#else +bool compiler_use_jit(void) +{ + // Check for the "jit" prefs item + if (!PrefsFindBool("jit")) + return false; + + // Don't use JIT if translation cache size is less then MIN_CACHE_SIZE KB + if (PrefsFindInt32("jitcachesize") < MIN_CACHE_SIZE) { + write_log(" : translation cache size is less than %d KB. Disabling JIT.\n", MIN_CACHE_SIZE); + return false; + } + + return true; +} +#endif + +static void init_comp(void) +{ + int i; + uae_s8* cb=can_byte; + uae_s8* cw=can_word; + uae_s8* au=always_used; + +#ifdef RECORD_REGISTER_USAGE + for (i=0;i<16;i++) + reg_count_local[i] = 0; +#endif + + for (i=0;idirect_handler_to_use; +} + +/* This version assumes that it is writing *real* memory, and *will* fail + * if that assumption is wrong! No branches, no second chances, just + * straight go-for-it attitude */ + +static void writemem_real(int address, int source, int size, int tmp, int clobber) +{ + int f=tmp; + +#ifdef NATMEM_OFFSET + if (canbang) { /* Woohoo! go directly at the memory! */ + if (clobber) + f=source; + + switch(size) { + case 1: mov_b_bRr(address,source,MEMBaseDiff); break; + case 2: mov_w_rr(f,source); mid_bswap_16(f); mov_w_bRr(address,f,MEMBaseDiff); break; + case 4: mov_l_rr(f,source); mid_bswap_32(f); mov_l_bRr(address,f,MEMBaseDiff); break; + } + forget_about(tmp); + forget_about(f); + return; + } +#endif + +#ifdef UAE + mov_l_rr(f,address); + shrl_l_ri(f,16); /* The index into the baseaddr table */ + mov_l_rm_indexed(f,uae_p32(baseaddr),f,SIZEOF_VOID_P); /* FIXME: is SIZEOF_VOID_P correct? */ + + if (address==source) { /* IBrowse does this! */ + if (size > 1) { + add_l(f,address); /* f now holds the final address */ + switch (size) { + case 2: mid_bswap_16(source); mov_w_Rr(f,source,0); + mid_bswap_16(source); return; + case 4: mid_bswap_32(source); mov_l_Rr(f,source,0); + mid_bswap_32(source); return; + } + } + } + switch (size) { /* f now holds the offset */ + case 1: mov_b_mrr_indexed(address,f,1,source); break; + case 2: mid_bswap_16(source); mov_w_mrr_indexed(address,f,1,source); + mid_bswap_16(source); break; /* base, index, source */ + case 4: mid_bswap_32(source); mov_l_mrr_indexed(address,f,1,source); + mid_bswap_32(source); break; + } +#endif +} + +#ifdef UAE +static inline void writemem(int address, int source, int offset, int size, int tmp) +{ + int f=tmp; + + mov_l_rr(f,address); + shrl_l_ri(f,16); /* The index into the mem bank table */ + mov_l_rm_indexed(f,uae_p32(mem_banks),f,SIZEOF_VOID_P); /* FIXME: is SIZEOF_VOID_P correct? */ + /* Now f holds a pointer to the actual membank */ + mov_l_rR(f,f,offset); + /* Now f holds the address of the b/w/lput function */ + call_r_02(f,address,source,4,size); + forget_about(tmp); +} +#endif + +void writebyte(int address, int source, int tmp) +{ +#ifdef UAE + if ((special_mem & S_WRITE) || distrust_byte()) + writemem_special(address, source, 5 * SIZEOF_VOID_P, 1, tmp); + else +#endif + writemem_real(address,source,1,tmp,0); +} + +static inline void writeword_general(int address, int source, int tmp, + int clobber) +{ +#ifdef UAE + if ((special_mem & S_WRITE) || distrust_word()) + writemem_special(address, source, 4 * SIZEOF_VOID_P, 2, tmp); + else +#endif + writemem_real(address,source,2,tmp,clobber); +} + +void writeword_clobber(int address, int source, int tmp) +{ + writeword_general(address,source,tmp,1); +} + +void writeword(int address, int source, int tmp) +{ + writeword_general(address,source,tmp,0); +} + +static inline void writelong_general(int address, int source, int tmp, + int clobber) +{ +#ifdef UAE + if ((special_mem & S_WRITE) || distrust_long()) + writemem_special(address, source, 3 * SIZEOF_VOID_P, 4, tmp); + else +#endif + writemem_real(address,source,4,tmp,clobber); +} + +void writelong_clobber(int address, int source, int tmp) +{ + writelong_general(address,source,tmp,1); +} + +void writelong(int address, int source, int tmp) +{ + writelong_general(address,source,tmp,0); +} + + + +/* This version assumes that it is reading *real* memory, and *will* fail + * if that assumption is wrong! No branches, no second chances, just + * straight go-for-it attitude */ + +static void readmem_real(int address, int dest, int size, int tmp) +{ + int f=tmp; + + if (size==4 && address!=dest) + f=dest; + +#ifdef NATMEM_OFFSET + if (canbang) { /* Woohoo! go directly at the memory! */ + switch(size) { + case 1: mov_b_brR(dest,address,MEMBaseDiff); break; + case 2: mov_w_brR(dest,address,MEMBaseDiff); mid_bswap_16(dest); break; + case 4: mov_l_brR(dest,address,MEMBaseDiff); mid_bswap_32(dest); break; + } + forget_about(tmp); + (void) f; + return; + } +#endif + +#ifdef UAE + mov_l_rr(f,address); + shrl_l_ri(f,16); /* The index into the baseaddr table */ + mov_l_rm_indexed(f,uae_p32(baseaddr),f,SIZEOF_VOID_P); /* FIXME: is SIZEOF_VOID_P correct? */ + /* f now holds the offset */ + + switch(size) { + case 1: mov_b_rrm_indexed(dest,address,f,1); break; + case 2: mov_w_rrm_indexed(dest,address,f,1); mid_bswap_16(dest); break; + case 4: mov_l_rrm_indexed(dest,address,f,1); mid_bswap_32(dest); break; + } + forget_about(tmp); +#endif +} + + + +#ifdef UAE +static inline void readmem(int address, int dest, int offset, int size, int tmp) +{ + int f=tmp; + + mov_l_rr(f,address); + shrl_l_ri(f,16); /* The index into the mem bank table */ + mov_l_rm_indexed(f,uae_p32(mem_banks),f,SIZEOF_VOID_P); /* FIXME: is SIZEOF_VOID_P correct? */ + /* Now f holds a pointer to the actual membank */ + mov_l_rR(f,f,offset); + /* Now f holds the address of the b/w/lget function */ + call_r_11(dest,f,address,size,4); + forget_about(tmp); +} +#endif + +void readbyte(int address, int dest, int tmp) +{ +#ifdef UAE + if ((special_mem & S_READ) || distrust_byte()) + readmem_special(address, dest, 2 * SIZEOF_VOID_P, 1, tmp); + else +#endif + readmem_real(address,dest,1,tmp); +} + +void readword(int address, int dest, int tmp) +{ +#ifdef UAE + if ((special_mem & S_READ) || distrust_word()) + readmem_special(address, dest, 1 * SIZEOF_VOID_P, 2, tmp); + else +#endif + readmem_real(address,dest,2,tmp); +} + +void readlong(int address, int dest, int tmp) +{ +#ifdef UAE + if ((special_mem & S_READ) || distrust_long()) + readmem_special(address, dest, 0 * SIZEOF_VOID_P, 4, tmp); + else +#endif + readmem_real(address,dest,4,tmp); +} + +void get_n_addr(int address, int dest, int tmp) +{ +#ifdef UAE + if (special_mem || distrust_addr()) { + /* This one might appear a bit odd... */ + readmem(address, dest, 6 * SIZEOF_VOID_P, 4, tmp); + return; + } +#endif + + // a is the register containing the virtual address + // after the offset had been fetched + int a=tmp; + + // f is the register that will contain the offset + int f=tmp; + + // a == f == tmp if (address == dest) + if (address!=dest) { + a=address; + f=dest; + } + +#ifdef NATMEM_OFFSET + if (canbang) { +//#if FIXED_ADDRESSING + lea_l_brr(dest,address,MEMBaseDiff); +//#else +//# error "Only fixed adressing mode supported" +//#endif + forget_about(tmp); + (void) f; + (void) a; + return; + } +#endif + +#ifdef UAE + mov_l_rr(f,address); + mov_l_rr(dest,address); // gb-- nop if dest==address + shrl_l_ri(f,16); + mov_l_rm_indexed(f,uae_p32(baseaddr),f,SIZEOF_VOID_P); /* FIXME: is SIZEOF_VOID_P correct? */ + add_l(dest,f); + forget_about(tmp); +#endif +} + +void get_n_addr_jmp(int address, int dest, int tmp) +{ +#ifdef WINUAE_ARANYM + /* For this, we need to get the same address as the rest of UAE + would --- otherwise we end up translating everything twice */ + get_n_addr(address,dest,tmp); +#else + int f=tmp; + if (address!=dest) + f=dest; + mov_l_rr(f,address); + shrl_l_ri(f,16); /* The index into the baseaddr bank table */ + mov_l_rm_indexed(dest,uae_p32(baseaddr),f,SIZEOF_VOID_P); /* FIXME: is SIZEOF_VOID_P correct? */ + add_l(dest,address); + and_l_ri (dest, ~1); + forget_about(tmp); +#endif +} + + +/* base is a register, but dp is an actual value. + target is a register, as is tmp */ +void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp) +{ + int reg = (dp >> 12) & 15; + int regd_shift=(dp >> 9) & 3; + + if (dp & 0x100) { + int ignorebase=(dp&0x80); + int ignorereg=(dp&0x40); + int addbase=0; + int outer=0; + + if ((dp & 0x30) == 0x20) addbase = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); + if ((dp & 0x30) == 0x30) addbase = comp_get_ilong((m68k_pc_offset+=4)-4); + + if ((dp & 0x3) == 0x2) outer = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); + if ((dp & 0x3) == 0x3) outer = comp_get_ilong((m68k_pc_offset+=4)-4); + + if ((dp & 0x4) == 0) { /* add regd *before* the get_long */ + if (!ignorereg) { + if ((dp & 0x800) == 0) + sign_extend_16_rr(target,reg); + else + mov_l_rr(target,reg); + shll_l_ri(target,regd_shift); + } + else + mov_l_ri(target,0); + + /* target is now regd */ + if (!ignorebase) + add_l(target,base); + add_l_ri(target,addbase); + if (dp&0x03) readlong(target,target,tmp); + } else { /* do the getlong first, then add regd */ + if (!ignorebase) { + mov_l_rr(target,base); + add_l_ri(target,addbase); + } + else + mov_l_ri(target,addbase); + if (dp&0x03) readlong(target,target,tmp); + + if (!ignorereg) { + if ((dp & 0x800) == 0) + sign_extend_16_rr(tmp,reg); + else + mov_l_rr(tmp,reg); + shll_l_ri(tmp,regd_shift); + /* tmp is now regd */ + add_l(target,tmp); + } + } + add_l_ri(target,outer); + } + else { /* 68000 version */ + if ((dp & 0x800) == 0) { /* Sign extend */ + sign_extend_16_rr(target,reg); + lea_l_brr_indexed(target,base,target,1< : 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 + max_compile_start = compiled_code + cache_size*1024 - BYTES_PER_INST; +#endif + current_compile_p = compiled_code; + current_cache_size = 0; +#if defined(USE_DATA_BUFFER) + reset_data_buffer(); +#endif + } +} + +extern void op_illg_1 (uae_u32 opcode) REGPARAM; + +static void calc_checksum(blockinfo* bi, uae_u32* c1, uae_u32* c2) +{ + uae_u32 k1 = 0; + uae_u32 k2 = 0; + +#if USE_CHECKSUM_INFO + checksum_info *csi = bi->csi; + Dif(!csi) abort(); + while (csi) { + uae_s32 len = csi->length; + uintptr tmp = (uintptr)csi->start_p; +#else + uae_s32 len = bi->len; + uintptr tmp = (uintptr)bi->min_pcp; +#endif + uae_u32* pos; + + len += (tmp & 3); + tmp &= ~((uintptr)3); + pos = (uae_u32 *)tmp; + + if (len >= 0 && len <= MAX_CHECKSUM_LEN) { + while (len > 0) { + k1 += *pos; + k2 ^= *pos; + pos++; + len -= 4; + } + } + +#if USE_CHECKSUM_INFO + csi = csi->next; + } +#endif + + *c1 = k1; + *c2 = k2; +} + +#if 0 +static void show_checksum(CSI_TYPE* csi) +{ + uae_u32 k1=0; + uae_u32 k2=0; + uae_s32 len=CSI_LENGTH(csi); + uae_u32 tmp=(uintptr)CSI_START_P(csi); + uae_u32* pos; + + len+=(tmp&3); + tmp&=(~3); + pos=(uae_u32*)tmp; + + if (len<0 || len>MAX_CHECKSUM_LEN) { + return; + } + else { + while (len>0) { + jit_log("%08x ",*pos); + pos++; + len-=4; + } + jit_log(" bla"); + } +} +#endif + + +int check_for_cache_miss(void) +{ + blockinfo* bi=get_blockinfo_addr(regs.pc_p); + + if (bi) { + int cl=cacheline(regs.pc_p); + if (bi!=cache_tags[cl+1].bi) { + raise_in_cl_list(bi); + return 1; + } + } + return 0; +} + + +static void recompile_block(void) +{ + /* An existing block's countdown code has expired. We need to make + sure that execute_normal doesn't refuse to recompile due to a + perceived cache miss... */ + blockinfo* bi=get_blockinfo_addr(regs.pc_p); + + Dif (!bi) + jit_abort("recompile_block"); + raise_in_cl_list(bi); + execute_normal(); + return; +} +static void cache_miss(void) +{ + blockinfo* bi=get_blockinfo_addr(regs.pc_p); +#if COMP_DEBUG + uae_u32 cl=cacheline(regs.pc_p); + blockinfo* bi2=get_blockinfo(cl); +#endif + + if (!bi) { + execute_normal(); /* Compile this block now */ + return; + } + Dif (!bi2 || bi==bi2) { + jit_abort("Unexplained cache miss %p %p",bi,bi2); + } + raise_in_cl_list(bi); + return; +} + +static int called_check_checksum(blockinfo* bi); + +static inline int block_check_checksum(blockinfo* bi) +{ + uae_u32 c1,c2; + bool isgood; + + if (bi->status!=BI_NEED_CHECK) + return 1; /* This block is in a checked state */ + + if (bi->c1 || bi->c2) + calc_checksum(bi,&c1,&c2); + else { + c1=c2=1; /* Make sure it doesn't match */ + } + + isgood=(c1==bi->c1 && c2==bi->c2); + + if (isgood) { + /* This block is still OK. So we reactivate. Of course, that + means we have to move it into the needs-to-be-flushed list */ + bi->handler_to_use=bi->handler; + set_dhtu(bi,bi->direct_handler); + bi->status=BI_CHECKING; + isgood=called_check_checksum(bi) != 0; + } + if (isgood) { + jit_log2("reactivate %p/%p (%x %x/%x %x)",bi,bi->pc_p, c1,c2,bi->c1,bi->c2); + remove_from_list(bi); + add_to_active(bi); + raise_in_cl_list(bi); + bi->status=BI_ACTIVE; + } + else { + /* This block actually changed. We need to invalidate it, + and set it up to be recompiled */ + jit_log2("discard %p/%p (%x %x/%x %x)",bi,bi->pc_p, c1,c2,bi->c1,bi->c2); + invalidate_block(bi); + raise_in_cl_list(bi); + } + return isgood; +} + +static int called_check_checksum(blockinfo* bi) +{ + int isgood=1; + int i; + + for (i=0;i<2 && isgood;i++) { + if (bi->dep[i].jmp_off) { + isgood=block_check_checksum(bi->dep[i].target); + } + } + return isgood; +} + +static void check_checksum(void) +{ + blockinfo* bi=get_blockinfo_addr(regs.pc_p); + uae_u32 cl=cacheline(regs.pc_p); + blockinfo* bi2=get_blockinfo(cl); + + /* These are not the droids you are looking for... */ + if (!bi) { + /* Whoever is the primary target is in a dormant state, but + calling it was accidental, and we should just compile this + new block */ + execute_normal(); + return; + } + if (bi!=bi2) { + /* The block was hit accidentally, but it does exist. Cache miss */ + cache_miss(); + return; + } + + if (!block_check_checksum(bi)) + execute_normal(); +} + +static inline void match_states(blockinfo* bi) +{ + int i; + smallstate* s=&(bi->env); + + if (bi->status==BI_NEED_CHECK) { + block_check_checksum(bi); + } + if (bi->status==BI_ACTIVE || + bi->status==BI_FINALIZING) { /* Deal with the *promises* the + block makes (about not using + certain vregs) */ + for (i=0;i<16;i++) { + if (s->virt[i]==L_UNNEEDED) { + jit_log2("unneeded reg %d at %p",i,target); + COMPCALL(forget_about)(i); // FIXME + } + } + } + flush(1); + + /* And now deal with the *demands* the block makes */ + for (i=0;inat[i]; + if (v>=0) { + // printf("Loading reg %d into %d at %p\n",v,i,target); + readreg_specific(v,4,i); + // do_load_reg(i,v); + // setlock(i); + } + } + for (i=0;inat[i]; + if (v>=0) { + unlock2(i); + } + } +} + +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; + for (i=0;idirect_pen=(cpuop_func*)get_target(); + compemu_raw_mov_l_rm(0,(uintptr)&(bi->pc_p)); + compemu_raw_mov_l_mr((uintptr)®s.pc_p,0); + compemu_raw_jmp((uintptr)popall_execute_normal); + + align_target(align_jumps); + bi->direct_pcc=(cpuop_func*)get_target(); + compemu_raw_mov_l_rm(0,(uintptr)&(bi->pc_p)); + compemu_raw_mov_l_mr((uintptr)®s.pc_p,0); + compemu_raw_jmp((uintptr)popall_check_checksum); + flush_cpu_icache((void *)current_compile_p, (void *)target); + current_compile_p=get_target(); + + bi->deplist=NULL; + for (i=0;i<2;i++) { + bi->dep[i].prev_p=NULL; + bi->dep[i].next=NULL; + } + bi->env=default_ss; + bi->status=BI_INVALID; + bi->havestate=0; + //bi->env=empty_ss; +} + +#ifdef UAE +void compemu_reset(void) +{ + set_cache_state(0); +} +#endif + +#ifdef UAE +#else +// OPCODE is in big endian format, use cft_map() beforehand, if needed. +#endif +static inline void reset_compop(int opcode) +{ + compfunctbl[opcode] = NULL; + nfcompfunctbl[opcode] = NULL; +} + +static int read_opcode(const char *p) +{ + int opcode = 0; + for (int i = 0; i < 4; i++) { + int op = p[i]; + switch (op) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + opcode = (opcode << 4) | (op - '0'); + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + opcode = (opcode << 4) | ((op - 'a') + 10); + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + opcode = (opcode << 4) | ((op - 'A') + 10); + break; + default: + return -1; + } + } + return opcode; +} + + +#ifdef USE_JIT_FPU +static struct { + const char *name; + bool *const disabled; +} const jit_opcodes[] = { + { "fbcc", &jit_disable.fbcc }, + { "fdbcc", &jit_disable.fdbcc }, + { "fscc", &jit_disable.fscc }, + { "ftrapcc", &jit_disable.ftrapcc }, + { "fsave", &jit_disable.fsave }, + { "frestore", &jit_disable.frestore }, + { "fmove", &jit_disable.fmove }, + { "fmovec", &jit_disable.fmovec }, + { "fmovem", &jit_disable.fmovem }, + { "fmovecr", &jit_disable.fmovecr }, + { "fint", &jit_disable.fint }, + { "fsinh", &jit_disable.fsinh }, + { "fintrz", &jit_disable.fintrz }, + { "fsqrt", &jit_disable.fsqrt }, + { "flognp1", &jit_disable.flognp1 }, + { "fetoxm1", &jit_disable.fetoxm1 }, + { "ftanh", &jit_disable.ftanh }, + { "fatan", &jit_disable.fatan }, + { "fasin", &jit_disable.fasin }, + { "fatanh", &jit_disable.fatanh }, + { "fsin", &jit_disable.fsin }, + { "ftan", &jit_disable.ftan }, + { "fetox", &jit_disable.fetox }, + { "ftwotox", &jit_disable.ftwotox }, + { "ftentox", &jit_disable.ftentox }, + { "flogn", &jit_disable.flogn }, + { "flog10", &jit_disable.flog10 }, + { "flog2", &jit_disable.flog2 }, + { "fabs", &jit_disable.fabs }, + { "fcosh", &jit_disable.fcosh }, + { "fneg", &jit_disable.fneg }, + { "facos", &jit_disable.facos }, + { "fcos", &jit_disable.fcos }, + { "fgetexp", &jit_disable.fgetexp }, + { "fgetman", &jit_disable.fgetman }, + { "fdiv", &jit_disable.fdiv }, + { "fmod", &jit_disable.fmod }, + { "fadd", &jit_disable.fadd }, + { "fmul", &jit_disable.fmul }, + { "fsgldiv", &jit_disable.fsgldiv }, + { "frem", &jit_disable.frem }, + { "fscale", &jit_disable.fscale }, + { "fsglmul", &jit_disable.fsglmul }, + { "fsub", &jit_disable.fsub }, + { "fsincos", &jit_disable.fsincos }, + { "fcmp", &jit_disable.fcmp }, + { "ftst", &jit_disable.ftst }, +}; + +static bool read_fpu_opcode(const char **pp) +{ + const char *p = *pp; + const char *end; + size_t len; + unsigned int i; + + end = p; + while (*end != '\0' && *end != ',') + end++; + len = end - p; + if (*end != '\0') + end++; + for (i = 0; i < (sizeof(jit_opcodes) / sizeof(jit_opcodes[0])); i++) + { + if (len == strlen(jit_opcodes[i].name) && strncasecmp(jit_opcodes[i].name, p, len) == 0) + { + *jit_opcodes[i].disabled = true; + jit_log(" : disabled %s", jit_opcodes[i].name); + *pp = end; + return true; + } + } + return false; +} +#endif + +static bool merge_blacklist() +{ +#ifdef UAE + const char *blacklist = ""; +#else + const char *blacklist = PrefsFindString("jitblacklist"); +#endif +#ifdef USE_JIT_FPU + for (unsigned int i = 0; i < (sizeof(jit_opcodes) / sizeof(jit_opcodes[0])); i++) + *jit_opcodes[i].disabled = false; +#endif + if (blacklist[0] != '\0') { + const char *p = blacklist; + for (;;) { + if (*p == 0) + return true; + + int opcode1 = read_opcode(p); + if (opcode1 < 0) + { +#ifdef USE_JIT_FPU + if (read_fpu_opcode(&p)) + continue; +#endif + bug(" : invalid opcode %s", p); + return false; + } + p += 4; + + int opcode2 = opcode1; + if (*p == '-') { + p++; + opcode2 = read_opcode(p); + if (opcode2 < 0) + { + bug(" : invalid opcode %s", p); + return false; + } + p += 4; + } + + if (*p == 0 || *p == ',') { + jit_log(" : blacklist opcodes : %04x-%04x", opcode1, opcode2); + for (int opcode = opcode1; opcode <= opcode2; opcode++) + reset_compop(cft_map(opcode)); + + if (*(p++) == ',') + continue; + + return true; + } + + return false; + } + } + return true; +} + +void build_comp(void) +{ +#ifdef FSUAE + if (!g_fs_uae_jit_compiler) { + jit_log("JIT: JIT compiler is not enabled"); + return; + } +#endif + int i; + unsigned long opcode; + const struct comptbl* tbl=op_smalltbl_0_comp_ff; + const struct comptbl* nftbl=op_smalltbl_0_comp_nf; + int count; +#ifdef WINUAE_ARANYM + unsigned int cpu_level = 4; // 68040 +#if 0 + const struct cputbl *nfctbl = op_smalltbl_0_nf; +#endif +#else +#ifdef NOFLAGS_SUPPORT + struct comptbl *nfctbl = (currprefs.cpu_level >= 5 ? op_smalltbl_0_nf + : currprefs.cpu_level == 4 ? op_smalltbl_1_nf + : (currprefs.cpu_level == 2 || currprefs.cpu_level == 3) ? op_smalltbl_2_nf + : currprefs.cpu_level == 1 ? op_smalltbl_3_nf + : ! currprefs.cpu_compatible ? op_smalltbl_4_nf + : op_smalltbl_5_nf); +#endif +#endif + // Initialize target CPU (check for features, e.g. CMOV, rat stalls) + raw_init_cpu(); + +#ifdef NATMEM_OFFSET +#ifdef UAE +#ifdef JIT_EXCEPTION_HANDLER + install_exception_handler(); +#endif +#endif +#endif + + jit_log(" : building compiler function tables"); + + for (opcode = 0; opcode < 65536; opcode++) { + reset_compop(opcode); +#ifdef NOFLAGS_SUPPORT + nfcpufunctbl[opcode] = op_illg; +#endif + prop[opcode].use_flags = FLAG_ALL; + prop[opcode].set_flags = FLAG_ALL; +#ifdef UAE + prop[opcode].is_jump=1; +#else + prop[opcode].cflow = fl_trap; // ILLEGAL instructions do trap +#endif + } + + for (i = 0; tbl[i].opcode < 65536; i++) { +#ifdef UAE + int isjmp = (tbl[i].specific & COMP_OPCODE_ISJUMP); + int isaddx = (tbl[i].specific & COMP_OPCODE_ISADDX); + int iscjmp = (tbl[i].specific & COMP_OPCODE_ISCJUMP); + + prop[cft_map(tbl[i].opcode)].is_jump = isjmp; + prop[cft_map(tbl[i].opcode)].is_const_jump = iscjmp; + prop[cft_map(tbl[i].opcode)].is_addx = isaddx; +#else + int cflow = table68k[tbl[i].opcode].cflow; + if (follow_const_jumps && (tbl[i].specific & COMP_OPCODE_ISCJUMP)) + cflow = fl_const_jump; + else + cflow &= ~fl_const_jump; + prop[cft_map(tbl[i].opcode)].cflow = cflow; +#endif + + bool uses_fpu = (tbl[i].specific & COMP_OPCODE_USES_FPU) != 0; + if (uses_fpu && avoid_fpu) + compfunctbl[cft_map(tbl[i].opcode)] = NULL; + else + compfunctbl[cft_map(tbl[i].opcode)] = tbl[i].handler; + } + + for (i = 0; nftbl[i].opcode < 65536; i++) { + bool uses_fpu = (tbl[i].specific & COMP_OPCODE_USES_FPU) != 0; + if (uses_fpu && avoid_fpu) + nfcompfunctbl[cft_map(nftbl[i].opcode)] = NULL; + else + nfcompfunctbl[cft_map(nftbl[i].opcode)] = nftbl[i].handler; +#ifdef NOFLAGS_SUPPORT + nfcpufunctbl[cft_map(nftbl[i].opcode)] = nfctbl[i].handler; +#endif + } + +#ifdef NOFLAGS_SUPPORT + for (i = 0; nfctbl[i].handler; i++) { + nfcpufunctbl[cft_map(nfctbl[i].opcode)] = nfctbl[i].handler; + } +#endif + + for (opcode = 0; opcode < 65536; opcode++) { + compop_func *f; + compop_func *nff; +#ifdef NOFLAGS_SUPPORT + cpuop_func *nfcf; +#endif + int isaddx; +#ifdef UAE + int isjmp,iscjmp; +#else + int cflow; +#endif + +#ifdef UAE + int cpu_level = (currprefs.cpu_model - 68000) / 10; + if (cpu_level > 4) + cpu_level--; +#endif + if ((instrmnem)table68k[opcode].mnemo == i_ILLG || table68k[opcode].clev > cpu_level) + continue; + + if (table68k[opcode].handler != -1) { + f = compfunctbl[cft_map(table68k[opcode].handler)]; + nff = nfcompfunctbl[cft_map(table68k[opcode].handler)]; +#ifdef NOFLAGS_SUPPORT + nfcf = nfcpufunctbl[cft_map(table68k[opcode].handler)]; +#endif + isaddx = prop[cft_map(table68k[opcode].handler)].is_addx; + prop[cft_map(opcode)].is_addx = isaddx; +#ifdef UAE + isjmp = prop[cft_map(table68k[opcode].handler)].is_jump; + iscjmp = prop[cft_map(table68k[opcode].handler)].is_const_jump; + prop[cft_map(opcode)].is_jump = isjmp; + prop[cft_map(opcode)].is_const_jump = iscjmp; +#else + cflow = prop[cft_map(table68k[opcode].handler)].cflow; + prop[cft_map(opcode)].cflow = cflow; +#endif + compfunctbl[cft_map(opcode)] = f; + nfcompfunctbl[cft_map(opcode)] = nff; +#ifdef NOFLAGS_SUPPORT + Dif (nfcf == op_illg) + abort(); + nfcpufunctbl[cft_map(opcode)] = nfcf; +#endif + } + prop[cft_map(opcode)].set_flags = table68k[opcode].flagdead; + prop[cft_map(opcode)].use_flags = table68k[opcode].flaglive; + /* Unconditional jumps don't evaluate condition codes, so they + * don't actually use any flags themselves */ +#ifdef UAE + if (prop[cft_map(opcode)].is_const_jump) +#else + if (prop[cft_map(opcode)].cflow & fl_const_jump) +#endif + prop[cft_map(opcode)].use_flags = 0; + } +#ifdef NOFLAGS_SUPPORT + for (i = 0; nfctbl[i].handler != NULL; i++) { + if (nfctbl[i].specific) + nfcpufunctbl[cft_map(tbl[i].opcode)] = nfctbl[i].handler; + } +#endif + + /* Merge in blacklist */ + if (!merge_blacklist()) + { + jit_log(" : blacklist merge failure!"); + } + + count=0; + for (opcode = 0; opcode < 65536; opcode++) { + if (compfunctbl[cft_map(opcode)]) + count++; + } + jit_log(" : supposedly %d compileable opcodes!",count); + + /* Initialise state */ + create_popalls(); + alloc_cache(); + reset_lists(); + + for (i=0;ipc_p)].handler=(cpuop_func*)popall_execute_normal; + cache_tags[cacheline(bi->pc_p)+1].bi=NULL; + dbi=bi; bi=bi->next; + free_blockinfo(dbi); + } + bi=dormant; + while(bi) { + cache_tags[cacheline(bi->pc_p)].handler=(cpuop_func*)popall_execute_normal; + cache_tags[cacheline(bi->pc_p)+1].bi=NULL; + dbi=bi; bi=bi->next; + free_blockinfo(dbi); + } + + reset_lists(); + if (!compiled_code) + return; + +#if defined(USE_DATA_BUFFER) + reset_data_buffer(); +#endif + + current_compile_p=compiled_code; +#ifdef UAE + set_special(0); /* To get out of compiled code */ +#else + SPCFLAGS_SET( SPCFLAG_JIT_EXEC_RETURN ); /* To get out of compiled code */ +#endif +} + + +/* "Soft flushing" --- instead of actually throwing everything away, + we simply mark everything as "needs to be checked". +*/ + +static inline void flush_icache_lazy(void) +{ + blockinfo* bi; + blockinfo* bi2; + + if (!active) + return; + + bi=active; + while (bi) { + uae_u32 cl=cacheline(bi->pc_p); + if (bi->status==BI_INVALID || + bi->status==BI_NEED_RECOMP) { + if (bi==cache_tags[cl+1].bi) + cache_tags[cl].handler=(cpuop_func*)popall_execute_normal; + bi->handler_to_use=(cpuop_func*)popall_execute_normal; + set_dhtu(bi,bi->direct_pen); + bi->status=BI_INVALID; + } + else { + if (bi==cache_tags[cl+1].bi) + cache_tags[cl].handler=(cpuop_func*)popall_check_checksum; + bi->handler_to_use=(cpuop_func*)popall_check_checksum; + set_dhtu(bi,bi->direct_pcc); + bi->status=BI_NEED_CHECK; + } + bi2=bi; + bi=bi->next; + } + /* bi2 is now the last entry in the active list */ + bi2->next=dormant; + if (dormant) + dormant->prev_p=&(bi2->next); + + dormant=active; + active->prev_p=&dormant; + active=NULL; +} + + +#if 0 +static void flush_icache_range(uae_u32 start, uae_u32 length) +{ + if (!active) + return; + +#if LAZY_FLUSH_ICACHE_RANGE + uae_u8 *start_p = get_real_address(start); + blockinfo *bi = active; + while (bi) { +#if USE_CHECKSUM_INFO + bool invalidate = false; + for (checksum_info *csi = bi->csi; csi && !invalidate; csi = csi->next) + invalidate = (((start_p - csi->start_p) < csi->length) || + ((csi->start_p - start_p) < length)); +#else + // Assume system is consistent and would invalidate the right range + const bool invalidate = (bi->pc_p - start_p) < length; +#endif + if (invalidate) { + uae_u32 cl = cacheline(bi->pc_p); + if (bi == cache_tags[cl + 1].bi) + cache_tags[cl].handler = (cpuop_func *)popall_execute_normal; + bi->handler_to_use = (cpuop_func *)popall_execute_normal; + set_dhtu(bi, bi->direct_pen); + bi->status = BI_NEED_RECOMP; + } + bi = bi->next; + } + return; +#else + UNUSED(start); + UNUSED(length); +#endif + flush_icache(); +} +#endif + + +int failure; + +#ifdef UAE +static inline unsigned int get_opcode_cft_map(unsigned int f) +{ + return ((f >> 8) & 255) | ((f & 255) << 8); +} +#define DO_GET_OPCODE(a) (get_opcode_cft_map((uae_u16)*(a))) +#else +#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU) +# define DO_GET_OPCODE(a) (do_get_mem_word_unswapped((uae_u16 *)(a))) +#else +# define DO_GET_OPCODE(a) (do_get_mem_word((uae_u16 *)(a))) +#endif +#endif + +#ifdef JIT_DEBUG +static uae_u8 *last_regs_pc_p = 0; +static uae_u8 *last_compiled_block_addr = 0; + +void compiler_dumpstate(void) +{ + if (!JITDebug) + return; + + jit_log("### Host addresses"); + jit_log("MEM_BASE : %lx", (unsigned long)MEMBaseDiff); + jit_log("PC_P : %p", ®s.pc_p); + jit_log("SPCFLAGS : %p", ®s.spcflags); + jit_log("D0-D7 : %p-%p", ®s.regs[0], ®s.regs[7]); + jit_log("A0-A7 : %p-%p", ®s.regs[8], ®s.regs[15]); + jit_log(" "); + + jit_log("### M68k processor state"); + m68k_dumpstate(stderr, 0); + jit_log(" "); + + jit_log("### Block in Atari address space"); + jit_log("M68K block : %p", + (void *)(uintptr)last_regs_pc_p); + if (last_regs_pc_p != 0) { + jit_log("Native block : %p (%d bytes)", + (void *)last_compiled_block_addr, + get_blockinfo_addr(last_regs_pc_p)->direct_handler_size); + } + jit_log(" "); +} +#endif + + +#if 0 /* debugging helpers; activate as needed */ +static void print_exc_frame(uae_u32 opcode) +{ + int nr = (opcode & 0x0f) + 32; + if (nr != 0x45 && /* Timer-C */ + nr != 0x1c && /* VBL */ + nr != 0x46) /* ACIA */ + { + memptr sp = m68k_areg(regs, 7); + uae_u16 sr = get_word(sp); + fprintf(stderr, "Exc:%02x SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x", nr, sp, regs.usp, sr, get_long(sp + 2), get_word(sp + 6)); + if (nr >= 32 && nr < 48) + { + fprintf(stderr, " Opcode: $%04x", sr & 0x2000 ? get_word(sp + 8) : get_word(regs.usp)); + } + fprintf(stderr, "\n"); + } +} + +static void push_all_nat(void) +{ + raw_pushfl(); + raw_push_l_r(EAX_INDEX); + raw_push_l_r(ECX_INDEX); + raw_push_l_r(EDX_INDEX); + raw_push_l_r(EBX_INDEX); + raw_push_l_r(EBP_INDEX); + raw_push_l_r(EDI_INDEX); + raw_push_l_r(ESI_INDEX); + raw_push_l_r(R8_INDEX); + raw_push_l_r(R9_INDEX); + raw_push_l_r(R10_INDEX); + raw_push_l_r(R11_INDEX); + raw_push_l_r(R12_INDEX); + raw_push_l_r(R13_INDEX); + raw_push_l_r(R14_INDEX); + raw_push_l_r(R15_INDEX); +} + +static void pop_all_nat(void) +{ + raw_pop_l_r(R15_INDEX); + raw_pop_l_r(R14_INDEX); + raw_pop_l_r(R13_INDEX); + raw_pop_l_r(R12_INDEX); + raw_pop_l_r(R11_INDEX); + raw_pop_l_r(R10_INDEX); + raw_pop_l_r(R9_INDEX); + raw_pop_l_r(R8_INDEX); + raw_pop_l_r(ESI_INDEX); + raw_pop_l_r(EDI_INDEX); + raw_pop_l_r(EBP_INDEX); + raw_pop_l_r(EBX_INDEX); + raw_pop_l_r(EDX_INDEX); + raw_pop_l_r(ECX_INDEX); + raw_pop_l_r(EAX_INDEX); + raw_popfl(); +} +#endif + +#if 0 +static void print_inst(void) +{ + disasm_m68k_block(regs.fault_pc + (uint8 *)MEMBaseDiff, 1); +} +#endif + + +#ifdef UAE +void compile_block(cpu_history *pc_hist, int blocklen, int totcycles) +{ + if (cache_enabled && compiled_code && currprefs.cpu_model >= 68020) { +#else +static void compile_block(cpu_history* pc_hist, int blocklen) +{ + if (cache_enabled && compiled_code) { +#endif +#ifdef PROFILE_COMPILE_TIME + compile_count++; + clock_t start_time = clock(); +#endif +#ifdef JIT_DEBUG + bool disasm_block = false; +#endif + + /* OK, here we need to 'compile' a block */ + int i; + int r; + int was_comp=0; + uae_u8 liveflags[MAXRUN+1]; +#if USE_CHECKSUM_INFO + bool trace_in_rom = isinrom((uintptr)pc_hist[0].location) != 0; + uintptr max_pcp=(uintptr)pc_hist[blocklen - 1].location; + uintptr min_pcp=max_pcp; +#else + uintptr max_pcp=(uintptr)pc_hist[0].location; + uintptr min_pcp=max_pcp; +#endif + uae_u32 cl=cacheline(pc_hist[0].location); + void* specflags=(void*)®s.spcflags; + blockinfo* bi=NULL; + blockinfo* bi2; + int extra_len=0; + + redo_current_block=0; + if (current_compile_p >= MAX_COMPILE_PTR) + flush_icache_hard(); + + alloc_blockinfos(); + + bi=get_blockinfo_addr_new(pc_hist[0].location,0); + bi2=get_blockinfo(cl); + + optlev=bi->optlevel; + if (bi->status!=BI_INVALID) { + Dif (bi!=bi2) { + /* I don't think it can happen anymore. Shouldn't, in + any case. So let's make sure... */ + jit_abort("WOOOWOO count=%d, ol=%d %p %p", bi->count,bi->optlevel,bi->handler_to_use, cache_tags[cl].handler); + } + + Dif (bi->count!=-1 && bi->status!=BI_NEED_RECOMP) { + jit_abort("bi->count=%d, bi->status=%d,bi->optlevel=%d",bi->count,bi->status,bi->optlevel); + /* What the heck? We are not supposed to be here! */ + } + } + if (bi->count==-1) { + optlev++; + while (!optcount[optlev]) + optlev++; + bi->count=optcount[optlev]-1; + } + current_block_pc_p=(uintptr)pc_hist[0].location; + + remove_deps(bi); /* We are about to create new code */ + bi->optlevel=optlev; + bi->pc_p=(uae_u8*)pc_hist[0].location; +#if USE_CHECKSUM_INFO + free_checksum_info_chain(bi->csi); + bi->csi = NULL; +#endif + + liveflags[blocklen]=FLAG_ALL; /* All flags needed afterwards */ + i=blocklen; + while (i--) { + uae_u16* currpcp=pc_hist[i].location; + uae_u32 op=DO_GET_OPCODE(currpcp); + +#if USE_CHECKSUM_INFO + trace_in_rom = trace_in_rom && isinrom((uintptr)currpcp); + if (follow_const_jumps && is_const_jump(op)) { + checksum_info *csi = alloc_checksum_info(); + csi->start_p = (uae_u8 *)min_pcp; + csi->length = max_pcp - min_pcp + LONGEST_68K_INST; + csi->next = bi->csi; + bi->csi = csi; + max_pcp = (uintptr)currpcp; + } + min_pcp = (uintptr)currpcp; +#else + if ((uintptr)currpcpmax_pcp) + max_pcp=(uintptr)currpcp; +#endif + +#ifdef UAE + if (!currprefs.compnf) { + liveflags[i]=FLAG_ALL; + } + else +#endif + { + liveflags[i] = ((liveflags[i+1] & (~prop[op].set_flags))|prop[op].use_flags); + if (prop[op].is_addx && (liveflags[i+1]&FLAG_Z)==0) + liveflags[i]&= ~FLAG_Z; + } + } + +#if USE_CHECKSUM_INFO + checksum_info *csi = alloc_checksum_info(); + csi->start_p = (uae_u8 *)min_pcp; + csi->length = max_pcp - min_pcp + LONGEST_68K_INST; + csi->next = bi->csi; + bi->csi = csi; +#endif + + bi->needed_flags=liveflags[0]; + + align_target(align_loops); + was_comp=0; + + bi->direct_handler=(cpuop_func*)get_target(); + set_dhtu(bi,bi->direct_handler); + bi->status=BI_COMPILING; + current_block_start_target=(uintptr)get_target(); + + log_startblock(); + + if (bi->count>=0) { /* Need to generate countdown code */ + compemu_raw_mov_l_mi((uintptr)®s.pc_p,(uintptr)pc_hist[0].location); + compemu_raw_sub_l_mi((uintptr)&(bi->count),1); + compemu_raw_jl((uintptr)popall_recompile_block); + } + if (optlev==0) { /* No need to actually translate */ + /* Execute normally without keeping stats */ + compemu_raw_mov_l_mi((uintptr)®s.pc_p,(uintptr)pc_hist[0].location); + compemu_raw_jmp((uintptr)popall_exec_nostats); + } + else { + reg_alloc_run=0; + next_pc_p=0; + taken_pc_p=0; + branch_cc=0; // Only to be initialized. Will be set together with next_pc_p + + comp_pc_p=(uae_u8*)pc_hist[0].location; + init_comp(); + was_comp=1; + +#ifdef USE_CPU_EMUL_SERVICES + compemu_raw_sub_l_mi((uintptr)&emulated_ticks,blocklen); + compemu_raw_jcc_b_oponly(NATIVE_CC_GT); + uae_u8 *branchadd=get_target(); + skip_byte(); + raw_dec_sp(STACK_SHADOW_SPACE); + compemu_raw_call((uintptr)cpu_do_check_ticks); + raw_inc_sp(STACK_SHADOW_SPACE); + *branchadd=get_target()-(branchadd+1); +#endif + +#ifdef JIT_DEBUG + if (JITDebug) { + compemu_raw_mov_l_mi((uintptr)&last_regs_pc_p,(uintptr)pc_hist[0].location); + compemu_raw_mov_l_mi((uintptr)&last_compiled_block_addr,current_block_start_target); + } +#endif + + for (i=0;i1) { + failure=0; + if (!was_comp) { + comp_pc_p=(uae_u8*)pc_hist[i].location; + init_comp(); + } + was_comp=1; + +#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K) +/* debugging helpers; activate as needed */ +#if 1 + disasm_this_inst = false; + const uae_u8 *start_m68k_thisinst = (const uae_u8 *)pc_hist[i].location; + uae_u8 *start_native_thisinst = get_target(); +#endif +#endif + +#ifdef WINUAE_ARANYM + bool isnop = do_get_mem_word(pc_hist[i].location) == 0x4e71 || + ((i + 1) < blocklen && do_get_mem_word(pc_hist[i+1].location) == 0x4e71); + + if (isnop) + compemu_raw_mov_l_mi((uintptr)®s.fault_pc, ((uintptr)(pc_hist[i].location)) - MEMBaseDiff); +#endif + + comptbl[opcode](opcode); + freescratch(); + if (!(liveflags[i+1] & FLAG_CZNV)) { + /* We can forget about flags */ + dont_care_flags(); + } +#if INDIVIDUAL_INST + flush(1); + nop(); + flush(1); + was_comp=0; +#endif +#ifdef WINUAE_ARANYM + /* + * workaround for buserror handling: on a "nop", write registers back + */ + if (isnop) + { + flush(1); + nop(); + was_comp=0; + } +#endif +#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K) + +/* debugging helpers; activate as needed */ +#if 0 + disasm_m68k_block(start_m68k_thisinst, 1); + push_all_nat(); + compemu_raw_mov_l_mi(uae_p32(®s.fault_pc), (uintptr)start_m68k_thisinst - MEMBaseDiff); + raw_dec_sp(STACK_SHADOW_SPACE); + compemu_raw_call(uae_p32(print_instn)); + raw_inc_sp(STACK_SHADOW_SPACE); + pop_all_nat(); +#endif + + if (disasm_this_inst) + { + disasm_m68k_block(start_m68k_thisinst, 1); +#if 1 + disasm_native_block(start_native_thisinst, get_target() - start_native_thisinst); +#endif + +#if 0 + push_all_nat(); + + raw_dec_sp(STACK_SHADOW_SPACE); + compemu_raw_mov_l_ri(REG_PAR1, (uae_u32)cft_map(opcode)); + compemu_raw_call((uintptr)print_exc_frame); + raw_inc_sp(STACK_SHADOW_SPACE); + + pop_all_nat(); +#endif + + if (failure) + { + bug("(discarded)"); + target = start_native_thisinst; + } + } +#endif + } + + if (failure) { + if (was_comp) { + flush(1); + was_comp=0; + } + compemu_raw_mov_l_ri(REG_PAR1,(uae_u32)opcode); +#if USE_NORMAL_CALLING_CONVENTION + raw_push_l_r(REG_PAR1); +#endif + compemu_raw_mov_l_mi((uintptr)®s.pc_p, + (uintptr)pc_hist[i].location); + raw_dec_sp(STACK_SHADOW_SPACE); + compemu_raw_call((uintptr)cputbl[opcode]); + raw_inc_sp(STACK_SHADOW_SPACE); +#ifdef PROFILE_UNTRANSLATED_INSNS + // raw_cputbl_count[] is indexed with plain opcode (in m68k order) + compemu_raw_add_l_mi((uintptr)&raw_cputbl_count[cft_map(opcode)],1); +#endif +#if USE_NORMAL_CALLING_CONVENTION + raw_inc_sp(4); +#endif + + if (i < blocklen - 1) { + uae_u8* branchadd; + + /* if (SPCFLAGS_TEST(SPCFLAG_ALL)) popall_do_nothing() */ + compemu_raw_mov_l_rm(0, (uintptr)specflags); + compemu_raw_test_l_rr(0,0); +#if defined(USE_DATA_BUFFER) + data_check_end(8, 64); // just a pessimistic guess... +#endif + compemu_raw_jz_b_oponly(); + branchadd=get_target(); + skip_byte(); +#ifdef UAE + raw_sub_l_mi(uae_p32(&countdown),scaled_cycles(totcycles)); +#endif + compemu_raw_jmp((uintptr)popall_do_nothing); + *branchadd = get_target() - (branchadd + 1); + } + } + } +#if 1 /* This isn't completely kosher yet; It really needs to be + be integrated into a general inter-block-dependency scheme */ + if (next_pc_p && taken_pc_p && + was_comp && taken_pc_p==current_block_pc_p) + { + blockinfo* bi1=get_blockinfo_addr_new((void*)next_pc_p,0); + blockinfo* bi2=get_blockinfo_addr_new((void*)taken_pc_p,0); + uae_u8 x=bi1->needed_flags; + + if (x==0xff || 1) { /* To be on the safe side */ + uae_u16* next=(uae_u16*)next_pc_p; + uae_u32 op=DO_GET_OPCODE(next); + + x=FLAG_ALL; + x&=(~prop[op].set_flags); + x|=prop[op].use_flags; + } + + x|=bi2->needed_flags; + if (!(x & FLAG_CZNV)) { + /* We can forget about flags */ + dont_care_flags(); + extra_len+=2; /* The next instruction now is part of this block */ + } + } +#endif + log_flush(); + + if (next_pc_p) { /* A branch was registered */ + uintptr t1=next_pc_p; + uintptr t2=taken_pc_p; + int cc=branch_cc; + + uae_u32* branchadd; + uae_u32* tba; + bigstate tmp; + blockinfo* tbi; + + if (taken_pc_penv))) { + mark_callers_recompile(bi); + } + + big_to_small_state(&live,&(bi->env)); +#endif + +#if USE_CHECKSUM_INFO + remove_from_list(bi); + if (trace_in_rom) { + // No need to checksum that block trace on cache invalidation + free_checksum_info_chain(bi->csi); + bi->csi = NULL; + add_to_dormant(bi); + } + else { + calc_checksum(bi,&(bi->c1),&(bi->c2)); + add_to_active(bi); + } +#else + if (next_pc_p+extra_len>=max_pcp && + next_pc_p+extra_lenlen=max_pcp-min_pcp; + bi->min_pcp=min_pcp; + + remove_from_list(bi); + if (isinrom(min_pcp) && isinrom(max_pcp)) { + add_to_dormant(bi); /* No need to checksum it on cache flush. + Please don't start changing ROMs in + flight! */ + } + else { + calc_checksum(bi,&(bi->c1),&(bi->c2)); + add_to_active(bi); + } +#endif + + current_cache_size += get_target() - current_compile_p; + +#ifdef JIT_DEBUG + bi->direct_handler_size = get_target() - (uae_u8 *)current_block_start_target; + + if (JITDebug && disasm_block) { + uaecptr block_addr = start_pc + ((char *)pc_hist[0].location - (char *)start_pc_p); + jit_log("M68K block @ 0x%08x (%d insns)", block_addr, blocklen); + uae_u32 block_size = ((uae_u8 *)pc_hist[blocklen - 1].location - (uae_u8 *)pc_hist[0].location) + 1; +#ifdef WINUAE_ARANYM + disasm_m68k_block((const uae_u8 *)pc_hist[0].location, block_size); +#endif + jit_log("Compiled block @ %p", pc_hist[0].location); +#ifdef WINUAE_ARANYM + disasm_native_block((const uae_u8 *)current_block_start_target, bi->direct_handler_size); +#endif + UNUSED(block_addr); + } +#endif + + log_dump(); + align_target(align_jumps); + +#ifdef UAE +#ifdef USE_UDIS86 + UDISFN(current_block_start_target, target) +#endif +#endif + + /* This is the non-direct handler */ + bi->handler= + bi->handler_to_use=(cpuop_func *)get_target(); + compemu_raw_cmp_l_mi((uintptr)®s.pc_p,(uintptr)pc_hist[0].location); + compemu_raw_jnz((uintptr)popall_cache_miss); + comp_pc_p=(uae_u8*)pc_hist[0].location; + + bi->status=BI_FINALIZING; + init_comp(); + match_states(bi); + flush(1); + + compemu_raw_jmp((uintptr)bi->direct_handler); + + flush_cpu_icache((void *)current_block_start_target, (void *)target); + current_compile_p=get_target(); + raise_in_cl_list(bi); +#ifdef UAE + bi->nexthandler=current_compile_p; +#endif + + /* We will flush soon, anyway, so let's do it now */ + if (current_compile_p >= MAX_COMPILE_PTR) + flush_icache_hard(); + + bi->status=BI_ACTIVE; + if (redo_current_block) + block_need_recompile(bi); + +#ifdef PROFILE_COMPILE_TIME + compile_time += (clock() - start_time); +#endif +#ifdef UAE + /* Account for compilation time */ + do_extra_cycles(totcycles); +#endif + } + +#ifdef USE_CPU_EMUL_SERVICES + /* Account for compilation time */ + cpu_do_check_ticks(); +#endif +} + +#ifdef UAE + /* Slightly different function defined in newcpu.cpp */ +#else +void do_nothing(void) +{ + /* What did you expect this to do? */ +} +#endif + +#ifdef UAE + /* Different implementation in newcpu.cpp */ +#else +void exec_nostats(void) +{ + for (;;) { + uae_u32 opcode = GET_OPCODE; +#if FLIGHT_RECORDER + m68k_record_step(m68k_getpc(), cft_map(opcode)); +#endif + (*cpufunctbl[opcode])(opcode); + cpu_check_ticks(); + if (end_block(opcode) || SPCFLAGS_TEST(SPCFLAG_ALL)) { + return; /* We will deal with the spcflags in the caller */ + } + } +} +#endif + +#ifdef UAE +/* FIXME: check differences against UAE execute_normal (newcpu.cpp) */ +#else +void execute_normal(void) +{ + if (!check_for_cache_miss()) { + cpu_history pc_hist[MAXRUN]; + int blocklen = 0; +#if 0 && FIXED_ADDRESSING + start_pc_p = regs.pc_p; + start_pc = get_virtual_address(regs.pc_p); +#else + start_pc_p = regs.pc_oldp; + start_pc = regs.pc; +#endif + for (;;) { /* Take note: This is the do-it-normal loop */ + pc_hist[blocklen++].location = (uae_u16 *)regs.pc_p; + uae_u32 opcode = GET_OPCODE; +#if FLIGHT_RECORDER + m68k_record_step(m68k_getpc(), cft_map(opcode)); +#endif + (*cpufunctbl[opcode])(opcode); + cpu_check_ticks(); + if (end_block(opcode) || SPCFLAGS_TEST(SPCFLAG_ALL) || blocklen>=MAXRUN) { + compile_block(pc_hist, blocklen); + return; /* We will deal with the spcflags in the caller */ + } + /* No need to check regs.spcflags, because if they were set, + we'd have ended up inside that "if" */ + } + } +} +#endif + +typedef void (*compiled_handler)(void); + +#ifdef UAE +/* FIXME: check differences against UAE m68k_do_compile_execute */ +#else +void m68k_do_compile_execute(void) +{ + for (;;) { + ((compiled_handler)(pushall_call_handler))(); + /* Whenever we return from that, we should check spcflags */ + if (SPCFLAGS_TEST(SPCFLAG_ALL)) { + if (m68k_do_specialties ()) + return; + } + } +} +#endif + +#ifdef UAE +/* FIXME: check differences against UAE m68k_compile_execute */ +#else +void m68k_compile_execute (void) +{ +setjmpagain: + TRY(prb) { + for (;;) { + if (quit_program > 0) { + if (quit_program == 1) { +#if FLIGHT_RECORDER + dump_flight_recorder(); +#endif + break; + } + quit_program = 0; + m68k_reset (); + } + m68k_do_compile_execute(); + } + } + CATCH(prb) { + jit_log("m68k_compile_execute: exception %d pc=%08x (%08x+%p-%p) fault_pc=%08x addr=%08x -> %08x sp=%08x", + int(prb), + m68k_getpc(), + regs.pc, regs.pc_p, regs.pc_oldp, + regs.fault_pc, + regs.mmu_fault_addr, get_long (regs.vbr + 4*prb), + regs.regs[15]); + flush_icache(); + Exception(prb, 0); + goto setjmpagain; + } +} +#endif + +#endif /* JIT */ + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/compiler/flags_x86.h b/BasiliskII/src/uae_cpu_2021/compiler/flags_x86.h new file mode 100644 index 000000000..310dbcc33 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/flags_x86.h @@ -0,0 +1,52 @@ +/* + * compiler/flags_x86.h - Native flags definitions for IA-32 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * + * Adaptation for Basilisk II and improvements, copyright 2000-2002 + * Gwenole Beauchesne + * + * 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 + */ + +#ifndef NATIVE_FLAGS_X86_H +#define NATIVE_FLAGS_X86_H + +/* Native integer code conditions */ +enum { + NATIVE_CC_HI = 7, + NATIVE_CC_LS = 6, + NATIVE_CC_CC = 3, + NATIVE_CC_CS = 2, + NATIVE_CC_NE = 5, + NATIVE_CC_EQ = 4, + NATIVE_CC_VC = 1, + NATIVE_CC_VS = 0, + NATIVE_CC_PL = 9, + NATIVE_CC_MI = 8, + NATIVE_CC_GE = 13, + NATIVE_CC_LT = 12, + NATIVE_CC_GT = 15, + NATIVE_CC_LE = 14 +}; + +/* FIXME: include/flags_x86.h in UAE had the following values: + NATIVE_CC_VC = 11, + NATIVE_CC_VS = 10, +*/ + +#endif /* NATIVE_FLAGS_X86_H */ diff --git a/BasiliskII/src/uae_cpu_2021/compiler/gencomp.c b/BasiliskII/src/uae_cpu_2021/compiler/gencomp.c new file mode 100644 index 000000000..d301ced78 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/compiler/gencomp.c @@ -0,0 +1,3386 @@ +/* + * compiler/gencomp.c - MC680x0 compilation generator + * + * Based on work Copyright 1995, 1996 Bernd Schmidt + * Changes for UAE-JIT Copyright 2000 Bernd Meyer + * + * Adaptation for ARAnyM/ARM, copyright 2001-2014 + * Milan Jurik, Jens Heitmann + * + * Adaptation for Basilisk II and improvements, copyright 2000-2005 + * Gwenole Beauchesne + * + * 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 + */ + +#define CC_FOR_BUILD 1 +// #include "sysconfig.h" +#define WINUAE_ARANYM + +#include "sysdeps.h" +#include "readcpu.h" + +#undef NDEBUG +#include +#include +#include +#include +#include +#include +#undef abort + +#ifdef UAE +/* +#define DISABLE_I_OR_AND_EOR +#define DISABLE_I_SUB +#define DISABLE_I_SUBA +#define DISABLE_I_SUBX +#define DISABLE_I_ADD +#define DISABLE_I_ADDA +#define DISABLE_I_ADDX +#define DISABLE_I_NEG +#define DISABLE_I_NEGX +#define DISABLE_I_CLR +#define DISABLE_I_NOT +#define DISABLE_I_TST +#define DISABLE_I_BCHG_BCLR_BSET_BTST +#define DISABLE_I_CMPM_CMP +#define DISABLE_I_CMPA +#define DISABLE_I_MOVE +#define DISABLE_I_MOVEA +#define DISABLE_I_SWAP +#define DISABLE_I_EXG +#define DISABLE_I_EXT +#define DISABLE_I_MVEL +#define DISABLE_I_MVMLE +#define DISABLE_I_RTD +#define DISABLE_I_LINK +#define DISABLE_I_UNLK +#define DISABLE_I_RTS +#define DISABLE_I_JSR +#define DISABLE_I_JMP +#define DISABLE_I_BSR +#define DISABLE_I_BCC +#define DISABLE_I_LEA +#define DISABLE_I_PEA +#define DISABLE_I_DBCC +#define DISABLE_I_SCC +#define DISABLE_I_MULU +#define DISABLE_I_MULS +#define DISABLE_I_ASR +#define DISABLE_I_ASL +#define DISABLE_I_LSR +#define DISABLE_I_LSL +#define DISABLE_I_ROL +#define DISABLE_I_ROR +#define DISABLE_I_MULL +#define DISABLE_I_FPP +#define DISABLE_I_FBCC +#define DISABLE_I_FSCC +#define DISABLE_I_MOVE16 +*/ + +#endif /* UAE */ + +#ifdef UAE +#define JIT_PATH "jit/" +#ifdef FSUAE +#define GEN_PATH "gen/" +#else +#define GEN_PATH "jit/" +#endif +#define RETURN "return 0;" +#define RETTYPE "uae_u32" +#define NEXT_CPU_LEVEL 5 +#else +#define JIT_PATH "compiler/" +#define GEN_PATH "" +#define RETURN "return;" +#define RETTYPE "void" +#define NEXT_CPU_LEVEL 4 +#endif + +#define BOOL_TYPE "int" +#define failure global_failure=1 +#define FAILURE global_failure=1 +#define isjump global_isjump=1 +#define is_const_jump global_iscjump=1 +#define isaddx global_isaddx=1 +#define uses_cmov global_cmov=1 +#define mayfail global_mayfail=1 +#define uses_fpu global_fpu=1 + +int hack_opcode; + +static int global_failure; +static int global_isjump; +static int global_iscjump; +static int global_isaddx; +static int global_cmov; +static int long_opcode; +static int global_mayfail; +static int global_fpu; + +static char endstr[1000]; +static char lines[100000]; +static int comp_index=0; + +#include "flags_x86.h" + +#ifndef __attribute__ +# ifndef __GNUC__ +# define __attribute__(x) +# endif +#endif + +#define GENA_GETV_NO_FETCH 0 +#define GENA_GETV_FETCH 1 +#define GENA_GETV_FETCH_ALIGN 2 +#define GENA_MOVEM_DO_INC 0 +#define GENA_MOVEM_NO_INC 1 +#define GENA_MOVEM_MOVE16 2 + + +static int cond_codes[]={-1,-1, + NATIVE_CC_HI,NATIVE_CC_LS, + NATIVE_CC_CC,NATIVE_CC_CS, + NATIVE_CC_NE,NATIVE_CC_EQ, + -1,-1, + NATIVE_CC_PL,NATIVE_CC_MI, + NATIVE_CC_GE,NATIVE_CC_LT, + NATIVE_CC_GT,NATIVE_CC_LE + }; + +__attribute__((format(printf, 1, 2))) +static void comprintf(const char *format, ...) +{ + va_list args; + + va_start(args, format); + comp_index += vsprintf(lines + comp_index, format, args); + va_end(args); +} + +static void com_discard(void) +{ + comp_index = 0; +} + +static void com_flush(void) +{ + int i; + for (i = 0; i < comp_index; i++) + putchar(lines[i]); + com_discard(); +} + + +static FILE *headerfile; +static FILE *stblfile; + +static int using_prefetch; +static int using_exception_3; +static int cpu_level; +static int noflags; + +/* For the current opcode, the next lower level that will have different code. + * Initialized to -1 for each opcode. If it remains unchanged, indicates we + * are done with that opcode. */ +static int next_cpu_level; + +static int *opcode_map; +static int *opcode_next_clev; +static int *opcode_last_postfix; +static unsigned long *counts; + +static void read_counts(void) +{ + FILE *file; + unsigned long opcode, count, total; + char name[20]; + int nr = 0; + memset (counts, 0, 65536 * sizeof *counts); + + file = fopen ("frequent.68k", "r"); + if (file) + { + if (fscanf (file, "Total: %lu\n", &total) != 1) { + assert(0); + } + while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) + { + opcode_next_clev[nr] = NEXT_CPU_LEVEL; + opcode_last_postfix[nr] = -1; + opcode_map[nr++] = opcode; + counts[opcode] = count; + } + fclose (file); + } + if (nr == nr_cpuop_funcs) + return; + for (opcode = 0; opcode < 0x10000; opcode++) + { + if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG + && counts[opcode] == 0) + { + opcode_next_clev[nr] = NEXT_CPU_LEVEL; + opcode_last_postfix[nr] = -1; + opcode_map[nr++] = opcode; + counts[opcode] = count; + } + } + assert (nr == nr_cpuop_funcs); +} + +static int n_braces = 0; +static int insn_n_cycles; + +static void +start_brace (void) +{ + n_braces++; + comprintf ("{"); +} + +static void +close_brace (void) +{ + assert (n_braces > 0); + n_braces--; + comprintf ("}"); +} + +static void +finish_braces (void) +{ + while (n_braces > 0) + close_brace (); + comprintf ("\n"); +} + +static inline void gen_update_next_handler(void) +{ + return; /* Can anything clever be done here? */ +} + +static void gen_writebyte(const char *address, const char *source) +{ + comprintf("\twritebyte(%s, %s, scratchie);\n", address, source); +} + +static void gen_writeword(const char *address, const char *source) +{ + comprintf("\twriteword(%s, %s, scratchie);\n", address, source); +} + +static void gen_writelong(const char *address, const char *source) +{ + comprintf("\twritelong(%s, %s, scratchie);\n", address, source); +} + +static void gen_readbyte(const char *address, const char* dest) +{ + comprintf("\treadbyte(%s, %s, scratchie);\n", address, dest); +} + +static void gen_readword(const char *address, const char *dest) +{ + comprintf("\treadword(%s,%s,scratchie);\n", address, dest); +} + +static void gen_readlong(const char *address, const char *dest) +{ + comprintf("\treadlong(%s, %s, scratchie);\n", address, dest); +} + + + +static const char * +gen_nextilong (void) +{ + static char buffer[80]; + + sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)"); + insn_n_cycles += 4; + + long_opcode=1; + return buffer; +} + +static const char * +gen_nextiword (void) +{ + static char buffer[80]; + + sprintf (buffer, "comp_get_iword((m68k_pc_offset+=2)-2)"); + insn_n_cycles+=2; + + long_opcode=1; + return buffer; +} + +static const char * +gen_nextibyte (void) +{ + static char buffer[80]; + + sprintf (buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)"); + insn_n_cycles += 2; + + long_opcode=1; + return buffer; +} + + +static void +swap_opcode (void) +{ +#ifdef UAE + /* no-op */ +#else + comprintf("#ifdef USE_JIT_FPU\n"); + comprintf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); + comprintf("\topcode = do_byteswap_16(opcode);\n"); + comprintf("#endif\n"); + comprintf("#endif\n"); +#endif +} + +static void +sync_m68k_pc (void) +{ + comprintf(" if (m68k_pc_offset > SYNC_PC_OFFSET)\n sync_m68k_pc();\n"); +} + + +static void gen_set_fault_pc(void) +{ + start_brace(); + comprintf("\tsync_m68k_pc();\n"); + comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); + comprintf("\tint ret=scratchie++;\n" + "\tmov_l_ri(ret,retadd);\n" + "\tmov_l_mr((uintptr)®s.fault_pc,ret);\n"); +} + + +static void make_sr(void) +{ + start_brace(); + comprintf("\tint sr = scratchie++;\n"); + comprintf("\tint tmp = scratchie++;\n"); + comprintf("\tcompemu_make_sr(sr, tmp);\n"); +} + + +static void disasm_this_inst(void) +{ + comprintf("\tdisasm_this_inst = true;\n"); +} + + +/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, + * the calling routine handles Apdi and Aipi modes. + * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ +static void genamode(amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem) +{ + start_brace(); + switch (mode) + { + case Dreg: /* Do we need to check dodgy here? */ + assert (movem == GENA_MOVEM_DO_INC); + if (getv == GENA_GETV_FETCH || getv == GENA_GETV_FETCH_ALIGN) + { + /* We generate the variable even for getv==2, so we can use + it as a destination for MOVE */ + comprintf("\tint %s = %s;\n", name, reg); + } + return; + + case Areg: + assert (movem == GENA_MOVEM_DO_INC); + if (getv == GENA_GETV_FETCH || getv == GENA_GETV_FETCH_ALIGN) + { + /* see above */ + comprintf("\tint %s = dodgy ? scratchie++ : %s + 8;\n", name, reg); + if (getv == GENA_GETV_FETCH) + { + comprintf("\tif (dodgy) \n"); + comprintf("\t\tmov_l_rr(%s, %s + 8);\n", name, reg); + } + } + return; + + case Aind: + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, %s + 8);\n", name, reg); + break; + case Aipi: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_rr(%sa, %s + 8);\n", name, reg); + break; + case Apdi: + switch (size) + { + case sz_byte: + if (movem != GENA_MOVEM_DO_INC) + { + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } else + { + start_brace(); + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tlea_l_brr(%s + 8, %s + 8, (uae_s32)-areg_byteinc[%s]);\n", reg, reg, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } + break; + case sz_word: + if (movem != GENA_MOVEM_DO_INC) + { + comprintf("\tint %sa=dodgy?scratchie++:%s+8;\n", name, reg); + comprintf("\tif (dodgy) \n"); + comprintf("\tmov_l_rr(%sa,8+%s);\n", name, reg); + } else + { + start_brace(); + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tlea_l_brr(%s + 8, %s + 8, -2);\n", reg, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } + break; + case sz_long: + if (movem != GENA_MOVEM_DO_INC) + { + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } else + { + start_brace(); + comprintf("\tint %sa = dodgy ? scratchie++ : %s + 8;\n", name, reg); + comprintf("\tlea_l_brr(%s + 8, %s + 8, -4);\n", reg, reg); + comprintf("\tif (dodgy)\n"); + comprintf("\t\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + } + break; + default: + assert(0); + break; + } + break; + case Ad16: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_rr(%sa, 8 + %s);\n", name, reg); + comprintf("\tlea_l_brr(%sa, %sa, (uae_s32)(uae_s16)%s);\n", name, name, gen_nextiword()); + break; + case Ad8r: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tcalc_disp_ea_020(%s + 8, %s, %sa, scratchie);\n", reg, gen_nextiword(), name); + break; + + case PC16: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n"); + comprintf("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword()); + comprintf("\tmov_l_ri(%sa, address + PC16off);\n", name); + break; + + case PC8r: + comprintf("\tint pctmp = scratchie++;\n"); + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tuae_u32 address = start_pc + ((char *)comp_pc_p - (char *)start_pc_p) + m68k_pc_offset;\n"); + start_brace(); + comprintf("\tmov_l_ri(pctmp,address);\n"); + + comprintf("\tcalc_disp_ea_020(pctmp, %s, %sa, scratchie);\n", gen_nextiword(), name); + break; + case absw: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_ri(%sa, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword()); + break; + case absl: + comprintf("\tint %sa = scratchie++;\n", name); + comprintf("\tmov_l_ri(%sa, %s); /* absl */\n", name, gen_nextilong()); + break; + case imm: + assert (getv == GENA_GETV_FETCH); + switch (size) + { + case sz_byte: + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte()); + break; + case sz_word: + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword()); + break; + case sz_long: + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong()); + break; + default: + assert(0); + break; + } + return; + case imm0: + assert (getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s8)%s);\n", name, gen_nextibyte()); + return; + case imm1: + assert (getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, (uae_s32)(uae_s16)%s);\n", name, gen_nextiword()); + return; + case imm2: + assert (getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, %s);\n", name, gen_nextilong()); + return; + case immi: + assert (getv == GENA_GETV_FETCH); + comprintf("\tint %s = scratchie++;\n", name); + comprintf("\tmov_l_ri(%s, %s);\n", name, reg); + return; + default: + assert(0); + break; + } + + /* We get here for all non-reg non-immediate addressing modes to + * actually fetch the value. */ + if (getv == GENA_GETV_FETCH) + { + char astring[80]; + sprintf(astring, "%sa", name); + switch (size) + { + case sz_byte: + insn_n_cycles += 2; + break; + case sz_word: + insn_n_cycles += 2; + break; + case sz_long: + insn_n_cycles += 4; + break; + default: + assert(0); + break; + } + start_brace(); + comprintf("\tint %s = scratchie++;\n", name); + switch (size) + { + case sz_byte: + gen_readbyte(astring, name); + break; + case sz_word: + gen_readword(astring, name); + break; + case sz_long: + gen_readlong(astring, name); + break; + default: + assert(0); + break; + } + } + + /* We now might have to fix up the register for pre-dec or post-inc + * addressing modes. */ + if (movem == GENA_MOVEM_DO_INC) + { + switch (mode) + { + case Aipi: + switch (size) + { + case sz_byte: + comprintf("\tlea_l_brr(%s + 8,%s + 8, areg_byteinc[%s]);\n", reg, reg, reg); + break; + case sz_word: + comprintf("\tlea_l_brr(%s + 8, %s + 8, 2);\n", reg, reg); + break; + case sz_long: + comprintf("\tlea_l_brr(%s + 8, %s + 8, 4);\n", reg, reg); + break; + default: + assert(0); + break; + } + break; + case Apdi: + break; + default: + break; + } + } +} + +static void genastore(const char *from, amodes mode, const char *reg, wordsizes size, const char *to) +{ + switch (mode) + { + case Dreg: + switch (size) + { + case sz_byte: + comprintf("\tif(%s != %s)\n", reg, from); + comprintf("\t\tmov_b_rr(%s, %s);\n", reg, from); + break; + case sz_word: + comprintf("\tif(%s != %s)\n", reg, from); + comprintf("\t\tmov_w_rr(%s, %s);\n", reg, from); + break; + case sz_long: + comprintf("\tif(%s != %s)\n", reg, from); + comprintf("\t\tmov_l_rr(%s, %s);\n", reg, from); + break; + default: + assert(0); + break; + } + break; + case Areg: + switch (size) + { + case sz_word: + comprintf("\tif(%s + 8 != %s)\n", reg, from); + comprintf("\t\tmov_w_rr(%s + 8, %s);\n", reg, from); + break; + case sz_long: + comprintf("\tif(%s + 8 != %s)\n", reg, from); + comprintf("\t\tmov_l_rr(%s + 8, %s);\n", reg, from); + break; + default: + assert(0); + break; + } + break; + + case Apdi: + case absw: + case PC16: + case PC8r: + case Ad16: + case Ad8r: + case Aipi: + case Aind: + case absl: + { + char astring[80]; + sprintf(astring, "%sa", to); + + switch (size) + { + case sz_byte: + insn_n_cycles += 2; + gen_writebyte(astring, from); + break; + case sz_word: + insn_n_cycles += 2; + gen_writeword(astring, from); + break; + case sz_long: + insn_n_cycles += 4; + gen_writelong(astring, from); + break; + default: + assert(0); + break; + } + } + break; + case imm: + case imm0: + case imm1: + case imm2: + case immi: + assert(0); + break; + default: + assert(0); + break; + } +} + +static void genmov16(uae_u32 opcode, struct instr *curi) +{ + comprintf("\tint src=scratchie++;\n"); + comprintf("\tint dst=scratchie++;\n"); + + if ((opcode & 0xfff8) == 0xf620) { + /* MOVE16 (Ax)+,(Ay)+ */ + comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword()); + comprintf("\tmov_l_rr(src,8+srcreg);\n"); + comprintf("\tmov_l_rr(dst,8+dstreg);\n"); + } + else { + /* Other variants */ + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16); + comprintf("\tmov_l_rr(src,srca);\n"); + comprintf("\tmov_l_rr(dst,dsta);\n"); + } + + /* Align on 16-byte boundaries */ + comprintf("\tand_l_ri(src,~15);\n"); + comprintf("\tand_l_ri(dst,~15);\n"); + + if ((opcode & 0xfff8) == 0xf620) { + comprintf("\tif (srcreg != dstreg)\n"); + comprintf("\tadd_l_ri(srcreg+8,16);\n"); + comprintf("\tadd_l_ri(dstreg+8,16);\n"); + } + else if ((opcode & 0xfff8) == 0xf600) + comprintf("\tadd_l_ri(srcreg+8,16);\n"); + else if ((opcode & 0xfff8) == 0xf608) + comprintf("\tadd_l_ri(dstreg+8,16);\n"); + +#ifdef UAE + comprintf("\tif (special_mem) {\n"); + comprintf("\t\tint tmp=scratchie;\n"); + comprintf("\tscratchie+=4;\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n" + "\tadd_l_ri(src,4);\n" + "\tadd_l_ri(dst,4);\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n" + "\tadd_l_ri(src,4);\n" + "\tadd_l_ri(dst,4);\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n" + "\tadd_l_ri(src,4);\n" + "\tadd_l_ri(dst,4);\n" + "\treadlong(src,tmp,scratchie);\n" + "\twritelong_clobber(dst,tmp,scratchie);\n"); + comprintf("\t} else\n"); +#endif + start_brace(); + comprintf("\tint tmp=scratchie;\n"); + comprintf("\tscratchie+=4;\n" + "\tget_n_addr(src,src,scratchie);\n" + "\tget_n_addr(dst,dst,scratchie);\n" + "\tmov_l_rR(tmp+0,src,0);\n" + "\tmov_l_rR(tmp+1,src,4);\n" + "\tmov_l_rR(tmp+2,src,8);\n" + "\tmov_l_rR(tmp+3,src,12);\n" + "\tmov_l_Rr(dst,tmp+0,0);\n" + "\tforget_about(tmp+0);\n" + "\tmov_l_Rr(dst,tmp+1,4);\n" + "\tforget_about(tmp+1);\n" + "\tmov_l_Rr(dst,tmp+2,8);\n" + "\tforget_about(tmp+2);\n" + "\tmov_l_Rr(dst,tmp+3,12);\n"); + close_brace(); +} + +static void +genmovemel (uae_u16 opcode) +{ + comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); + comprintf ("\tint native=scratchie++;\n"); + comprintf ("\tint i;\n"); + comprintf ("\tsigned char offset=0;\n"); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC); +#ifdef UAE + if (table68k[opcode].size == sz_long) + comprintf("\tif (1 && !special_mem) {\n"); + else + comprintf("\tif (1 && !special_mem) {\n"); +#endif + + /* Fast but unsafe... */ + comprintf("\tget_n_addr(srca,native,scratchie);\n"); + + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch(table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tmov_l_rR(i,native,offset);\n" + "\t\t\tmid_bswap_32(i);\n" + "\t\t\toffset+=4;\n"); + break; + case sz_word: + comprintf("\t\t\tmov_w_rR(i,native,offset);\n" + "\t\t\tmid_bswap_16(i);\n" + "\t\t\tsign_extend_16_rr(i,i);\n" + "\t\t\toffset+=2;\n"); + break; + default: assert(0); + } + comprintf("\t\t}\n" + "\t}"); + if (table68k[opcode].dmode == Aipi) { + comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); + } + /* End fast but unsafe. */ + +#ifdef UAE + comprintf("\t} else {\n"); + + comprintf ("\t\tint tmp=scratchie++;\n"); + + comprintf("\t\tmov_l_rr(tmp,srca);\n"); + comprintf("\t\tfor (i=0;i<16;i++) {\n" + "\t\t\tif ((mask>>i)&1) {\n"); + switch(table68k[opcode].size) { + case sz_long: + comprintf("\t\t\t\treadlong(tmp,i,scratchie);\n" + "\t\t\t\tadd_l_ri(tmp,4);\n"); + break; + case sz_word: + comprintf("\t\t\t\treadword(tmp,i,scratchie);\n" + "\t\t\t\tadd_l_ri(tmp,2);\n"); + break; + default: assert(0); + } + + comprintf("\t\t\t}\n" + "\t\t}\n"); + if (table68k[opcode].dmode == Aipi) { + comprintf("\t\tmov_l_rr(8+dstreg,tmp);\n"); + } + comprintf("\t}\n"); +#endif + +} + + +static void +genmovemle (uae_u16 opcode) +{ + comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); + comprintf ("\tint native=scratchie++;\n"); + comprintf ("\tint i;\n"); + comprintf ("\tint tmp=scratchie++;\n"); + comprintf ("\tsigned char offset=0;\n"); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC); + +#ifdef UAE + /* *Sigh* Some clever geek realized that the fastest way to copy a + buffer from main memory to the gfx card is by using movmle. Good + on her, but unfortunately, gfx mem isn't "real" mem, and thus that + act of cleverness means that movmle must pay attention to special_mem, + or Genetic Species is a rather boring-looking game ;-) */ + if (table68k[opcode].size == sz_long) + comprintf("\tif (1 && !special_mem) {\n"); + else + comprintf("\tif (1 && !special_mem) {\n"); +#endif + comprintf("\tget_n_addr(srca,native,scratchie);\n"); + + if (table68k[opcode].dmode!=Apdi) { + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch(table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tmov_l_rr(tmp,i);\n" + "\t\t\tmid_bswap_32(tmp);\n" + "\t\t\tmov_l_Rr(native,tmp,offset);\n" + "\t\t\toffset+=4;\n"); + break; + case sz_word: + comprintf("\t\t\tmov_l_rr(tmp,i);\n" + "\t\t\tmid_bswap_16(tmp);\n" + "\t\t\tmov_w_Rr(native,tmp,offset);\n" + "\t\t\toffset+=2;\n"); + break; + default: assert(0); + } + } + else { /* Pre-decrement */ + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch(table68k[opcode].size) { + case sz_long: + comprintf("\t\t\toffset-=4;\n" + "\t\t\tmov_l_rr(tmp,15-i);\n" + "\t\t\tmid_bswap_32(tmp);\n" + "\t\t\tmov_l_Rr(native,tmp,offset);\n" + ); + break; + case sz_word: + comprintf("\t\t\toffset-=2;\n" + "\t\t\tmov_l_rr(tmp,15-i);\n" + "\t\t\tmid_bswap_16(tmp);\n" + "\t\t\tmov_w_Rr(native,tmp,offset);\n" + ); + break; + default: assert(0); + } + } + + + comprintf("\t\t}\n" + "\t}"); + if (table68k[opcode].dmode == Apdi) { + comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); + } +#ifdef UAE + comprintf("\t} else {\n"); + + if (table68k[opcode].dmode!=Apdi) { + comprintf("\tmov_l_rr(tmp,srca);\n"); + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch(table68k[opcode].size) { + case sz_long: + comprintf("\t\t\twritelong(tmp,i,scratchie);\n" + "\t\t\tadd_l_ri(tmp,4);\n"); + break; + case sz_word: + comprintf("\t\t\twriteword(tmp,i,scratchie);\n" + "\t\t\tadd_l_ri(tmp,2);\n"); + break; + default: assert(0); + } + } + else { /* Pre-decrement */ + comprintf("\tfor (i=0;i<16;i++) {\n" + "\t\tif ((mask>>i)&1) {\n"); + switch(table68k[opcode].size) { + case sz_long: + comprintf("\t\t\tsub_l_ri(srca,4);\n" + "\t\t\twritelong(srca,15-i,scratchie);\n"); + break; + case sz_word: + comprintf("\t\t\tsub_l_ri(srca,2);\n" + "\t\t\twriteword(srca,15-i,scratchie);\n"); + break; + default: assert(0); + } + } + + + comprintf("\t\t}\n" + "\t}"); + if (table68k[opcode].dmode == Apdi) { + comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n"); + } + comprintf("\t}\n"); +#endif +} + + +static void +duplicate_carry (void) +{ + comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n"); +} + +typedef enum +{ + flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, + flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or, + flag_eor, flag_mov +} +flagtypes; + + +static void +genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst) +{ + if (noflags) { + switch(type) { + case flag_cmp: + comprintf("\tdont_care_flags();\n"); + comprintf("/* Weird --- CMP with noflags ;-) */\n"); + return; + case flag_add: + case flag_sub: + comprintf("\tdont_care_flags();\n"); + { + const char* op; + switch(type) { + case flag_add: op="add"; break; + case flag_sub: op="sub"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("\t%s_b(%s,%s);\n",op,dst,src); + break; + case sz_word: + comprintf("\t%s_w(%s,%s);\n",op,dst,src); + break; + case sz_long: + comprintf("\t%s_l(%s,%s);\n",op,dst,src); + break; + } + return; + } + break; + + case flag_and: + comprintf("\tdont_care_flags();\n"); + switch (size) + { + case sz_byte: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); + comprintf("\tor_l_ri(scratchie,0xffffff00);\n"); + comprintf("\tand_l(%s,scratchie);\n",dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tand_b(%s,%s);\n",dst,src); + break; + case sz_word: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); + comprintf("\tor_l_ri(scratchie,0xffff0000);\n"); + comprintf("\tand_l(%s,scratchie);\n",dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tand_w(%s,%s);\n",dst,src); + break; + case sz_long: + comprintf("\tand_l(%s,%s);\n",dst,src); + break; + } + return; + + case flag_mov: + comprintf("\tdont_care_flags();\n"); + switch (size) + { + case sz_byte: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); + comprintf("\tand_l_ri(%s,0xffffff00);\n",dst); + comprintf("\tor_l(%s,scratchie);\n",dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tmov_b_rr(%s,%s);\n",dst,src); + break; + case sz_word: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); + comprintf("\tand_l_ri(%s,0xffff0000);\n",dst); + comprintf("\tor_l(%s,scratchie);\n",dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\tmov_w_rr(%s,%s);\n",dst,src); + break; + case sz_long: + comprintf("\tmov_l_rr(%s,%s);\n",dst,src); + break; + } + return; + + case flag_or: + case flag_eor: + comprintf("\tdont_care_flags();\n"); + start_brace(); + { + const char* op; + switch(type) { + case flag_or: op="or"; break; + case flag_eor: op="xor"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); + comprintf("\t%s_l(%s,scratchie);\n",op,dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\t%s_b(%s,%s);\n",op,dst,src); + break; + case sz_word: + comprintf("if (kill_rodent(dst)) {\n"); + comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); + comprintf("\t%s_l(%s,scratchie);\n",op,dst); + comprintf("\tforget_about(scratchie);\n"); + comprintf("\t} else \n" + "\t%s_w(%s,%s);\n",op,dst,src); + break; + case sz_long: + comprintf("\t%s_l(%s,%s);\n",op,dst,src); + break; + } + close_brace(); + return; + } + + + case flag_addx: + case flag_subx: + comprintf("\tdont_care_flags();\n"); + { + const char* op; + switch(type) { + case flag_addx: op="adc"; break; + case flag_subx: op="sbb"; break; + default: assert(0); + } + comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ + switch (size) + { + case sz_byte: + comprintf("\t%s_b(%s,%s);\n",op,dst,src); + break; + case sz_word: + comprintf("\t%s_w(%s,%s);\n",op,dst,src); + break; + case sz_long: + comprintf("\t%s_l(%s,%s);\n",op,dst,src); + break; + } + return; + } + break; + default: return; + } + } + + /* Need the flags, but possibly not all of them */ + switch (type) + { + case flag_logical_noclobber: + failure; + /* fall through */ + + case flag_and: + case flag_or: + case flag_eor: + comprintf("\tdont_care_flags();\n"); + start_brace(); + { + const char* op; + switch(type) { + case flag_and: op="and"; break; + case flag_or: op="or"; break; + case flag_eor: op="xor"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\t%s_b(%s,%s);\n",op,dst,src); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\t%s_w(%s,%s);\n",op,dst,src); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\t%s_l(%s,%s);\n",op,dst,src); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + close_brace(); + return; + } + + case flag_mov: + comprintf("\tdont_care_flags();\n"); + start_brace(); + { + switch (size) + { + case sz_byte: + comprintf("\tif (%s!=%s) {\n",src,dst); + comprintf("\tmov_b_ri(%s,0);\n" + "\tstart_needflags();\n",dst); + comprintf("\tor_b(%s,%s);\n",dst,src); + comprintf("\t} else {\n"); + comprintf("\tmov_b_rr(%s,%s);\n",dst,src); + comprintf("\ttest_b_rr(%s,%s);\n",dst,dst); + comprintf("\t}\n"); + break; + case sz_word: + comprintf("\tif (%s!=%s) {\n",src,dst); + comprintf("\tmov_w_ri(%s,0);\n" + "\tstart_needflags();\n",dst); + comprintf("\tor_w(%s,%s);\n",dst,src); + comprintf("\t} else {\n"); + comprintf("\tmov_w_rr(%s,%s);\n",dst,src); + comprintf("\ttest_w_rr(%s,%s);\n",dst,dst); + comprintf("\t}\n"); + break; + case sz_long: + comprintf("\tif (%s!=%s) {\n",src,dst); + comprintf("\tmov_l_ri(%s,0);\n" + "\tstart_needflags();\n",dst); + comprintf("\tor_l(%s,%s);\n",dst,src); + comprintf("\t} else {\n"); + comprintf("\tmov_l_rr(%s,%s);\n",dst,src); + comprintf("\ttest_l_rr(%s,%s);\n",dst,dst); + comprintf("\t}\n"); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + close_brace(); + return; + } + + case flag_logical: + comprintf("\tdont_care_flags();\n"); + start_brace(); + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\ttest_b_rr(%s,%s);\n",value,value); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\ttest_w_rr(%s,%s);\n",value,value); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\ttest_l_rr(%s,%s);\n",value,value); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + close_brace(); + return; + + + case flag_add: + case flag_sub: + case flag_cmp: + comprintf("\tdont_care_flags();\n"); + { + const char* op; + switch(type) { + case flag_add: op="add"; break; + case flag_sub: op="sub"; break; + case flag_cmp: op="cmp"; break; + default: assert(0); + } + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\t%s_b(%s,%s);\n",op,dst,src); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\t%s_w(%s,%s);\n",op,dst,src); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\t%s_l(%s,%s);\n",op,dst,src); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (type!=flag_cmp) { + duplicate_carry(); + } + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + + return; + } + + case flag_addx: + case flag_subx: + uses_cmov; + comprintf("\tdont_care_flags();\n"); + { + const char* op; + switch(type) { + case flag_addx: op="adc"; break; + case flag_subx: op="sbb"; break; + default: assert(0); + } + start_brace(); + comprintf("\tint zero=scratchie++;\n" + "\tint one=scratchie++;\n" + "\tif (needed_flags&FLAG_Z) {\n" + "\tmov_l_ri(zero,0);\n" + "\tmov_l_ri(one,-1);\n" + "\tmake_flags_live();\n" + "\tcmov_l_rr(zero,one,%d);\n" + "\t}\n",NATIVE_CC_NE); + comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ + switch (size) + { + case sz_byte: + comprintf("\tstart_needflags();\n" + "\t%s_b(%s,%s);\n",op,dst,src); + break; + case sz_word: + comprintf("\tstart_needflags();\n" + "\t%s_w(%s,%s);\n",op,dst,src); + break; + case sz_long: + comprintf("\tstart_needflags();\n" + "\t%s_l(%s,%s);\n",op,dst,src); + break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tif (needed_flags&FLAG_Z) {\n"); + comprintf("\tcmov_l_rr(zero,one,%d);\n", NATIVE_CC_NE); + comprintf("\tset_zero(zero, one);\n"); /* No longer need one */ + comprintf("\tlive_flags();\n"); + comprintf("\t}\n"); + comprintf("\tend_needflags();\n"); + duplicate_carry(); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + return; + } + default: + failure; + break; + } +} + +static int /* returns zero for success, non-zero for failure */ +gen_opcode (unsigned int opcode) +{ + struct instr *curi = table68k + opcode; + const char* ssize=NULL; + + insn_n_cycles = 2; + global_failure=0; + long_opcode=0; + global_isjump=0; + global_iscjump=0; + global_isaddx=0; + global_cmov=0; + global_fpu=0; + global_mayfail=0; + hack_opcode=opcode; + endstr[0]=0; + + start_brace (); + comprintf("\tuae_u8 scratchie=S1;\n"); + switch (curi->plev) + { + case 0: /* not privileged */ + break; + case 1: /* unprivileged only on 68000 */ + if (cpu_level == 0) + break; + if (next_cpu_level < 0) + next_cpu_level = 0; + + /* fall through */ + case 2: /* priviledged */ + failure; /* Easy ones first */ + break; + case 3: /* privileged if size == word */ + if (curi->size == sz_byte) + break; + failure; + break; + } + switch (curi->size) { + case sz_byte: ssize="b"; break; + case sz_word: ssize="w"; break; + case sz_long: ssize="l"; break; + default: assert(0); + } + (void)ssize; + + switch (curi->mnemo) + { + case i_OR: + case i_AND: + case i_EOR: +#ifdef DISABLE_I_OR_AND_EOR + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + switch(curi->mnemo) { + case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break; + case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break; + case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break; + } + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_ORSR: + case i_EORSR: + failure; + isjump; + break; + + case i_ANDSR: + failure; + isjump; + break; + + case i_SUB: +#ifdef DISABLE_I_SUB + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags (flag_sub, curi->size, "", "src", "dst"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_SUBA: +#ifdef DISABLE_I_SUBA + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmp=scratchie++;\n"); + switch(curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; + case sz_long: comprintf("\ttmp=src;\n"); break; + default: assert(0); + } + comprintf("\tsub_l(dst,tmp);\n"); + genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; + + case i_SUBX: +#ifdef DISABLE_I_SUBX + failure; +#endif + isaddx; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags (flag_subx, curi->size, "", "src", "dst"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_SBCD: + failure; + /* I don't think so! */ + break; + + case i_ADD: +#ifdef DISABLE_I_ADD + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags (flag_add, curi->size, "", "src", "dst"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_ADDA: +#ifdef DISABLE_I_ADDA + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmp=scratchie++;\n"); + switch(curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; + case sz_long: comprintf("\ttmp=src;\n"); break; + default: assert(0); + } + comprintf("\tadd_l(dst,tmp);\n"); + genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; + + case i_ADDX: +#ifdef DISABLE_I_ADDX + failure; +#endif + isaddx; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + genflags (flag_addx, curi->size, "", "src", "dst"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_ABCD: + failure; + /* No BCD maths for me.... */ + break; + + case i_NEG: +#ifdef DISABLE_I_NEG + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace (); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0);\n"); + genflags (flag_sub, curi->size, "", "src", "dst"); + genastore ("dst", curi->smode, "srcreg", curi->size, "src"); + break; + + case i_NEGX: +#ifdef DISABLE_I_NEGX + failure; +#endif + isaddx; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace (); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0);\n"); + genflags (flag_subx, curi->size, "", "src", "dst"); + genastore ("dst", curi->smode, "srcreg", curi->size, "src"); + break; + + case i_NBCD: + failure; + /* Nope! */ + break; + + case i_CLR: +#ifdef DISABLE_I_CLR + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0);\n"); + genflags (flag_logical, curi->size, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", curi->size, "src"); + break; + + case i_NOT: +#ifdef DISABLE_I_NOT + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace (); + comprintf("\tint dst=scratchie++;\n"); + comprintf("\tmov_l_ri(dst,0xffffffff);\n"); + genflags (flag_eor, curi->size, "", "src", "dst"); + genastore ("dst", curi->smode, "srcreg", curi->size, "src"); + break; + + case i_TST: +#ifdef DISABLE_I_TST + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genflags (flag_logical, curi->size, "src", "", ""); + break; + case i_BCHG: + case i_BCLR: + case i_BSET: + case i_BTST: +#ifdef DISABLE_I_BCHG_BCLR_BSET_BTST + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint s=scratchie++;\n" + "\tint tmp=scratchie++;\n" + "\tmov_l_rr(s,src);\n"); + if (curi->size == sz_byte) + comprintf("\tand_l_ri(s,7);\n"); + else + comprintf("\tand_l_ri(s,31);\n"); + + { + const char* op; + int need_write=1; + + switch(curi->mnemo) { + case i_BCHG: op="btc"; break; + case i_BCLR: op="btr"; break; + case i_BSET: op="bts"; break; + case i_BTST: op="bt"; need_write=0; break; + default: op=""; assert(0); + } + comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */ + "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */ + "\tmake_flags_live();\n" /* Get the flags back */ + "\tdont_care_flags();\n",op); + if (!noflags) { + comprintf("\tstart_needflags();\n" + "\tset_zero(s,tmp);\n" + "\tlive_flags();\n" + "\tend_needflags();\n"); + } + if (need_write) + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + } + break; + + case i_CMPM: + case i_CMP: +#ifdef DISABLE_I_CMPM_CMP + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace (); + genflags (flag_cmp, curi->size, "", "src", "dst"); + break; + + case i_CMPA: +#ifdef DISABLE_I_CMPA + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmps=scratchie++;\n"); + switch(curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break; + case sz_long: comprintf("tmps=src;\n"); break; + default: assert(0); + } + genflags (flag_cmp, sz_long, "", "tmps", "dst"); + break; + /* The next two are coded a little unconventional, but they are doing + * weird things... */ + + case i_MVPRM: + isjump; + failure; + break; + + case i_MVPMR: + isjump; + failure; + break; + + case i_MOVE: +#ifdef DISABLE_I_MOVE + failure; +#endif + switch(curi->dmode) { + case Dreg: + case Areg: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genflags (flag_mov, curi->size, "", "src", "dst"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); + break; + default: /* It goes to memory, not a register */ + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genflags (flag_logical, curi->size, "src", "", ""); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); + break; + } + break; + + case i_MOVEA: +#ifdef DISABLE_I_MOVEA + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + + start_brace(); + comprintf("\tint tmps=scratchie++;\n"); + switch(curi->size) { + case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break; + case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break; + default: assert(0); + } + genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; + + case i_MVSR2: + isjump; + failure; + break; + + case i_MV2SR: + isjump; + failure; + break; + + case i_SWAP: +#ifdef DISABLE_I_SWAP + failure; +#endif + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tdont_care_flags();\n"); + comprintf("\trol_l_ri(src,16);\n"); + genflags (flag_logical, sz_long, "src", "", ""); + genastore ("src", curi->smode, "srcreg", sz_long, "src"); + break; + + case i_EXG: +#ifdef DISABLE_I_EXG + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tint tmp=scratchie++;\n" + "\tmov_l_rr(tmp,src);\n"); + genastore ("dst", curi->smode, "srcreg", curi->size, "src"); + genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_EXT: +#ifdef DISABLE_I_EXT + failure; +#endif + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tdont_care_flags();\n"); + start_brace (); + switch (curi->size) + { + case sz_byte: + comprintf ("\tint dst = src;\n" + "\tsign_extend_8_rr(src,src);\n"); + break; + case sz_word: + comprintf ("\tint dst = scratchie++;\n" + "\tsign_extend_8_rr(dst,src);\n"); + break; + case sz_long: + comprintf ("\tint dst = src;\n" + "\tsign_extend_16_rr(src,src);\n"); + break; + default: + assert(0); + } + genflags (flag_logical, + curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", + curi->size == sz_word ? sz_word : sz_long, "src"); + break; + + case i_MVMEL: +#ifdef DISABLE_I_MVEL + failure; +#endif + genmovemel (opcode); + break; + + case i_MVMLE: +#ifdef DISABLE_I_MVMLE + failure; +#endif + genmovemle (opcode); + break; + + case i_TRAP: +#ifdef DISABLE_I_TRAP + failure; +#endif + isjump; + mayfail; + start_brace(); + comprintf(" int trapno = srcreg + 32;\n"); + gen_set_fault_pc(); + make_sr(); + comprintf(" compemu_enter_super(sr);\n"); + comprintf(" compemu_exc_make_frame(0, sr, ret, trapno, scratchie);\n"); + comprintf(" forget_about(ret);\n"); + /* m68k_setpc (get_long (regs.vbr + 4*nr)); */ + start_brace(); + comprintf(" int srca = scratchie++;\n"); + comprintf(" mov_l_rm(srca, (uintptr)®s.vbr);\n"); + comprintf(" mov_l_brR(srca, srca, MEMBaseDiff + trapno * 4); mid_bswap_32(srca);\n"); + comprintf(" mov_l_mr((uintptr)®s.pc, srca);\n"); + comprintf(" get_n_addr_jmp(srca, PC_P, scratchie);\n"); + comprintf(" mov_l_mr((uintptr)®s.pc_oldp, PC_P);\n"); + gen_update_next_handler(); + disasm_this_inst(); /* for debugging only */ + /* + * this currently deactivates this feature, since it does not work yet + */ + failure; + break; + + case i_MVR2USP: + isjump; + failure; + break; + + case i_MVUSP2R: + isjump; + failure; + break; + + case i_RESET: + isjump; + failure; + break; + + case i_NOP: + break; + + case i_STOP: + isjump; + failure; + break; + + case i_RTE: + isjump; + failure; + break; + + case i_RTD: +#ifdef DISABLE_I_RTD + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* offs is constant */ + comprintf("\tadd_l_ri(offs,4);\n"); + start_brace(); + comprintf("\tint newad=scratchie++;\n" + "\treadlong(SP_REG,newad,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc,newad);\n" + "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n" + "\tadd_l(SP_REG,offs);\n"); + gen_update_next_handler(); + isjump; + break; + + case i_LINK: +#ifdef DISABLE_I_LINK + failure; +#endif + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tsub_l_ri(SP_REG,4);\n" + "\twritelong_clobber(SP_REG,src,scratchie);\n" + "\tmov_l_rr(src,SP_REG);\n"); + if (curi->size==sz_word) + comprintf("\tsign_extend_16_rr(offs,offs);\n"); + comprintf("\tadd_l(SP_REG,offs);\n"); + genastore ("src", curi->smode, "srcreg", sz_long, "src"); + break; + + case i_UNLK: +#ifdef DISABLE_I_UNLK + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tmov_l_rr(SP_REG,src);\n" + "\treadlong(SP_REG,src,scratchie);\n" + "\tadd_l_ri(SP_REG,4);\n"); + genastore ("src", curi->smode, "srcreg", curi->size, "src"); + break; + + case i_RTS: +#ifdef DISABLE_I_RTS + failure; +#endif + comprintf("\tint newad=scratchie++;\n" + "\treadlong(SP_REG,newad,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc,newad);\n" + "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n" + "\tlea_l_brr(SP_REG,SP_REG,4);\n"); + gen_update_next_handler(); + isjump; + break; + + case i_TRAPV: + isjump; + failure; + break; + + case i_RTR: + isjump; + failure; + break; + + case i_JSR: +#ifdef DISABLE_I_JSR + failure; +#endif + isjump; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); + comprintf("\tint ret=scratchie++;\n" + "\tmov_l_ri(ret,retadd);\n" + "\tsub_l_ri(SP_REG,4);\n" + "\twritelong_clobber(SP_REG,ret,scratchie);\n"); + comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" + "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n"); + gen_update_next_handler(); + break; + + case i_JMP: +#ifdef DISABLE_I_JMP + failure; +#endif + isjump; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n" + "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" + "\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n" + "\tm68k_pc_offset=0;\n"); + gen_update_next_handler(); + break; + + case i_BSR: +#ifdef DISABLE_I_BSR + failure; +#endif + is_const_jump; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace(); + comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); + comprintf("\tint ret=scratchie++;\n" + "\tmov_l_ri(ret,retadd);\n" + "\tsub_l_ri(SP_REG,4);\n" + "\twritelong_clobber(SP_REG,ret,scratchie);\n"); + comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n"); + comprintf("\tm68k_pc_offset=0;\n"); + comprintf("\tadd_l(PC_P,src);\n"); + + comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n"); + gen_update_next_handler(); + break; + + case i_Bcc: +#ifdef DISABLE_I_BCC + failure; +#endif + comprintf("\tuae_u32 v,v1,v2;\n"); + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* That source is an immediate, so we can clobber it with abandon */ + switch(curi->size) { + case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break; + case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break; + case sz_long: break; + } + comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); + /* Leave the following as "add" --- it will allow it to be optimized + away due to src being a constant ;-) */ + comprintf("\tadd_l_ri(src,(uintptr)comp_pc_p);\n"); + comprintf("\tmov_l_ri(PC_P,(uintptr)comp_pc_p);\n"); + /* Now they are both constant. Might as well fold in m68k_pc_offset */ + comprintf("\tadd_l_ri(src,m68k_pc_offset);\n"); + comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); + comprintf("\tm68k_pc_offset=0;\n"); + + if (curi->cc>=2) { + comprintf("\tv1=get_const(PC_P);\n" + "\tv2=get_const(src);\n" + "\tregister_branch(v1,v2,%d);\n", + cond_codes[curi->cc]); + comprintf("\tmake_flags_live();\n"); /* Load the flags */ + isjump; + } + else { + is_const_jump; + } + + switch(curi->cc) { + case 0: /* Unconditional jump */ + comprintf("\tmov_l_rr(PC_P,src);\n"); + comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n"); + break; + case 1: break; /* This is silly! */ + case 8: failure; break; /* Work out details! FIXME */ + case 9: failure; break; /* Not critical, though! */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + break; + default: assert(0); + } + break; + + case i_LEA: +#ifdef DISABLE_I_LEA + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); + break; + + case i_PEA: +#ifdef DISABLE_I_PEA + failure; +#endif + if (table68k[opcode].smode==Areg || + table68k[opcode].smode==Aind || + table68k[opcode].smode==Aipi || + table68k[opcode].smode==Apdi || + table68k[opcode].smode==Ad16 || + table68k[opcode].smode==Ad8r) + comprintf("if (srcreg==7) dodgy=1;\n"); + + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC); + genamode (Apdi, "7", sz_long, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + genastore ("srca", Apdi, "7", sz_long, "dst"); + break; + + case i_DBcc: +#ifdef DISABLE_I_DBCC + failure; +#endif + isjump; + uses_cmov; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + + /* That offs is an immediate, so we can clobber it with abandon */ + switch(curi->size) { + case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break; + default: assert(0); /* Seems this only comes in word flavour */ + } + comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); + comprintf("\tadd_l_ri(offs,(uintptr)comp_pc_p);\n"); /* New PC, + once the + offset_68k is + * also added */ + /* Let's fold in the m68k_pc_offset at this point */ + comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n"); + comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); + comprintf("\tm68k_pc_offset=0;\n"); + + start_brace(); + comprintf("\tint nsrc=scratchie++;\n"); + + if (curi->cc>=2) { + comprintf("\tmake_flags_live();\n"); /* Load the flags */ + } + + assert (curi->size==sz_word); + + switch(curi->cc) { + case 0: /* This is an elaborate nop? */ + break; + case 1: + comprintf("\tstart_needflags();\n"); + comprintf("\tsub_w_ri(src,1);\n"); + comprintf("\tend_needflags();\n"); + start_brace(); + comprintf("\tuae_u32 v2,v;\n" + "\tuae_u32 v1=get_const(PC_P);\n"); + comprintf("\tv2=get_const(offs);\n" + "\tregister_branch(v1,v2,%d);\n", NATIVE_CC_CC); + break; + + case 8: failure; break; /* Work out details! FIXME */ + case 9: failure; break; /* Not critical, though! */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + comprintf("\tmov_l_rr(nsrc,src);\n"); + comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n" + "\tmov_w_rr(src,scratchie);\n"); + comprintf("\tcmov_l_rr(offs,PC_P,%d);\n", + cond_codes[curi->cc]); + comprintf("\tcmov_l_rr(src,nsrc,%d);\n", + cond_codes[curi->cc]); + /* OK, now for cc=true, we have src==nsrc and offs==PC_P, + so whether we move them around doesn't matter. However, + if cc=false, we have offs==jump_pc, and src==nsrc-1 */ + + comprintf("\tstart_needflags();\n"); + comprintf("\ttest_w_rr(nsrc,nsrc);\n"); + comprintf("\tend_needflags();\n"); + comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE); + break; + default: assert(0); + } + genastore ("src", curi->smode, "srcreg", curi->size, "src"); + gen_update_next_handler(); + break; + + case i_Scc: +#ifdef DISABLE_I_SCC + failure; +#endif + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC); + start_brace (); + comprintf ("\tint val = scratchie++;\n"); + + /* We set val to 0 if we really should use 255, and to 1 for real 0 */ + switch(curi->cc) { + case 0: /* Unconditional set */ + comprintf("\tmov_l_ri(val,0);\n"); + break; + case 1: + /* Unconditional not-set */ + comprintf("\tmov_l_ri(val,1);\n"); + break; + case 8: failure; break; /* Work out details! FIXME */ + case 9: failure; break; /* Not critical, though! */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + comprintf("\tmake_flags_live();\n"); /* Load the flags */ + /* All condition codes can be inverted by changing the LSB */ + comprintf("\tsetcc(val,%d);\n", + cond_codes[curi->cc]^1); break; + default: assert(0); + } + comprintf("\tsub_b_ri(val,1);\n"); + genastore ("val", curi->smode, "srcreg", curi->size, "src"); + break; + + case i_DIVU: + isjump; + failure; + break; + + case i_DIVS: + isjump; + failure; + break; + + case i_MULU: +#ifdef DISABLE_I_MULU + failure; +#endif + comprintf("\tdont_care_flags();\n"); + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* To do 16x16 unsigned multiplication, we actually use + 32x32 signed, and zero-extend the registers first. + That solves the problem of MUL needing dedicated registers + on the x86 */ + comprintf("\tzero_extend_16_rr(scratchie,src);\n" + "\tzero_extend_16_rr(dst,dst);\n" + "\timul_32_32(dst,scratchie);\n"); + genflags (flag_logical, sz_long, "dst", "", ""); + genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; + + case i_MULS: +#ifdef DISABLE_I_MULS + failure; +#endif + comprintf("\tdont_care_flags();\n"); + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + comprintf("\tsign_extend_16_rr(scratchie,src);\n" + "\tsign_extend_16_rr(dst,dst);\n" + "\timul_32_32(dst,scratchie);\n"); + genflags (flag_logical, sz_long, "dst", "", ""); + genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); + break; + + case i_CHK: + isjump; + failure; + break; + + case i_CHK2: + isjump; + failure; + break; + + case i_ASR: +#ifdef DISABLE_I_ASR + failure; +#endif + mayfail; + if (curi->smode==Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + + start_brace(); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode!=immi) { + uses_cmov; + start_brace(); + comprintf("\tint zero = scratchie++;\n"); + comprintf("\tint tmpcnt = scratchie++;\n"); + comprintf("\tint minus1 = scratchie++;\n"); + comprintf("\tint cdata = minus1;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(zero, 0);\n"); + comprintf("\tmov_l_ri(minus1, -1);\n"); + switch(curi->size) { + case sz_byte: + comprintf("\ttest_b_rr(data,data);\n"); + comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n"); + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tmov_l_rr(cdata,data);\n"); + comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n"); + comprintf("\tshra_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data,cdata);\n"); + break; + case sz_word: + comprintf("\ttest_w_rr(data,data);\n"); + comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n"); + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tmov_l_rr(cdata,data);\n"); + comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n"); + comprintf("\tshra_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data,cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_rr(data,data);\n"); + comprintf("\tcmov_l_rr(zero, minus1, NATIVE_CC_MI);\n"); + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tmov_l_rr(cdata,data);\n"); + comprintf("\tcmov_l_rr(cdata, zero, NATIVE_CC_NE);\n"); + comprintf("\tshra_l_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_l_rr(data,cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } + else { + switch(curi->size) { + case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } + /* And create the flags */ + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode!=immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore ("data", curi->dmode, "dstreg", curi->size, "data"); + break; + + case i_ASL: +#ifdef DISABLE_I_ASL + failure; +#endif + mayfail; + if (curi->smode==Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + /* Except for the handling of the V flag, this is identical to + LSL. The handling of V is, uhm, unpleasant, so if it's needed, + let the normal emulation handle it. Shoulders of giants kinda + thing ;-) */ + comprintf( + " if (needed_flags & FLAG_V) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + + start_brace(); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode!=immi) { + uses_cmov; + start_brace(); + comprintf("\tint cdata = scratchie++;\n"); + comprintf("\tint tmpcnt=scratchie++;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(cdata, 0);\n"); + switch(curi->size) { + case sz_byte: + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data, cdata);\n"); + break; + case sz_word: + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data, cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_l_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_l_rr(data, cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } + else { + switch(curi->size) { + case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } + /* And create the flags */ + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode!=immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore ("data", curi->dmode, "dstreg", curi->size, "data"); + break; + + case i_LSR: +#ifdef DISABLE_I_LSR + failure; +#endif + mayfail; + if (curi->smode==Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + + start_brace(); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode!=immi) { + uses_cmov; + start_brace(); + comprintf("\tint cdata = scratchie++;\n"); + comprintf("\tint tmpcnt=scratchie++;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(cdata, 0);\n"); + switch(curi->size) { + case sz_byte: + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshrl_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data, cdata);\n"); + break; + case sz_word: + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshrl_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data, cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshrl_l_rr(cdata, tmpcnt);\n"); + comprintf("\tmov_l_rr(data, cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } + else { + switch(curi->size) { + case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } + /* And create the flags */ + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode!=immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore ("data", curi->dmode, "dstreg", curi->size, "data"); + break; + + case i_LSL: +#ifdef DISABLE_I_LSL + failure; +#endif + mayfail; + if (curi->smode==Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + + start_brace(); + if (!noflags) + comprintf("\tstart_needflags();\n"); + if (curi->smode!=immi) { + uses_cmov; + start_brace(); + comprintf("\tint cdata = scratchie++;\n"); + comprintf("\tint tmpcnt = scratchie++;\n"); + comprintf("\tmov_l_rr(tmpcnt,cnt);\n"); + comprintf("\tand_l_ri(tmpcnt,63);\n"); + comprintf("\tmov_l_ri(cdata, 0);\n"); + switch(curi->size) { + case sz_byte: + comprintf("\ttest_l_ri(tmpcnt, 0x38);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_b_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_b_rr(data, cdata);\n"); + break; + case sz_word: + comprintf("\ttest_l_ri(tmpcnt, 0x30);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_w_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_w_rr(data, cdata);\n"); + break; + case sz_long: + comprintf("\ttest_l_ri(tmpcnt, 0x20);\n"); + comprintf("\tcmov_l_rr(cdata, data, NATIVE_CC_EQ);\n"); + comprintf("\tshll_l_rr(cdata,tmpcnt);\n"); + comprintf("\tmov_l_rr(data, cdata);\n"); + break; + default: assert(0); + } + /* Result of shift is now in data. */ + } + else { + switch(curi->size) { + case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n"); break; + case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n"); break; + case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n"); break; + default: assert(0); + } + } + /* And create the flags */ + if (!noflags) { + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + if (curi->smode!=immi) + comprintf("\tsetcc_for_cntzero(tmpcnt, data, %d);\n", curi->size == sz_byte ? 1 : curi->size == sz_word ? 2 : 4); + else + comprintf("\tduplicate_carry();\n"); + comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); + } + genastore ("data", curi->dmode, "dstreg", curi->size, "data"); + break; + + case i_ROL: +#ifdef DISABLE_I_ROL + failure; +#endif + mayfail; + if (curi->smode==Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace (); + + switch(curi->size) { + case sz_long: comprintf("\trol_l_rr(data,cnt);\n"); break; + case sz_word: comprintf("\trol_w_rr(data,cnt);\n"); break; + case sz_byte: comprintf("\trol_b_rr(data,cnt);\n"); break; + } + + if (!noflags) { + comprintf("\tstart_needflags();\n"); + /* + * x86 ROL instruction does not set ZF/SF, so we need extra checks here + */ + comprintf("\tif (needed_flags & FLAG_ZNV)\n"); + switch(curi->size) { + case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; + case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; + case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; + } + comprintf("\tbt_l_ri(data,0x00);\n"); /* Set C */ + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + } + genastore ("data", curi->dmode, "dstreg", curi->size, "data"); + break; + + case i_ROR: +#ifdef DISABLE_I_ROR + failure; +#endif + mayfail; + if (curi->smode==Dreg) { + comprintf( + " if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" + " FAIL(1);\n" + " " RETURN "\n" + " }\n"); + start_brace(); + } + comprintf("\tdont_care_flags();\n"); + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + start_brace (); + + switch(curi->size) { + case sz_long: comprintf("\tror_l_rr(data,cnt);\n"); break; + case sz_word: comprintf("\tror_w_rr(data,cnt);\n"); break; + case sz_byte: comprintf("\tror_b_rr(data,cnt);\n"); break; + } + + if (!noflags) { + comprintf("\tstart_needflags();\n"); + /* + * x86 ROR instruction does not set ZF/SF, so we need extra checks here + */ + comprintf("\tif (needed_flags & FLAG_ZNV)\n"); + switch(curi->size) { + case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; + case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; + case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; + } + switch(curi->size) { + case sz_byte: comprintf("\tbt_l_ri(data,0x07);\n"); break; + case sz_word: comprintf("\tbt_l_ri(data,0x0f);\n"); break; + case sz_long: comprintf("\tbt_l_ri(data,0x1f);\n"); break; + } + comprintf("\tlive_flags();\n"); + comprintf("\tend_needflags();\n"); + } + genastore ("data", curi->dmode, "dstreg", curi->size, "data"); + break; + + case i_ROXL: + failure; + break; + + case i_ROXR: + failure; + break; + + case i_ASRW: + failure; + break; + + case i_ASLW: + failure; + break; + + case i_LSRW: + failure; + break; + + case i_LSLW: + failure; + break; + + case i_ROLW: + failure; + break; + + case i_RORW: + failure; + break; + + case i_ROXLW: + failure; + break; + + case i_ROXRW: + failure; + break; + + case i_MOVEC2: + isjump; + failure; + break; + + case i_MOVE2C: + isjump; + failure; + break; + + case i_CAS: + failure; + break; + + case i_CAS2: + failure; + break; + + case i_MOVES: /* ignore DFC and SFC because we have no MMU */ + isjump; + failure; + break; + + case i_BKPT: /* only needed for hardware emulators */ + isjump; + failure; + break; + + case i_CALLM: /* not present in 68030 */ + isjump; + failure; + break; + + case i_RTM: /* not present in 68030 */ + isjump; + failure; + break; + + case i_TRAPcc: + isjump; + failure; + break; + + case i_DIVL: + isjump; + failure; + break; + + case i_MULL: +#ifdef DISABLE_I_MULL + failure; +#endif + if (!noflags) { + failure; + break; + } + comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); + comprintf("\tint r2=(extra>>12)&7;\n" + "\tint tmp=scratchie++;\n"); + + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC); + /* The two operands are in dst and r2 */ + comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */ + "\tint r3=(extra&7);\n" + "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */ + comprintf("\tif (extra&0x0800) { \n" /* signed */ + "\t\timul_64_32(r2,r3);\n" + "\t} else { \n" + "\t\tmul_64_32(r2,r3);\n" + "\t} \n"); + /* The result is in r2/tmp, with r2 holding the lower 32 bits */ + comprintf("\t} else {\n"); /* Only want 32 bit result */ + /* operands in dst and r2, result foes into r2 */ + /* shouldn't matter whether it's signed or unsigned?!? */ + comprintf("\timul_32_32(r2,dst);\n" + "\t}\n"); + break; + + case i_BFTST: + case i_BFEXTU: + case i_BFCHG: + case i_BFEXTS: + case i_BFCLR: + case i_BFFFO: + case i_BFSET: + case i_BFINS: + failure; + break; + + case i_PACK: + failure; + break; + + case i_UNPK: + failure; + break; + + case i_TAS: + failure; + break; + + case i_FPP: +#ifdef DISABLE_I_FPP + failure; +#endif + uses_fpu; + mayfail; + comprintf("#ifdef USE_JIT_FPU\n"); + comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); + swap_opcode(); + comprintf("\tcomp_fpp_opp(opcode,extra);\n"); + comprintf("#else\n"); + comprintf("\tfailure = 1;\n"); + comprintf("#endif\n"); + break; + + case i_FBcc: +#ifdef DISABLE_I_FBCC + failure; +#endif + uses_fpu; + isjump; + uses_cmov; + mayfail; + comprintf("#ifdef USE_JIT_FPU\n"); + swap_opcode(); + comprintf("\tcomp_fbcc_opp(opcode);\n"); + comprintf("#else\n"); + comprintf("\tfailure = 1;\n"); + comprintf("#endif\n"); + break; + + case i_FDBcc: + uses_fpu; + isjump; + failure; + break; + + case i_FScc: +#ifdef DISABLE_I_FSCC + failure; +#endif + uses_fpu; + mayfail; + uses_cmov; + comprintf("#ifdef USE_JIT_FPU\n"); + comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); + swap_opcode(); + comprintf("\tcomp_fscc_opp(opcode,extra);\n"); + comprintf("#else\n"); + comprintf("\tfailure = 1;\n"); + comprintf("#endif\n"); + break; + + case i_FTRAPcc: + uses_fpu; + isjump; + failure; + break; + + case i_FSAVE: + uses_fpu; + failure; + break; + + case i_FRESTORE: + uses_fpu; + failure; + break; + + case i_CINVL: + case i_CINVP: + case i_CINVA: + isjump; /* Not really, but it's probably a good idea to stop + translating at this point */ + failure; + comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */ + break; + + case i_CPUSHL: + case i_CPUSHP: + case i_CPUSHA: + isjump; /* Not really, but it's probably a good idea to stop + translating at this point */ + failure; + break; + + case i_MOVE16: +#ifdef DISABLE_I_MOVE16 + failure; +#endif + genmov16(opcode,curi); + break; + +#ifdef UAE + case i_MMUOP030: + case i_PFLUSHN: + case i_PFLUSH: + case i_PFLUSHAN: + case i_PFLUSHA: + case i_PLPAR: + case i_PLPAW: + case i_PTESTR: + case i_PTESTW: + case i_LPSTOP: + isjump; + failure; + break; +#endif + +#ifdef WINUAE_ARANYM + case i_EMULOP_RETURN: + isjump; + failure; + break; + + case i_EMULOP: + failure; + break; + + // case i_NATFEAT_ID: + // case i_NATFEAT_CALL: + // failure; + // break; + + case i_MMUOP: + isjump; + failure; + break; +#endif + + default: + assert(0); + break; + } + comprintf("%s",endstr); + finish_braces (); + sync_m68k_pc (); + if (global_mayfail) + comprintf(" if (failure)\n m68k_pc_offset = m68k_pc_offset_thisinst;\n"); + return global_failure; +} + +static void +generate_includes (FILE * f) +{ + // fprintf (f, "#include \"sysconfig.h\"\n"); + fprintf (f, "#if defined(JIT)\n"); + fprintf (f, "#include \"sysdeps.h\"\n"); +#ifdef UAE + fprintf (f, "#include \"options.h\"\n"); + fprintf (f, "#include \"uae/memory.h\"\n"); +#else + fprintf (f, "#include \"m68k.h\"\n"); + fprintf (f, "#include \"memory.h\"\n"); +#endif + fprintf (f, "#include \"readcpu.h\"\n"); + fprintf (f, "#include \"newcpu.h\"\n"); + fprintf (f, "#include \"comptbl.h\"\n"); + fprintf (f, "#include \"debug.h\"\n"); +} + +static int postfix; + + +static char *decodeEA (amodes mode, wordsizes size) +{ + static char buffer[80]; + + buffer[0] = 0; + switch (mode){ + case Dreg: + strcpy (buffer,"Dn"); + break; + case Areg: + strcpy (buffer,"An"); + break; + case Aind: + strcpy (buffer,"(An)"); + break; + case Aipi: + strcpy (buffer,"(An)+"); + break; + case Apdi: + strcpy (buffer,"-(An)"); + break; + case Ad16: + strcpy (buffer,"(d16,An)"); + break; + case Ad8r: + strcpy (buffer,"(d8,An,Xn)"); + break; + case PC16: + strcpy (buffer,"(d16,PC)"); + break; + case PC8r: + strcpy (buffer,"(d8,PC,Xn)"); + break; + case absw: + strcpy (buffer,"(xxx).W"); + break; + case absl: + strcpy (buffer,"(xxx).L"); + break; + case imm: + switch (size){ + case sz_byte: + strcpy (buffer,"#.B"); + break; + case sz_word: + strcpy (buffer,"#.W"); + break; + case sz_long: + strcpy (buffer,"#.L"); + break; + default: + break; + } + break; + case imm0: + strcpy (buffer,"#.B"); + break; + case imm1: + strcpy (buffer,"#.W"); + break; + case imm2: + strcpy (buffer,"#.L"); + break; + case immi: + strcpy (buffer,"#"); + break; + + default: + break; + } + return buffer; +} + +static char *outopcode (const char *name, int opcode) +{ + static char out[100]; + struct instr *ins; + + ins = &table68k[opcode]; + strcpy (out, name); + if (ins->smode == immi) + strcat (out, "Q"); + if (ins->size == sz_byte) + strcat (out,".B"); + if (ins->size == sz_word) + strcat (out,".W"); + if (ins->size == sz_long) + strcat (out,".L"); + strcat (out," "); + if (ins->suse) + strcat (out, decodeEA (ins->smode, ins->size)); + if (ins->duse) { + if (ins->suse) strcat (out,","); + strcat (out, decodeEA (ins->dmode, ins->size)); + } + return out; +} + + +static void +generate_one_opcode (int rp, int noflags) +{ + int i; + uae_u16 smsk, dmsk; + unsigned int opcode = opcode_map[rp]; + int aborted=0; + int have_srcreg=0; + int have_dstreg=0; + const char *name; + + if (table68k[opcode].mnemo == i_ILLG + || table68k[opcode].clev > cpu_level) + return; + + for (i = 0; lookuptab[i].name[0]; i++) + { + if (table68k[opcode].mnemo == lookuptab[i].mnemo) + break; + } + + if (table68k[opcode].handler != -1) + return; + + switch (table68k[opcode].stype) + { + case 0: + smsk = 7; + break; + case 1: + smsk = 255; + break; + case 2: + smsk = 15; + break; + case 3: + smsk = 7; + break; + case 4: + smsk = 7; + break; + case 5: + smsk = 63; + break; +#ifndef UAE + case 6: + smsk = 255; + break; +#endif + case 7: + smsk = 3; + break; + default: + smsk = 0; + assert(0); + } + dmsk = 7; + + next_cpu_level = -1; + if (table68k[opcode].suse + && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 + && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 + && table68k[opcode].smode != absw && table68k[opcode].smode != absl + && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) + { + have_srcreg=1; + if (table68k[opcode].spos == -1) + { + if (((int) table68k[opcode].sreg) >= 128) + comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); + else + comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg); + } + else + { + char source[100]; + int pos = table68k[opcode].spos; + +#ifndef UAE + comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); + + if (pos < 8 && (smsk >> (8 - pos)) != 0) + sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)", + pos ^ 8, 8 - pos, dmsk); + else if (pos != 8) + sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk); + else + sprintf (source, "(opcode & %d)", smsk); + + if (table68k[opcode].stype == 3) + comprintf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); + else if (table68k[opcode].stype == 1) + comprintf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); + else + comprintf ("\tuae_u32 srcreg = %s;\n", source); + + comprintf ("#else\n"); +#endif + + if (pos) + sprintf (source, "((opcode >> %d) & %d)", pos, smsk); + else + sprintf (source, "(opcode & %d)", smsk); + + if (table68k[opcode].stype == 3) + comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source); + else if (table68k[opcode].stype == 1) + comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source); + else + comprintf ("\tuae_s32 srcreg = %s;\n", source); + +#ifndef UAE + comprintf ("#endif\n"); +#endif + } + } + if (table68k[opcode].duse + /* Yes, the dmode can be imm, in case of LINK or DBcc */ + && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 + && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 + && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) + { + have_dstreg=1; + if (table68k[opcode].dpos == -1) + { + if (((int) table68k[opcode].dreg) >= 128) + comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); + else + comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg); + } + else + { + int pos = table68k[opcode].dpos; + +#ifndef UAE + comprintf ("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); + + if (pos < 8 && (dmsk >> (8 - pos)) != 0) + comprintf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n", + pos ^ 8, 8 - pos, dmsk); + else if (pos != 8) + comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", + pos ^ 8, dmsk); + else + comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); + + comprintf ("#else\n"); +#endif + + if (pos) + comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", + pos, dmsk); + else + comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); + +#ifndef UAE + comprintf ("#endif\n"); +#endif + } + } + + if (have_srcreg && have_dstreg && + (table68k[opcode].dmode==Areg || + table68k[opcode].dmode==Aind || + table68k[opcode].dmode==Aipi || + table68k[opcode].dmode==Apdi || + table68k[opcode].dmode==Ad16 || + table68k[opcode].dmode==Ad8r) && + (table68k[opcode].smode==Areg || + table68k[opcode].smode==Aind || + table68k[opcode].smode==Aipi || + table68k[opcode].smode==Apdi || + table68k[opcode].smode==Ad16 || + table68k[opcode].smode==Ad8r) + ) { + comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n"); + } + else { + comprintf("\tuae_u32 dodgy=0;\n"); + } + comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n"); + comprintf("\tm68k_pc_offset+=2;\n"); + + aborted=gen_opcode (opcode); + { + char flags[64 * 6]; + *flags = '\0'; + if (global_isjump) strcat(flags, "COMP_OPCODE_ISJUMP|"); + if (long_opcode) strcat(flags, "COMP_OPCODE_LONG_OPCODE|"); + if (global_cmov) strcat(flags, "COMP_OPCODE_CMOV|"); + if (global_isaddx) strcat(flags, "COMP_OPCODE_ISADDX|"); + if (global_iscjump) strcat(flags, "COMP_OPCODE_ISCJUMP|"); + if (global_fpu) strcat(flags, "COMP_OPCODE_USES_FPU|"); + if (*flags) + flags[strlen(flags) - 1] = '\0'; + else + strcpy(flags, "0"); + +#ifdef UAE /* RETTYPE != void */ + comprintf ("return 0;\n"); +#endif + comprintf ("}\n"); + + name = lookuptab[i].name; + if (aborted) { + fprintf (stblfile, "{ NULL, %u, %s }, /* %s */\n", opcode, flags, name); + com_discard(); + } else { + const char *tbl = noflags ? "nf" : "ff"; + fprintf (stblfile, "{ op_%x_%d_comp_%s, %u, %s }, /* %s */\n", opcode, postfix, tbl, opcode, flags, name); + fprintf (headerfile, "extern compop_func op_%x_%d_comp_%s;\n", opcode, postfix, tbl); + printf ("/* %s */\n", outopcode (name, opcode)); + printf (RETTYPE " REGPARAM2 op_%x_%d_comp_%s(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, tbl, name); + com_flush(); + } + } + opcode_next_clev[rp] = next_cpu_level; + opcode_last_postfix[rp] = postfix; +} + +static void +generate_func (int noflags) +{ + int i, j, rp; + const char *tbl = noflags ? "nf" : "ff"; + + using_prefetch = 0; + using_exception_3 = 0; + for (i = 0; i < 1; i++) /* We only do one level! */ + { + cpu_level = NEXT_CPU_LEVEL - i; + postfix = i; + + fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_%s[] = {\n", postfix, tbl); + + /* sam: this is for people with low memory (eg. me :)) */ + printf ("\n" + "#if !defined(PART_1) && !defined(PART_2) && " + "!defined(PART_3) && !defined(PART_4) && " + "!defined(PART_5) && !defined(PART_6) && " + "!defined(PART_7) && !defined(PART_8)" + "\n" + "#define PART_1 1\n" + "#define PART_2 1\n" + "#define PART_3 1\n" + "#define PART_4 1\n" + "#define PART_5 1\n" + "#define PART_6 1\n" + "#define PART_7 1\n" + "#define PART_8 1\n" + "#endif\n\n"); +#ifdef UAE + printf ("extern void comp_fpp_opp();\n" + "extern void comp_fscc_opp();\n" + "extern void comp_fbcc_opp();\n\n"); +#endif + + rp = 0; + for (j = 1; j <= 8; ++j) + { + int k = (j * nr_cpuop_funcs) / 8; + printf ("#ifdef PART_%d\n", j); + for (; rp < k; rp++) + generate_one_opcode (rp,noflags); + printf ("#endif\n\n"); + } + + fprintf (stblfile, "{ 0, 65536, 0 }};\n"); + } + +} + +#if (defined(OS_cygwin) || defined(OS_mingw)) && defined(EXTENDED_SIGSEGV) +void cygwin_mingw_abort() +{ +#undef abort + abort(); +} +#endif + +#if defined(FSUAE) && defined (WINDOWS) +#include "windows.h" +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +#else +int main(void) +#endif +{ + init_table68k (); + + opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); + read_counts (); + + /* It would be a lot nicer to put all in one file (we'd also get rid of + * cputbl.h that way), but cpuopti can't cope. That could be fixed, but + * I don't dare to touch the 68k version. */ + + headerfile = fopen (GEN_PATH "comptbl.h", "wb"); + fprintf (headerfile, "" + "extern const struct comptbl op_smalltbl_0_comp_nf[];\n" + "extern const struct comptbl op_smalltbl_0_comp_ff[];\n" + ""); + + stblfile = fopen (GEN_PATH "compstbl.cpp", "wb"); + if (freopen (GEN_PATH "compemu.cpp", "wb", stdout) == NULL) { + abort(); + } + + generate_includes (stdout); + generate_includes (stblfile); + + printf("#include \"" JIT_PATH "compemu.h\"\n"); + printf("#include \"" JIT_PATH "flags_x86.h\"\n"); + + noflags=0; + generate_func (noflags); + + free(opcode_map); + free(opcode_last_postfix); + free(opcode_next_clev); + free(counts); + + opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); + read_counts (); + noflags=1; + generate_func (noflags); + + printf ("#endif\n"); + fprintf (stblfile, "#endif\n"); + + free(opcode_map); + free(opcode_last_postfix); + free(opcode_next_clev); + free(counts); + + free (table68k); + fclose (stblfile); + fclose (headerfile); + (void)disasm_this_inst; + return 0; +} + +#ifdef UAE +void write_log (const TCHAR *format,...) +{ +} +#endif diff --git a/BasiliskII/src/uae_cpu_2021/cpu_emulation.h b/BasiliskII/src/uae_cpu_2021/cpu_emulation.h new file mode 100644 index 000000000..b014be79d --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/cpu_emulation.h @@ -0,0 +1,263 @@ +/* + * cpu_emulation.h - CPU interface + * + * Copyright (c) 2001-2005 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; 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 + */ + +#if 0 +#include "sysdeps.h" +#include "memory.h" +#include "tools.h" +#endif + +// RAM and ROM pointers (allocated and set by main_*.cpp) +#if 0 +extern memptr RAMBase; // RAM base (Atari address space), does not include Low Mem when != 0 +#else +extern uint32 RAMBaseMac; // RAM base (Mac address space), does not include Low Mem when != 0 +#endif +extern uint8 *RAMBaseHost; // RAM base (host address space) +extern uint32 RAMSize; // Size of RAM +#if 0 +extern memptr ROMBase; // ROM base (Atari address space) +#else +extern uint32 ROMBaseMac; // ROM base (Mac address space) +#endif +extern uint8 *ROMBaseHost; // ROM base (host address space) +extern uint32 ROMSize; // Size of ROM +#if 0 +extern uint32 RealROMSize; // Real size of ROM +extern memptr HWBase; // HW base (Atari address space) +extern uint8 *HWBaseHost; // HW base (host address space) +extern uint32 HWSize; // Size of HW space + +extern memptr FastRAMBase; // Fast-RAM base (Atari address space) +extern uint8 *FastRAMBaseHost; // Fast-RAM base (host address space) +extern memptr VideoRAMBase; // VideoRAM base (Atari address space) +extern uint8 *VideoRAMBaseHost; // VideoRAM base (host address space) + +#ifdef HW_SIGSEGV +extern uint8 *FakeIOBaseHost; +#endif + +#ifdef RAMENDNEEDED +# define RAMEnd 0x01000000 // Not accessible top of memory +#else +# define RAMEnd 0 +#endif +#endif +#if !REAL_ADDRESSING +// If we are not using real 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) +extern uint32 MacFrameSize; // Size of frame buffer +extern int MacFrameLayout; // Frame buffer layout (see defines below) +#endif + +#if 0 +// Atari memory access functions +// Direct access to CPU address space +// For HW operations +// Read/WriteAtariIntXX +// +static inline uint64 ReadAtariInt64(memptr addr) {return phys_get_quad(addr);} +static inline uint32 ReadAtariInt32(memptr addr) {return phys_get_long(addr);} +static inline uint16 ReadAtariInt16(memptr addr) {return phys_get_word(addr);} +static inline uint8 ReadAtariInt8(memptr addr) {return phys_get_byte(addr);} +static inline void WriteAtariInt64(memptr addr, uint64 q) {phys_put_quad(addr, q);} +static inline void WriteAtariInt32(memptr addr, uint32 l) {phys_put_long(addr, l);} +static inline void WriteAtariInt16(memptr addr, uint16 w) {phys_put_word(addr, w);} +static inline void WriteAtariInt8(memptr addr, uint8 b) {phys_put_byte(addr, b);} + +// Direct access to allocated memory +// Ignores HW checks, so that be carefull +// Read/WriteHWMemIntXX +// +static inline uint32 ReadHWMemInt32(memptr addr) {return do_get_mem_long((uae_u32 *)phys_get_real_address(addr));} +static inline uint16 ReadHWMemInt16(memptr addr) {return do_get_mem_word((uae_u16 *)phys_get_real_address(addr));} +static inline uint8 ReadHWMemInt8(memptr addr) {return do_get_mem_byte((uae_u8 *)phys_get_real_address(addr));} +static inline void WriteHWMemInt32(memptr addr, uint32 l) {do_put_mem_long((uae_u32 *)phys_get_real_address(addr), l);} +static inline void WriteHWMemInt16(memptr addr, uint16 w) {do_put_mem_word((uae_u16 *)phys_get_real_address(addr), w);} +static inline void WriteHWMemInt8(memptr addr, uint8 b) {do_put_mem_byte((uae_u8 *)phys_get_real_address(addr), b);} + +// Indirect access to CPU address space +// Uses MMU if available +// For SW operations +// Only data space +// Read/WriteIntXX +// +static inline uint64 ReadInt64(memptr addr) {return get_quad(addr);} +static inline uint32 ReadInt32(memptr addr) {return get_long(addr);} +static inline uint16 ReadInt16(memptr addr) {return get_word(addr);} +static inline uint8 ReadInt8(memptr addr) {return get_byte(addr);} +static inline void WriteInt64(memptr addr, uint64 q) {put_quad(addr, q);} +static inline void WriteInt32(memptr addr, uint32 l) {put_long(addr, l);} +static inline void WriteInt16(memptr addr, uint16 w) {put_word(addr, w);} +static inline void WriteInt8(memptr addr, uint8 b) {put_byte(addr, b);} + +#ifdef EXTENDED_SIGSEGV +extern int in_handler; +#ifdef NO_NESTED_SIGSEGV +extern JMP_BUF sigsegv_env; +# define BUS_ERROR(a) \ +{ \ + regs.mmu_fault_addr=(a); \ + if (in_handler) \ + { \ + in_handler = 0; \ + LONGJMP(sigsegv_env, 1); \ + } \ + else { \ + breakpt(); \ + THROW(2); \ + } \ +} +#else /* NO_NESTED_SIGSEGV */ +# define BUS_ERROR(a) \ +{ \ + regs.mmu_fault_addr=(a); \ + in_handler = 0; \ + breakpt(); \ + THROW(2); \ +} +#endif /* NO_NESTED_SIGSEGV */ +#else /* EXTENDED_SIGSEGV */ +# define BUS_ERROR(a) \ +{ \ + regs.mmu_fault_addr=(a); \ + breakpt(); \ + THROW(2); \ +} +#endif /* EXTENDED_SIGSEGV */ + +// For address validation +static inline bool ValidAtariAddr(memptr addr, bool write, uint32 len) { return phys_valid_address(addr, write, len); } +static inline bool ValidAddr(memptr addr, bool write, uint32 len) { return valid_address(addr, write, len); } + +// Helper functions for usual memory operations +static inline uint8 *Atari2HostAddr(memptr addr) {return phys_get_real_address(addr);} +#endif +// Possible frame buffer layouts +enum { + FLAYOUT_NONE, // No frame buffer + FLAYOUT_DIRECT, // Frame buffer is in MacOS layout, no conversion needed + FLAYOUT_HOST_555, // 16 bit, RGB 555, host byte order + FLAYOUT_HOST_565, // 16 bit, RGB 565, host byte order + FLAYOUT_HOST_888 // 32 bit, RGB 888, host byte order +}; + +// Mac memory access functions +#include "memory.h" +static inline uint32 ReadMacInt32(uint32 addr) {return get_long(addr);} +static inline uint32 ReadMacInt16(uint32 addr) {return get_word(addr);} +static inline uint32 ReadMacInt8(uint32 addr) {return get_byte(addr);} +static inline void WriteMacInt32(uint32 addr, uint32 l) {put_long(addr, l);} +static inline void WriteMacInt16(uint32 addr, uint32 w) {put_word(addr, w);} +static inline void WriteMacInt8(uint32 addr, uint32 b) {put_byte(addr, b);} +static inline uint8 *Mac2HostAddr(uint32 addr) {return get_real_address(addr);} +static inline uint32 Host2MacAddr(uint8 *addr) {return get_virtual_address(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);} + + +// From newcpu.cpp +extern int quit_program; +extern int exit_val; + +/* + * 680x0 emulation + */ + +// Initialization +#if 0 +extern bool InitMEM(); +#endif +extern bool Init680x0(void); +#if 0 +extern void Reset680x0(void); +#endif +extern void Exit680x0(void); +#if 0 +extern void AtariReset(void); +#endif + +// 680x0 emulation functions +struct M68kRegisters; +extern void Start680x0(void); // Reset and start 680x0 +#if 0 +extern void Restart680x0(void); // Restart running 680x0 +extern void Quit680x0(void); // Quit 680x0 +#endif + +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 +#if 0 +extern int MFPdoInterrupt(void); +extern int SCCdoInterrupt(void); +extern void TriggerInternalIRQ(void); +extern void TriggerInt3(void); // Trigger interrupt level 3 +extern void TriggerVBL(void); // Trigger interrupt level 4 +extern void TriggerInt5(void); // Trigger interrupt level 5 +extern void TriggerSCC(bool); // Trigger interrupt level 5 +extern void TriggerMFP(bool); // Trigger interrupt level 6 +#endif +extern void TriggerInterrupt(void); // Trigger interrupt level 1 (InterruptFlag must be set first) +extern void TriggerNMI(void); // Trigger interrupt level 7 + +#if 0 +#ifdef FLIGHT_RECORDER +extern void cpu_flight_recorder(int); +extern void dump_flight_recorder(void); +#endif +#endif + +// CPU looping handlers +void check_eps_limit(uaecptr); +void report_double_bus_error(void); + +#if 0 +// This function will be removed +static inline uaecptr showPC(void) { return m68k_getpc(); } // for debugging only +#endif + +extern int intlev(void); +static inline void AtariReset(void) {} + +#endif + +/* +vim:ts=4:sw=4: +*/ diff --git a/BasiliskII/src/uae_cpu_2021/cpummu.h b/BasiliskII/src/uae_cpu_2021/cpummu.h new file mode 100644 index 000000000..01359f6f5 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/cpummu.h @@ -0,0 +1,267 @@ +/* + * cpummu.h - MMU emulation + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by UAE MMU patch + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CPUMMU_H +#define CPUMMU_H + +#include "registers.h" + +# include + +#define MMU_TEST_PTEST 1 +#define MMU_TEST_VERBOSE 2 +#define MMU_TEST_FORCE_TABLE_SEARCH 4 +#define MMU_TEST_NO_BUSERR 8 + +extern void mmu_dump_tables(void); + +#define MMU_TTR_LOGICAL_BASE 0xff000000 +#define MMU_TTR_LOGICAL_MASK 0x00ff0000 +#define MMU_TTR_BIT_ENABLED (1 << 15) +#define MMU_TTR_BIT_SFIELD_ENABLED (1 << 14) +#define MMU_TTR_BIT_SFIELD_SUPER (1 << 13) +#define MMU_TTR_SFIELD_SHIFT 13 +#define MMU_TTR_UX_MASK ((1 << 9) | (1 << 8)) +#define MMU_TTR_UX_SHIFT 8 +#define MMU_TTR_CACHE_MASK ((1 << 6) | (1 << 5)) +#define MMU_TTR_CACHE_SHIFT 5 +#define MMU_TTR_BIT_WRITE_PROTECT (1 << 2) + +#define MMU_UDT_MASK 3 +#define MMU_PDT_MASK 3 + +#define MMU_DES_WP 4 +#define MMU_DES_USED 8 + +/* page descriptors only */ +#define MMU_DES_MODIFIED 16 +#define MMU_DES_SUPER (1 << 7) +#define MMU_DES_GLOBAL (1 << 10) + +#define MMU_ROOT_PTR_ADDR_MASK 0xfffffe00 +#define MMU_PTR_PAGE_ADDR_MASK_8 0xffffff80 +#define MMU_PTR_PAGE_ADDR_MASK_4 0xffffff00 + +#define MMU_PAGE_INDIRECT_MASK 0xfffffffc +#define MMU_PAGE_ADDR_MASK_8 0xffffe000 +#define MMU_PAGE_ADDR_MASK_4 0xfffff000 +#define MMU_PAGE_UR_MASK_8 ((1 << 12) | (1 << 11)) +#define MMU_PAGE_UR_MASK_4 (1 << 11) +#define MMU_PAGE_UR_SHIFT 11 + +#define MMU_MMUSR_ADDR_MASK 0xfffff000 +#define MMU_MMUSR_B (1 << 11) +#define MMU_MMUSR_G (1 << 10) +#define MMU_MMUSR_U1 (1 << 9) +#define MMU_MMUSR_U0 (1 << 8) +#define MMU_MMUSR_Ux (MMU_MMUSR_U1 | MMU_MMUSR_U0) +#define MMU_MMUSR_S (1 << 7) +#define MMU_MMUSR_CM ((1 << 6) | ( 1 << 5)) +#define MMU_MMUSR_M (1 << 4) +#define MMU_MMUSR_W (1 << 2) +#define MMU_MMUSR_T (1 << 1) +#define MMU_MMUSR_R (1 << 0) + +/* special status word (access error stack frame) */ +#define MMU_SSW_TM 0x0007 +#define MMU_SSW_TT 0x0018 +#define MMU_SSW_SIZE 0x0060 +#define MMU_SSW_SIZE_B 0x0020 +#define MMU_SSW_SIZE_W 0x0040 +#define MMU_SSW_SIZE_L 0x0000 +#define MMU_SSW_RW 0x0100 +#define MMU_SSW_LK 0x0200 +#define MMU_SSW_ATC 0x0400 +#define MMU_SSW_MA 0x0800 + +#define TTR_I0 4 +#define TTR_I1 5 +#define TTR_D0 6 +#define TTR_D1 7 + +#define TTR_NO_MATCH 0 +#define TTR_NO_WRITE 1 +#define TTR_OK_MATCH 2 + +struct mmu_atc_line { + uae_u16 tag; + unsigned tt : 1; + unsigned valid_data : 1; + unsigned valid_inst : 1; + unsigned global : 1; + unsigned modified : 1; + unsigned write_protect : 1; + unsigned hw : 1; + unsigned bus_fault : 1; + uaecptr phys; +}; + +/* + * We don't need to store the whole logical address in the atc cache, as part of + * it is encoded as index into the cache. 14 bits of the address are stored in + * the tag, this means at least 6 bits must go into the index. The upper two + * bits of the tag define the type of data in the atc line: + * - 00: a normal memory address + * - 11: invalid memory address or hardware access + * (generated via ~ATC_TAG(addr) in the slow path) + * - 10: empty atc line + */ + +#define ATC_TAG_SHIFT 18 +#define ATC_TAG(addr) ((uae_u32)(addr) >> ATC_TAG_SHIFT) + + +#define ATC_L1_SIZE_LOG 8 +#define ATC_L1_SIZE (1 << ATC_L1_SIZE_LOG) + +#define ATC_L1_INDEX(addr) (((addr) >> 12) % ATC_L1_SIZE) + +/* + * first level atc cache + * indexed by [super][data][rw][idx] + */ + +typedef struct mmu_atc_line mmu_atc_l1_array[2][2][ATC_L1_SIZE]; +extern mmu_atc_l1_array atc_l1[2]; +extern mmu_atc_l1_array *current_atc; + +#define ATC_L2_SIZE_LOG 12 +#define ATC_L2_SIZE (1 << ATC_L2_SIZE_LOG) + +#define ATC_L2_INDEX(addr) ((((addr) >> 12) ^ ((addr) >> (32 - ATC_L2_SIZE_LOG))) % ATC_L2_SIZE) + +extern struct mmu_atc_line atc_l2[2][ATC_L2_SIZE]; + +/* + * lookup address in the level 1 atc cache, + * the data and write arguments are constant in the common, + * thus allows gcc to generate a constant offset. + */ +static ALWAYS_INLINE int mmu_lookup(uaecptr addr, bool data, bool write, + struct mmu_atc_line **cl) +{ + addr >>= 12; + *cl = &(*current_atc)[data][write][addr % ATC_L1_SIZE]; + return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12); +} + +/* + * similiar to mmu_user_lookup, but for the use of the moves instruction + */ +static ALWAYS_INLINE int mmu_user_lookup(uaecptr addr, bool super, bool data, + bool write, struct mmu_atc_line **cl) +{ + addr >>= 12; + *cl = &atc_l1[super][data][write][addr % ATC_L1_SIZE]; + return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12); +} + +extern REGPARAM2 uae_u16 mmu_get_word_unaligned(uaecptr addr, int data); +extern REGPARAM2 uae_u32 mmu_get_long_unaligned(uaecptr addr, int data); + +extern REGPARAM2 uae_u8 mmu_get_byte_slow(uaecptr addr, int super, int data, + int size, struct mmu_atc_line *cl); +extern REGPARAM2 uae_u16 mmu_get_word_slow(uaecptr addr, int super, int data, + int size, struct mmu_atc_line *cl); +extern REGPARAM2 uae_u32 mmu_get_long_slow(uaecptr addr, int super, int data, + int size, struct mmu_atc_line *cl); +extern REGPARAM2 uae_u64 mmu_get_quad_slow(uaecptr addr, int super, int data, + struct mmu_atc_line *cl); + +extern REGPARAM2 void mmu_put_word_unaligned(uaecptr addr, uae_u16 val, int data); +extern REGPARAM2 void mmu_put_long_unaligned(uaecptr addr, uae_u32 val, int data); + +extern REGPARAM2 void mmu_put_byte_slow(uaecptr addr, uae_u8 val, int super, int data, + int size, struct mmu_atc_line *cl); +extern REGPARAM2 void mmu_put_word_slow(uaecptr addr, uae_u16 val, int super, int data, + int size, struct mmu_atc_line *cl); +extern REGPARAM2 void mmu_put_long_slow(uaecptr addr, uae_u32 val, int super, int data, + int size, struct mmu_atc_line *cl); +extern REGPARAM2 void mmu_put_quad_slow(uaecptr addr, uae_u64 val, int super, int data, + struct mmu_atc_line *cl); + +extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode); + +static inline void mmu_set_ttr(int regno, uae_u32 val) +{ + uae_u32 * ttr; + switch(regno) { + case TTR_I0: ttr = ®s.itt0; break; + case TTR_I1: ttr = ®s.itt1; break; + case TTR_D0: ttr = ®s.dtt0; break; + case TTR_D1: ttr = ®s.dtt1; break; + default: abort(); + } + *ttr = val; +} + +static inline void mmu_set_mmusr(uae_u32 val) +{ + regs.mmusr = val; +} + +#define FC_DATA (regs.s ? 5 : 1) +#define FC_INST (regs.s ? 6 : 2) + +extern uaecptr REGPARAM2 mmu_translate(uaecptr addr, int super, int data, int write); + +extern uae_u32 REGPARAM2 sfc_get_long(uaecptr addr); +extern uae_u16 REGPARAM2 sfc_get_word(uaecptr addr); +extern uae_u8 REGPARAM2 sfc_get_byte(uaecptr addr); +extern void REGPARAM2 dfc_put_long(uaecptr addr, uae_u32 val); +extern void REGPARAM2 dfc_put_word(uaecptr addr, uae_u16 val); +extern void REGPARAM2 dfc_put_byte(uaecptr addr, uae_u8 val); + + +extern void REGPARAM2 mmu_flush_atc(uaecptr addr, bool super, bool global); +extern void REGPARAM2 mmu_flush_atc_all(bool global); +extern void REGPARAM2 mmu_op(uae_u32 opcode, uae_u16 extra); + +#ifdef FULLMMU + +extern void REGPARAM2 mmu_reset(void); +extern void REGPARAM2 mmu_set_tc(uae_u16 tc); +extern void REGPARAM2 mmu_set_super(bool super); + +#else + +static inline void mmu_reset(void) +{ +} + +static inline void mmu_set_tc(uae_u16 /*tc*/) +{ +} + +static inline void mmu_set_super(bool /*super*/) +{ +} + +#endif + +#endif /* CPUMMU_H */ +/* +vim:ts=4:sw=4: +*/ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/core.h b/BasiliskII/src/uae_cpu_2021/fpu/core.h new file mode 100644 index 000000000..2eccc4d24 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/core.h @@ -0,0 +1,263 @@ +/* + * fpu/core.h - base fpu context definition + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_CORE_H +#define FPU_CORE_H + +#include "sysdeps.h" +#include "fpu/types.h" + +/* Always use x87 FPU stack on IA-32. */ +#if defined(X86_ASSEMBLY) +#define USE_X87_ASSEMBLY 1 +#ifndef USE_JIT_FPU +#define ACCURATE_SIN_COS_TAN 1 +#endif +#endif + +/* Only use x87 FPU on x86-64 if long double precision is requested. */ +#if defined(X86_64_ASSEMBLY) && defined(USE_LONG_DOUBLE) +#define USE_X87_ASSEMBLY 1 +#define ACCURATE_SIN_COS_TAN 1 +#endif + +/* ========================================================================== */ +/* ========================= FPU CONTEXT DEFINITION ========================= */ +/* ========================================================================== */ + +/* We don't use all features of the C++ language so that we may still + * easily backport that code to C. + */ + +struct fpu_t { + + /* ---------------------------------------------------------------------- */ + /* --- Floating-Point Data Registers --- */ + /* ---------------------------------------------------------------------- */ + + /* The eight %fp0 .. %fp7 registers */ + fpu_register registers[8]; + + /* Used for lazy evalualation of FPU flags */ + fpu_register result; + + /* ---------------------------------------------------------------------- */ + /* --- Floating-Point Control Register --- */ + /* ---------------------------------------------------------------------- */ + + /* Exception Enable Byte */ + #define FPCR_EXCEPTION_ENABLE 0x0000ff00 + #define FPCR_EXCEPTION_BSUN 0x00008000 + #define FPCR_EXCEPTION_SNAN 0x00004000 + #define FPCR_EXCEPTION_OPERR 0x00002000 + #define FPCR_EXCEPTION_OVFL 0x00001000 + #define FPCR_EXCEPTION_UNFL 0x00000800 + #define FPCR_EXCEPTION_DZ 0x00000400 + #define FPCR_EXCEPTION_INEX2 0x00000200 + #define FPCR_EXCEPTION_INEX1 0x00000100 + + /* Mode Control Byte Mask */ + #define FPCR_MODE_CONTROL 0x000000ff + + /* Rounding precision */ + #define FPCR_ROUNDING_PRECISION 0x000000c0 + #define FPCR_PRECISION_SINGLE 0x00000040 + #define FPCR_PRECISION_DOUBLE 0x00000080 + #define FPCR_PRECISION_EXTENDED 0x00000000 + + /* Rounding mode */ + #define FPCR_ROUNDING_MODE 0x00000030 + #define FPCR_ROUND_NEAR 0x00000000 + #define FPCR_ROUND_ZERO 0x00000010 + #define FPCR_ROUND_MINF 0x00000020 + #define FPCR_ROUND_PINF 0x00000030 + + uae_u32 fpcr; + + /* ---------------------------------------------------------------------- */ + /* --- Floating-Point Status Register --- */ + /* ---------------------------------------------------------------------- */ + + struct { + + /* Floating-Point Condition Code Byte */ + uae_u32 condition_codes; + #define FPSR_CCB 0x0f000000 + #define FPSR_CCB_NEGATIVE 0x08000000 + #define FPSR_CCB_ZERO 0x04000000 + #define FPSR_CCB_INFINITY 0x02000000 + #define FPSR_CCB_NAN 0x01000000 + + /* Quotient Byte */ + uae_u32 quotient; + #define FPSR_QUOTIENT 0x00ff0000 + #define FPSR_QUOTIENT_SIGN 0x00800000 + #define FPSR_QUOTIENT_VALUE 0x007f0000 + + /* Exception Status Byte */ + uae_u32 exception_status; + #define FPSR_EXCEPTION_STATUS FPCR_EXCEPTION_ENABLE + #define FPSR_EXCEPTION_BSUN FPCR_EXCEPTION_BSUN + #define FPSR_EXCEPTION_SNAN FPCR_EXCEPTION_SNAN + #define FPSR_EXCEPTION_OPERR FPCR_EXCEPTION_OPERR + #define FPSR_EXCEPTION_OVFL FPCR_EXCEPTION_OVFL + #define FPSR_EXCEPTION_UNFL FPCR_EXCEPTION_UNFL + #define FPSR_EXCEPTION_DZ FPCR_EXCEPTION_DZ + #define FPSR_EXCEPTION_INEX2 FPCR_EXCEPTION_INEX2 + #define FPSR_EXCEPTION_INEX1 FPCR_EXCEPTION_INEX1 + + /* Accrued Exception Byte */ + uae_u32 accrued_exception; + #define FPSR_ACCRUED_EXCEPTION 0x000000f8 + #define FPSR_ACCR_IOP 0x00000080 + #define FPSR_ACCR_OVFL 0x00000040 + #define FPSR_ACCR_UNFL 0x00000020 + #define FPSR_ACCR_DZ 0x00000010 + #define FPSR_ACCR_INEX 0x00000008 + + } fpsr; + + /* ---------------------------------------------------------------------- */ + /* --- Floating-Point Instruction Address Register --- */ + /* ---------------------------------------------------------------------- */ + + uae_u32 instruction_address; + + /* ---------------------------------------------------------------------- */ + /* --- Initialization / Finalization --- */ + /* ---------------------------------------------------------------------- */ + + /* Flag set if we emulate an integral 68040 FPU */ + bool is_integral; + + /* ---------------------------------------------------------------------- */ + /* --- Extra FPE-dependant defines --- */ + /* ---------------------------------------------------------------------- */ + + #if defined(FPU_X86) \ + || (defined(FPU_UAE) && defined(USE_X87_ASSEMBLY)) \ + || (defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)) + + #define CW_RESET 0x0040 // initial CW value after RESET + #define CW_FINIT 0x037F // initial CW value after FINIT + #define SW_RESET 0x0000 // initial SW value after RESET + #define SW_FINIT 0x0000 // initial SW value after FINIT + #define TW_RESET 0x5555 // initial TW value after RESET + #define TW_FINIT 0x0FFF // initial TW value after FINIT + + #define CW_X 0x1000 // infinity control + #define CW_RC_ZERO 0x0C00 // rounding control toward zero + #define CW_RC_UP 0x0800 // rounding control toward + + #define CW_RC_DOWN 0x0400 // rounding control toward - + #define CW_RC_NEAR 0x0000 // rounding control toward even + #define CW_PC_EXTENDED 0x0300 // precision control 64bit + #define CW_PC_DOUBLE 0x0200 // precision control 53bit + #define CW_PC_RESERVED 0x0100 // precision control reserved + #define CW_PC_SINGLE 0x0000 // precision control 24bit + #define CW_PM 0x0020 // precision exception mask + #define CW_UM 0x0010 // underflow exception mask + #define CW_OM 0x0008 // overflow exception mask + #define CW_ZM 0x0004 // zero divide exception mask + #define CW_DM 0x0002 // denormalized operand exception mask + #define CW_IM 0x0001 // invalid operation exception mask + + #define SW_B 0x8000 // busy flag + #define SW_C3 0x4000 // condition code flag 3 + #define SW_TOP_7 0x3800 // top of stack = ST(7) + #define SW_TOP_6 0x3000 // top of stack = ST(6) + #define SW_TOP_5 0x2800 // top of stack = ST(5) + #define SW_TOP_4 0x2000 // top of stack = ST(4) + #define SW_TOP_3 0x1800 // top of stack = ST(3) + #define SW_TOP_2 0x1000 // top of stack = ST(2) + #define SW_TOP_1 0x0800 // top of stack = ST(1) + #define SW_TOP_0 0x0000 // top of stack = ST(0) + #define SW_C2 0x0400 // condition code flag 2 + #define SW_C1 0x0200 // condition code flag 1 + #define SW_C0 0x0100 // condition code flag 0 + #define SW_ES 0x0080 // error summary status flag + #define SW_SF 0x0040 // stack fault flag + #define SW_PE 0x0020 // precision exception flag + #define SW_UE 0x0010 // underflow exception flag + #define SW_OE 0x0008 // overflow exception flag + #define SW_ZE 0x0004 // zero divide exception flag + #define SW_DE 0x0002 // denormalized operand exception flag + #define SW_IE 0x0001 // invalid operation exception flag + + #define X86_ROUNDING_MODE 0x0C00 + #define X86_ROUNDING_PRECISION 0x0300 + + #endif /* FPU_X86 */ + +}; + +/* We handle only one global fpu */ +extern fpu_t fpu; + +/* Return the address of a particular register */ +inline fpu_register * fpu_register_address(int i) + { return &fpu.registers[i]; } + +/* Dump functions for m68k_dumpstate */ +extern void fpu_dump_registers(void); +extern void fpu_dump_flags(void); + +/* Accessors to FPU Control Register */ +//static inline uae_u32 get_fpcr(void); +//static inline void set_fpcr(uae_u32 new_fpcr); + +/* Accessors to FPU Status Register */ +//static inline uae_u32 get_fpsr(void); +//static inline void set_fpsr(uae_u32 new_fpsr); + +/* Accessors to FPU Instruction Address Register */ +//static inline uae_u32 get_fpiar(); +//static inline void set_fpiar(uae_u32 new_fpiar); + +/* Initialization / Finalization */ +extern void fpu_init(bool integral_68040); +extern void fpu_exit(void); +extern void fpu_reset(void); + +/* Floating-point arithmetic instructions */ +void fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) REGPARAM; + +/* Floating-point program control operations */ +void fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) REGPARAM; +void fpuop_dbcc(uae_u32 opcode, uae_u32 extra) REGPARAM; +void fpuop_scc(uae_u32 opcode, uae_u32 extra) REGPARAM; + +/* Floating-point system control operations */ +void fpuop_save(uae_u32 opcode) REGPARAM; +void fpuop_restore(uae_u32 opcode) REGPARAM; +void fpuop_trapcc(uae_u32 opcode, uaecptr oldpc, uae_u32 extra) REGPARAM; + +#endif /* FPU_CORE_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/exceptions.cpp b/BasiliskII/src/uae_cpu_2021/fpu/exceptions.cpp new file mode 100644 index 000000000..2a597997d --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/exceptions.cpp @@ -0,0 +1,193 @@ +/* + * fpu/exceptions.cpp - system-dependant FPU exceptions management + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#undef PRIVATE +#define PRIVATE /**/ + +#undef PUBLIC +#define PUBLIC /**/ + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* -------------------------------------------------------------------------- */ +/* --- Native X86 exceptions --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_X86_EXCEPTIONS +void FFPU fpu_init_native_exceptions(void) +{ + // Mapping for "sw" -> fpsr exception byte + for (uae_u32 i = 0; i < 0x80; i++) { + exception_host2mac[i] = 0; + + if(i & SW_FAKE_BSUN) { + exception_host2mac[i] |= FPSR_EXCEPTION_BSUN; + } + // precision exception + if(i & SW_PE) { + exception_host2mac[i] |= FPSR_EXCEPTION_INEX2; + } + // underflow exception + if(i & SW_UE) { + exception_host2mac[i] |= FPSR_EXCEPTION_UNFL; + } + // overflow exception + if(i & SW_OE) { + exception_host2mac[i] |= FPSR_EXCEPTION_OVFL; + } + // zero divide exception + if(i & SW_ZE) { + exception_host2mac[i] |= FPSR_EXCEPTION_DZ; + } + // denormalized operand exception. + // wrong, but should not get here, normalization is done in elsewhere + if(i & SW_DE) { + exception_host2mac[i] |= FPSR_EXCEPTION_SNAN; + } + // invalid operation exception + if(i & SW_IE) { + exception_host2mac[i] |= FPSR_EXCEPTION_OPERR; + } + } + + // Mapping for fpsr exception byte -> "sw" + for (uae_u32 i = 0; i < 0x100; i++) { + uae_u32 fpsr = (i << 8); + exception_mac2host[i] = 0; + + // BSUN; make sure that you don't generate FPU stack faults. + if(fpsr & FPSR_EXCEPTION_BSUN) { + exception_mac2host[i] |= SW_FAKE_BSUN; + } + // precision exception + if(fpsr & FPSR_EXCEPTION_INEX2) { + exception_mac2host[i] |= SW_PE; + } + // underflow exception + if(fpsr & FPSR_EXCEPTION_UNFL) { + exception_mac2host[i] |= SW_UE; + } + // overflow exception + if(fpsr & FPSR_EXCEPTION_OVFL) { + exception_mac2host[i] |= SW_OE; + } + // zero divide exception + if(fpsr & FPSR_EXCEPTION_DZ) { + exception_mac2host[i] |= SW_ZE; + } + // denormalized operand exception + if(fpsr & FPSR_EXCEPTION_SNAN) { + exception_mac2host[i] |= SW_DE; //Wrong + } + // invalid operation exception + if(fpsr & FPSR_EXCEPTION_OPERR) { + exception_mac2host[i] |= SW_IE; + } + } +} +#endif + +#ifdef FPU_USE_X86_ACCRUED_EXCEPTIONS +void FFPU fpu_init_native_accrued_exceptions(void) +{ + /* + 68881/68040 accrued exceptions accumulate as follows: + Accrued.IOP |= (Exception.SNAN | Exception.OPERR) + Accrued.OVFL |= (Exception.OVFL) + Accrued.UNFL |= (Exception.UNFL | Exception.INEX2) + Accrued.DZ |= (Exception.DZ) + Accrued.INEX |= (Exception.INEX1 | Exception.INEX2 | Exception.OVFL) + */ + + // Mapping for "fpsr.accrued_exception" -> fpsr accrued exception byte + for (uae_u32 i = 0; i < 0x40; i++ ) { + accrued_exception_host2mac[i] = 0; + + // precision exception + if(i & SW_PE) { + accrued_exception_host2mac[i] |= FPSR_ACCR_INEX; + } + // underflow exception + if(i & SW_UE) { + accrued_exception_host2mac[i] |= FPSR_ACCR_UNFL; + } + // overflow exception + if(i & SW_OE) { + accrued_exception_host2mac[i] |= FPSR_ACCR_OVFL; + } + // zero divide exception + if(i & SW_ZE) { + accrued_exception_host2mac[i] |= FPSR_ACCR_DZ; + } + // denormalized operand exception + if(i & SW_DE) { + accrued_exception_host2mac[i] |= FPSR_ACCR_IOP; //?????? + } + // invalid operation exception + if(i & SW_IE) { + accrued_exception_host2mac[i] |= FPSR_ACCR_IOP; + } + } + + // Mapping for fpsr accrued exception byte -> "fpsr.accrued_exception" + for (uae_u32 i = 0; i < 0x20; i++) { + int fpsr = (i << 3); + accrued_exception_mac2host[i] = 0; + + // precision exception + if(fpsr & FPSR_ACCR_INEX) { + accrued_exception_mac2host[i] |= SW_PE; + } + // underflow exception + if(fpsr & FPSR_ACCR_UNFL) { + accrued_exception_mac2host[i] |= SW_UE; + } + // overflow exception + if(fpsr & FPSR_ACCR_OVFL) { + accrued_exception_mac2host[i] |= SW_OE; + } + // zero divide exception + if(fpsr & FPSR_ACCR_DZ) { + accrued_exception_mac2host[i] |= SW_ZE; + } + // What about SW_DE; //?????? + // invalid operation exception + if(fpsr & FPSR_ACCR_IOP) { + accrued_exception_mac2host[i] |= SW_IE; + } + } +} +#endif diff --git a/BasiliskII/src/uae_cpu_2021/fpu/exceptions.h b/BasiliskII/src/uae_cpu_2021/fpu/exceptions.h new file mode 100644 index 000000000..f943da04f --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/exceptions.h @@ -0,0 +1,154 @@ +/* + * fpu/exceptions.h - system-dependant FPU exceptions management + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_EXCEPTIONS_H +#define FPU_EXCEPTIONS_H + +/* NOTE: this file shall be included only from fpu/fpu_*.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* Defaults to generic exceptions */ +#define FPU_USE_GENERIC_EXCEPTIONS +#define FPU_USE_GENERIC_ACCRUED_EXCEPTIONS + +/* -------------------------------------------------------------------------- */ +/* --- Selection of floating-point exceptions handling mode --- */ +/* -------------------------------------------------------------------------- */ + +/* Optimized i386 fpu core must use native exceptions */ +#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_EXCEPTIONS +# define FPU_USE_X86_EXCEPTIONS +#endif + +/* Optimized i386 fpu core must use native accrued exceptions */ +#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_ACCRUED_EXCEPTIONS +# define FPU_USE_X86_ACCRUED_EXCEPTIONS +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Native X86 Exceptions --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_X86_EXCEPTIONS + +/* Extend the SW_* codes */ +#define SW_FAKE_BSUN SW_SF + +/* Shorthand */ +#define SW_EXCEPTION_MASK (SW_ES|SW_SF|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE) +// #define SW_EXCEPTION_MASK (SW_SF|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE) + +/* Lookup tables */ +PRIVATE uae_u32 exception_host2mac[ 0x80 ]; +PRIVATE uae_u32 exception_mac2host[ 0x100 ]; + +/* Initialize native exception management */ +PUBLIC void FFPU fpu_init_native_exceptions(void); + +/* Return m68k floating-point exception status */ +PRIVATE inline uae_u32 FFPU get_exception_status(void) + { return exception_host2mac[FPU fpsr.exception_status & (SW_FAKE_BSUN|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE)]; } + +/* Set new exception status. Assumes mask against FPSR_EXCEPTION to be already performed */ +PRIVATE inline void FFPU set_exception_status(uae_u32 new_status) + { FPU fpsr.exception_status = exception_mac2host[new_status >> 8]; } + +#endif /* FPU_USE_X86_EXCEPTIONS */ + +#ifdef FPU_USE_X86_ACCRUED_EXCEPTIONS + +/* Lookup tables */ +PRIVATE uae_u32 accrued_exception_host2mac[ 0x40 ]; +PRIVATE uae_u32 accrued_exception_mac2host[ 0x20 ]; + +/* Initialize native accrued exception management */ +PUBLIC void FFPU fpu_init_native_accrued_exceptions(void); + +/* Return m68k accrued exception byte */ +PRIVATE inline uae_u32 FFPU get_accrued_exception(void) + { return accrued_exception_host2mac[FPU fpsr.accrued_exception & (SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE)]; } + +/* Set new accrued exception byte */ +PRIVATE inline void FFPU set_accrued_exception(uae_u32 new_status) + { FPU fpsr.accrued_exception = accrued_exception_mac2host[(new_status & 0xF8) >> 3]; } + +#endif /* FPU_USE_X86_ACCRUED_EXCEPTIONS */ + +/* -------------------------------------------------------------------------- */ +/* --- Default Exceptions Handling --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_GENERIC_EXCEPTIONS + +/* Initialize native exception management */ +static inline void FFPU fpu_init_native_exceptions(void) + { } + +/* Return m68k floating-point exception status */ +PRIVATE inline uae_u32 FFPU get_exception_status(void) + { return FPU fpsr.exception_status; } + +/* Set new exception status. Assumes mask against FPSR_EXCEPTION to be already performed */ +PRIVATE inline void FFPU set_exception_status(uae_u32 new_status) + { FPU fpsr.exception_status = new_status; } + +#endif /* FPU_USE_GENERIC_EXCEPTIONS */ + +#ifdef FPU_USE_GENERIC_ACCRUED_EXCEPTIONS + +/* Initialize native accrued exception management */ +PRIVATE inline void FFPU fpu_init_native_accrued_exceptions(void) + { } + +/* Return m68k accrued exception byte */ +PRIVATE inline uae_u32 FFPU get_accrued_exception(void) + { return FPU fpsr.accrued_exception; } + +/* Set new accrued exception byte */ +PRIVATE inline void FFPU set_accrued_exception(uae_u32 new_status) + { FPU fpsr.accrued_exception = new_status; } + +#endif /* FPU_USE_GENERIC_ACCRUED_EXCEPTIONS */ + +#endif /* FPU_EXCEPTIONS_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/flags.cpp b/BasiliskII/src/uae_cpu_2021/fpu/flags.cpp new file mode 100644 index 000000000..4b0972df3 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/flags.cpp @@ -0,0 +1,174 @@ +/* + * fpu/flags.cpp - Floating-point flags + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* NOTE: this file shall be included only from fpu/fpu_*.cpp */ +#undef PRIVATE +#define PRIVATE /**/ + +#undef PUBLIC +#define PUBLIC /**/ + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* -------------------------------------------------------------------------- */ +/* --- Native X86 floating-point flags --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_X86_FLAGS + +/* Initialization */ +void FFPU fpu_init_native_fflags(void) +{ + // Adapted from fpu_x86.cpp + #define SW_Z_I_NAN_MASK (SW_C0|SW_C2|SW_C3) + #define SW_Z (SW_C3) + #define SW_I (SW_C0|SW_C2) + #define SW_NAN (SW_C0) + #define SW_FINITE (SW_C2) + #define SW_EMPTY_REGISTER (SW_C0|SW_C3) + #define SW_DENORMAL (SW_C2|SW_C3) + #define SW_UNSUPPORTED (0) + #define SW_N (SW_C1) + + // Sanity checks + #if (SW_Z != NATIVE_FFLAG_ZERO) + #error "Incorrect X86 Z fflag" + #endif + #if (SW_I != NATIVE_FFLAG_INFINITY) + #error "Incorrect X86 I fflag" + #endif + #if (SW_N != NATIVE_FFLAG_NEGATIVE) + #error "Incorrect X86 N fflag" + #endif + #if (SW_NAN != NATIVE_FFLAG_NAN) + #error "Incorrect X86 NAN fflag" + #endif + + // Native status word to m68k mappings + for (uae_u32 i = 0; i < 0x48; i++) { + to_m68k_fpcond[i] = 0; + const uae_u32 native_fpcond = i << 8; + switch (native_fpcond & SW_Z_I_NAN_MASK) { +#ifndef FPU_UAE +// gb-- enabling it would lead to incorrect drawing of digits +// in Speedometer Performance Test + case SW_UNSUPPORTED: +#endif + case SW_NAN: + case SW_EMPTY_REGISTER: + to_m68k_fpcond[i] |= FPSR_CCB_NAN; + break; + case SW_FINITE: + case SW_DENORMAL: + break; + case SW_I: + to_m68k_fpcond[i] |= FPSR_CCB_INFINITY; + break; + case SW_Z: + to_m68k_fpcond[i] |= FPSR_CCB_ZERO; + break; + } + if (native_fpcond & SW_N) + to_m68k_fpcond[i] |= FPSR_CCB_NEGATIVE; + } + + // m68k to native status word mappings + for (uae_u32 i = 0; i < 0x10; i++) { + const uae_u32 m68k_fpcond = i << 24; + if (m68k_fpcond & FPSR_CCB_NAN) + to_host_fpcond[i] = SW_NAN; + else if (m68k_fpcond & FPSR_CCB_ZERO) + to_host_fpcond[i] = SW_Z; + else if (m68k_fpcond & FPSR_CCB_INFINITY) + to_host_fpcond[i] = SW_I; + else + to_host_fpcond[i] = SW_FINITE; + if (m68k_fpcond & FPSR_CCB_NEGATIVE) + to_host_fpcond[i] |= SW_N; + } + + // truth-table for FPU conditions + for (uae_u32 host_fpcond = 0; host_fpcond < 0x08; host_fpcond++) { + // host_fpcond: C3 on bit 2, C1 and C0 are respectively on bits 1 and 0 + const uae_u32 real_host_fpcond = ((host_fpcond & 4) << 12) | ((host_fpcond & 3) << 8); + const bool N = ((real_host_fpcond & NATIVE_FFLAG_NEGATIVE) == NATIVE_FFLAG_NEGATIVE); + const bool Z = ((real_host_fpcond & NATIVE_FFLAG_ZERO) == NATIVE_FFLAG_ZERO); + const bool NaN = ((real_host_fpcond & NATIVE_FFLAG_NAN) == NATIVE_FFLAG_NAN); + + int value; + for (uae_u32 m68k_fpcond = 0; m68k_fpcond < 0x20; m68k_fpcond++) { + switch (m68k_fpcond) { + case 0x00: value = 0; break; // False + case 0x01: value = Z; break; // Equal + case 0x02: value = !(NaN || Z || N); break; // Ordered Greater Than + case 0x03: value = Z || !(NaN || N); break; // Ordered Greater Than or Equal + case 0x04: value = N && !(NaN || Z); break; // Ordered Less Than + case 0x05: value = Z || (N && !NaN); break; // Ordered Less Than or Equal + case 0x06: value = !(NaN || Z); break; // Ordered Greater or Less Than + case 0x07: value = !NaN; break; // Ordered + case 0x08: value = NaN; break; // Unordered + case 0x09: value = NaN || Z; break; // Unordered or Equal + case 0x0a: value = NaN || !(N || Z); break; // Unordered or Greater Than + case 0x0b: value = NaN || Z || !N; break; // Unordered or Greater or Equal + case 0x0c: value = NaN || (N && !Z); break; // Unordered or Less Than + case 0x0d: value = NaN || Z || N; break; // Unordered or Less or Equal + case 0x0e: value = !Z; break; // Not Equal + case 0x0f: value = 1; break; // True + case 0x10: value = 0; break; // Signaling False + case 0x11: value = Z; break; // Signaling Equal + case 0x12: value = !(NaN || Z || N); break; // Greater Than + case 0x13: value = Z || !(NaN || N); break; // Greater Than or Equal + case 0x14: value = N && !(NaN || Z); break; // Less Than + case 0x15: value = Z || (N && !NaN); break; // Less Than or Equal + case 0x16: value = !(NaN || Z); break; // Greater or Less Than + case 0x17: value = !NaN; break; // Greater, Less or Equal + case 0x18: value = NaN; break; // Not Greater, Less or Equal + case 0x19: value = NaN || Z; break; // Not Greater or Less Than + case 0x1a: value = NaN || !(N || Z); break; // Not Less Than or Equal + case 0x1b: value = NaN || Z || !N; break; // Not Less Than + case 0x1c: value = NaN || (N && !Z); break; // Not Greater Than or Equal +// case 0x1c: value = !Z && (NaN || N); break; // Not Greater Than or Equal + case 0x1d: value = NaN || Z || N; break; // Not Greater Than + case 0x1e: value = !Z; break; // Signaling Not Equal + case 0x1f: value = 1; break; // Signaling True + default: value = -1; + } + fpcond_truth_table[m68k_fpcond][host_fpcond] = value; + } + } +} + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/fpu/flags.h b/BasiliskII/src/uae_cpu_2021/fpu/flags.h new file mode 100644 index 000000000..de25a2b66 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/flags.h @@ -0,0 +1,228 @@ +/* + * fpu/flags.h - Floating-point flags + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_FLAGS_H +#define FPU_FLAGS_H + +/* NOTE: this file shall be included only from fpu/fpu_*.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* Defaults to generic flags */ +#define FPU_USE_GENERIC_FLAGS + +/* -------------------------------------------------------------------------- */ +/* --- Selection of floating-point flags handling mode --- */ +/* -------------------------------------------------------------------------- */ + +/* Optimized i386 fpu core must use native flags */ +#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_FLAGS +# define FPU_USE_X86_FLAGS +#endif + +/* Old UAE FPU core can use native flags */ +#if defined(FPU_UAE) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_FLAGS +# define FPU_USE_X86_FLAGS +#endif + +/* IEEE-based implementation must use lazy flag evaluation */ +#if defined(FPU_IEEE) +# undef FPU_USE_GENERIC_FLAGS +# define FPU_USE_LAZY_FLAGS +#endif + +/* JIT Compilation for FPU only works with lazy evaluation of FPU flags */ +#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) && defined(USE_JIT_FPU) +# undef FPU_USE_GENERIC_FLAGS +# define FPU_USE_LAZY_FLAGS +#endif + +#ifdef FPU_IMPLEMENTATION + +/* -------------------------------------------------------------------------- */ +/* --- Native X86 Floating-Point Flags --- */ +/* -------------------------------------------------------------------------- */ + +/* FPU_X86 has its own set of lookup functions */ + +#ifdef FPU_USE_X86_FLAGS + +#define FPU_USE_NATIVE_FLAGS + +#define NATIVE_FFLAG_NEGATIVE 0x0200 +#define NATIVE_FFLAG_ZERO 0x4000 +#define NATIVE_FFLAG_INFINITY 0x0500 +#define NATIVE_FFLAG_NAN 0x0100 + +/* Translation tables between native and m68k floating-point flags */ +PRIVATE uae_u32 to_m68k_fpcond[0x48]; +PRIVATE uae_u32 to_host_fpcond[0x10]; + +/* Truth table for floating-point condition codes */ +PRIVATE uae_u32 fpcond_truth_table[32][8]; // 32 m68k conditions x 8 host condition codes + +/* Initialization */ +PUBLIC void FFPU fpu_init_native_fflags(void); + +#ifdef FPU_UAE + +/* Native to m68k floating-point condition codes */ +PRIVATE inline uae_u32 FFPU get_fpccr(void) + { return to_m68k_fpcond[(FPU fpsr.condition_codes >> 8) & 0x47]; } + +/* M68k to native floating-point condition codes */ +PRIVATE inline void FFPU set_fpccr(uae_u32 new_fpcond) + /* Precondition: new_fpcond is only valid for floating-point condition codes */ + { FPU fpsr.condition_codes = to_host_fpcond[new_fpcond >> 24]; } + +/* Make FPSR according to the value passed in argument */ +PRIVATE inline void FFPU make_fpsr(fpu_register const & r) + { uae_u16 sw; __asm__ __volatile__ ("fxam\n\tfnstsw %0" : "=a" (sw) : "f" (r)); FPU fpsr.condition_codes = sw; } + +/* Return the corresponding ID of the current floating-point condition codes */ +/* NOTE: only valid for evaluation of a condition */ +PRIVATE inline int FFPU host_fpcond_id(void) + { return ((FPU fpsr.condition_codes >> 12) & 4) | ((FPU fpsr.condition_codes >> 8) & 3); } + +/* Return true if the floating-point condition is satisfied */ +PRIVATE inline bool FFPU fpcctrue(int condition) + { return fpcond_truth_table[condition][host_fpcond_id()]; } + +#endif /* FPU_UAE */ + +/* Return the address of the floating-point condition codes truth table */ +static inline uae_u8 * const FFPU address_of_fpcond_truth_table(void) + { return ((uae_u8*)&fpcond_truth_table[0][0]); } + +#endif /* FPU_X86_USE_NATIVE_FLAGS */ + +/* -------------------------------------------------------------------------- */ +/* --- Use Original M68K FPU Mappings --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_GENERIC_FLAGS + +#undef FPU_USE_NATIVE_FLAGS + +#define NATIVE_FFLAG_NEGATIVE 0x08000000 +#define NATIVE_FFLAG_ZERO 0x04000000 +#define NATIVE_FFLAG_INFINITY 0x02000000 +#define NATIVE_FFLAG_NAN 0x01000000 + +/* Initialization - NONE */ +PRIVATE inline void FFPU fpu_init_native_fflags(void) + { } + +/* Native to m68k floating-point condition codes - SELF */ +PRIVATE inline uae_u32 FFPU get_fpccr(void) + { return FPU fpsr.condition_codes; } + +/* M68k to native floating-point condition codes - SELF */ +PRIVATE inline void FFPU set_fpccr(uae_u32 new_fpcond) + { FPU fpsr.condition_codes = new_fpcond; } + +#endif /* FPU_USE_GENERIC_FLAGS */ + +/* -------------------------------------------------------------------------- */ +/* --- Use Lazy Flags Evaluation --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_LAZY_FLAGS + +#undef FPU_USE_NATIVE_FLAGS + +#define NATIVE_FFLAG_NEGATIVE 0x08000000 +#define NATIVE_FFLAG_ZERO 0x04000000 +#define NATIVE_FFLAG_INFINITY 0x02000000 +#define NATIVE_FFLAG_NAN 0x01000000 + +/* Initialization - NONE */ +PRIVATE inline void FFPU fpu_init_native_fflags(void) + { } + +/* Native to m68k floating-point condition codes - SELF */ +PRIVATE inline uae_u32 FFPU get_fpccr(void) +{ + uae_u32 fpccr = 0; + if (isnan(FPU result)) + fpccr |= FPSR_CCB_NAN; + else if (isinf(FPU result)) + fpccr |= FPSR_CCB_INFINITY; + else if (iszero(FPU result)) + fpccr |= FPSR_CCB_ZERO; + if (isneg(FPU result)) + fpccr |= FPSR_CCB_NEGATIVE; + return fpccr; +} + +/* M68k to native floating-point condition codes - SELF */ +PRIVATE inline void FFPU set_fpccr(uae_u32 new_fpcond) +{ + bool negative = (new_fpcond & FPSR_CCB_NEGATIVE) != 0; + if (new_fpcond & FPSR_CCB_NAN) + make_nan(FPU result, negative); + else if (new_fpcond & FPSR_CCB_INFINITY) + make_inf(FPU result, negative); + else if (new_fpcond & FPSR_CCB_ZERO) + make_zero(FPU result, negative); + else + FPU result = negative ? -1.0 : +1.0; +} + +/* Make FPSR according to the value passed in argument */ +PRIVATE inline void FFPU make_fpsr(fpu_register const & r) + { FPU result = r; } + +#endif /* FPU_USE_LAZY_FLAGS */ + +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Common methods --- */ +/* -------------------------------------------------------------------------- */ + +/* Return the address of the floating-point condition codes register */ +static inline uae_u32 * FFPU address_of_fpccr(void) + { return ((uae_u32 *)& FPU fpsr.condition_codes); } + +#endif /* FPU_FLAGS_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu.h b/BasiliskII/src/uae_cpu_2021/fpu/fpu.h new file mode 100644 index 000000000..d1fe6dd25 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu.h @@ -0,0 +1,59 @@ +/* + * fpu/fpu.h - public header + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_PUBLIC_HEADER_H +#define FPU_PUBLIC_HEADER_H + +#ifndef FPU_DEBUG +#define FPU_DEBUG 0 +#endif + +#if FPU_DEBUG +#define fpu_debug(args) printf args; +#define FPU_DUMP_REGISTERS 0 +#define FPU_DUMP_FIRST_BYTES 0 +#else +#define fpu_debug(args) ; +#undef FPU_DUMP_REGISTERS +#undef FPU_DUMP_FIRST_BYTES +#endif + +#include "sysdeps.h" +#include "fpu/types.h" +#include "fpu/core.h" + +void fpu_set_fpsr(uae_u32 new_fpsr); +uae_u32 fpu_get_fpsr(void); +void fpu_set_fpcr(uae_u32 new_fpcr); +uae_u32 fpu_get_fpcr(void); + +#endif /* FPU_PUBLIC_HEADER_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_ieee.cpp b/BasiliskII/src/uae_cpu_2021/fpu/fpu_ieee.cpp new file mode 100644 index 000000000..e70f76791 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_ieee.cpp @@ -0,0 +1,2478 @@ +/* + * fpu_ieee.cpp - the IEEE FPU + * + * Copyright (c) 2001-2008 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * UAE - The Un*x Amiga Emulator + * + * MC68881/MC68040 emulation + * + * Copyright 1996 Herman ten Brugge + * + * + * Following fixes by Lauri Pesonen, July 1999: + * + * FMOVEM list handling: + * The lookup tables did not work correctly, rewritten. + * FINT: + * (int) cast does not work, fixed. + * Further, now honors the FPU fpcr rounding modes. + * FINTRZ: + * (int) cast cannot be used, fixed. + * FGETEXP: + * Input argument value 0 returned erroneous value. + * FMOD: + * (int) cast cannot be used. Replaced by proper rounding. + * Quotient byte handling was missing. + * FREM: + * (int) cast cannot be used. Replaced by proper rounding. + * Quotient byte handling was missing. + * FSCALE: + * Input argument value 0 was not handled correctly. + * FMOVEM Control Registers to/from address FPU registers An: + * A bug caused the code never been called. + * FMOVEM Control Registers pre-decrement: + * Moving of control regs from memory to FPP was not handled properly, + * if not all of the three FPU registers were moved. + * Condition code "Not Greater Than or Equal": + * Returned erroneous value. + * FSINCOS: + * Cosine must be loaded first if same register. + * FMOVECR: + * Status register was not updated (yes, this affects it). + * FMOVE -> reg: + * Status register was not updated (yes, this affects it). + * FMOVE reg -> reg: + * Status register was not updated. + * FDBcc: + * The loop termination condition was wrong. + * Possible leak from int16 to int32 fixed. + * get_fp_value: + * Immediate addressing mode && Operation Length == Byte -> + * Use the low-order byte of the extension word. + * Now FPU fpcr high 16 bits are always read as zeroes, no matter what was + * written to them. + * + * Other: + * - Optimized single/double/extended to/from conversion functions. + * Huge speed boost, but not (necessarily) portable to other systems. + * Enabled/disabled by #define FPU_HAVE_IEEE_DOUBLE 1 + * - Optimized versions of FSCALE, FGETEXP, FGETMAN + * - Conversion routines now handle NaN and infinity better. + * - Some constants precalculated. Not all compilers can optimize the + * expressions previously used. + * + * TODO: + * - Floating point exceptions. + * - More Infinity/NaN/overflow/underflow checking. + * - FPU instruction_address (only needed when exceptions are implemented) + * - Should be written in assembly to support long doubles. + * - Precision rounding single/double + */ + +#include "sysdeps.h" + +#ifdef FPU_IEEE + +#include +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#include "main.h" +#define FPU_IMPLEMENTATION +#include "fpu/fpu.h" +#include "fpu/fpu_ieee.h" + +/* Global FPU context */ +fpu_t fpu; + +/* -------------------------------------------------------------------------- */ +/* --- Scopes Definition --- */ +/* -------------------------------------------------------------------------- */ + +#undef PUBLIC +#define PUBLIC /**/ + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* -------------------------------------------------------------------------- */ +/* --- Native Support --- */ +/* -------------------------------------------------------------------------- */ + +#include "fpu/mathlib.h" +#include "fpu/flags.h" +#include "fpu/exceptions.h" +#include "fpu/rounding.h" +#include "fpu/impl.h" + +#include "fpu/mathlib.cpp" +#include "fpu/flags.cpp" +#include "fpu/exceptions.cpp" +#include "fpu/rounding.cpp" + +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) +#define LD(x) x ## L +#ifdef HAVE_POWL +#define POWL(x, y) powl(x, y) +#else +#define POWL(x, y) pow(x, y) +#endif +#ifdef HAVE_LOG10L +#define LOG10L(x) log10l(x) +#else +#define LOG10L(x) log10(x) +#endif +#else +#define LD(x) x +#define POWL(x, y) pow(x, y) +#define LOG10L(x) log10(x) +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Debugging --- */ +/* -------------------------------------------------------------------------- */ + +PUBLIC void FFPU fpu_dump_registers(void) +{ + for (int i = 0; i < 8; i++){ + printf ("FP%d: %g ", i, fpu_get_register(i)); + if ((i & 3) == 3) + printf ("\n"); + } +} + +PUBLIC void FFPU fpu_dump_flags(void) +{ + printf ("N=%d Z=%d I=%d NAN=%d\n", + (get_fpsr() & FPSR_CCB_NEGATIVE) != 0, + (get_fpsr() & FPSR_CCB_ZERO)!= 0, + (get_fpsr() & FPSR_CCB_INFINITY) != 0, + (get_fpsr() & FPSR_CCB_NAN) != 0); +} + +#if FPU_DEBUG && FPU_DUMP_REGISTERS +PRIVATE void FFPU dump_registers(const char * str) +{ + char temp_str[512]; + + sprintf(temp_str, "%s: %.04f, %.04f, %.04f, %.04f, %.04f, %.04f, %.04f, %.04f\n", + str, + fpu_get_register(0), fpu_get_register(1), fpu_get_register(2), + fpu_get_register(3), fpu_get_register(4), fpu_get_register(5), + fpu_get_register(6), fpu_get_register(7) ); + + fpu_debug((temp_str)); +#else +PRIVATE void FFPU dump_registers(const char *) +{ +#endif +} + +#if FPU_DEBUG && FPU_DUMP_FIRST_BYTES +PRIVATE void FFPU dump_first_bytes(uae_u8 * buffer, uae_s32 actual) +{ + char temp_buf1[256], temp_buf2[10]; + int bytes = sizeof(temp_buf1)/3-1-3; + if (actual < bytes) + bytes = actual; + + temp_buf1[0] = 0; + for (int i = 0; i < bytes; i++) { + sprintf(temp_buf2, "%02x ", (uae_u32)buffer[i]); + strcat(temp_buf1, temp_buf2); + } + + strcat(temp_buf1, "\n"); + fpu_debug((temp_buf1)); +#else + PRIVATE void FFPU dump_first_bytes(uae_u8 *, uae_s32) +{ +#endif +} + +// Quotient Byte is loaded with the sign and least significant +// seven bits of the quotient. +PRIVATE inline void FFPU make_quotient(fpu_register const & quotient, uae_u32 sign) +{ + uae_u32 lsb = (uae_u32)fp_fabs(quotient) & 0x7f; + FPU fpsr.quotient = sign | (lsb << 16); +} + +// to_single +PRIVATE inline fpu_register FFPU make_single(uae_u32 value) +{ +#if 1 + // Use a single, otherwise some checks for NaN, Inf, Zero would have to + // be performed + fpu_single result = 0; + fp_declare_init_shape(srp, single); + srp.ieee.negative = (value >> 31) & 1; + srp.ieee.exponent = (value >> 23) & FP_SINGLE_EXP_MAX; + srp.ieee.mantissa = value & 0x007fffff; + result = srp.value; + fpu_debug(("make_single (%X) = %.04f\n",value,(double)result)); + return result; +#elif 0 /* Original code */ + if ((value & 0x7fffffff) == 0) + return (0.0); + + fpu_register result; + fpu_register_parts *p = (fpu_register_parts *)&result; + + uae_u32 sign = (value & 0x80000000); + uae_u32 exp = ((value & 0x7F800000) >> 23) + 1023 - 127; + + p->parts[FLO] = value << 29; + p->parts[FHI] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3); + + fpu_debug(("make_single (%X) = %.04f\n",value,(double)result)); + + return(result); +#endif +} + +// from_single +PRIVATE inline uae_u32 FFPU extract_single(fpu_register const & src) +{ +#if 1 + fpu_single input = (fpu_single) src; + fp_declare_init_shape(sip, single); + sip.value = input; + uae_u32 result = (sip.ieee.negative << 31) + | (sip.ieee.exponent << 23) + | sip.ieee.mantissa; + fpu_debug(("extract_single (%.04f) = %X\n",(double)src,result)); + return result; +#elif 0 /* Original code */ + if (src == 0.0) + return 0; + + uae_u32 result; + fpu_register_parts const *p = (fpu_register_parts const *)&src; + + uae_u32 sign = (p->parts[FHI] & 0x80000000); + uae_u32 exp = (p->parts[FHI] & 0x7FF00000) >> 20; + + if(exp + 127 < 1023) { + exp = 0; + } else if(exp > 1023 + 127) { + exp = 255; + } else { + exp = exp + 127 - 1023; + } + + result = sign | (exp << 23) | ((p->parts[FHI] & 0x000FFFFF) << 3) | (p->parts[FLO] >> 29); + + fpu_debug(("extract_single (%.04f) = %X\n",(double)src,result)); + + return (result); +#endif +} + +// to_exten +PRIVATE inline fpu_register FFPU make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +{ + // is it zero? + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) + return (wrd1 & 0x80000000) ? -0.0 : 0.0; + + fpu_register result; +#if defined(USE_QUAD_DOUBLE) + // is it NaN? + if ((wrd1 & 0x7fff0000) == 0x7fff0000 && ((wrd2 & 0x7fffffff) != 0 || wrd3 != 0)) { + make_nan(result, (wrd1 & 0x80000000) != 0); + return result; + } + // is it inf? + if ((wrd1 & 0x7ffff000) == 0x7fff0000 && (wrd2 & 0x7fffffff) == 0 && wrd3 == 0) { + make_inf(result, (wrd1 & 0x80000000) != 0); + return result; + } + fp_declare_init_shape(srp, extended); + srp.ieee.negative = (wrd1 >> 31) & 1; + srp.ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; + srp.ieee.mantissa0 = (wrd2 >> 16) & 0xffff; + srp.ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff); + srp.ieee.mantissa2 = (wrd3 & 0xffff) << 16; + srp.ieee.mantissa3 = 0; +#elif defined(USE_LONG_DOUBLE) + fp_declare_init_shape(srp, extended); + srp.ieee.negative = (wrd1 >> 31) & 1; + srp.ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; + srp.ieee.mantissa0 = wrd2; + srp.ieee.mantissa1 = wrd3; + +#else + uae_u32 sgn = (wrd1 >> 31) & 1; + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + + // the explicit integer bit is not set, must normalize + if ((wrd2 & 0x80000000) == 0) { + fpu_debug(("make_extended denormalized mantissa (%X,%X,%X)\n",wrd1,wrd2,wrd3)); + if (wrd2 | wrd3) { + // mantissa, not fraction. + uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; + while (exp > 0 && (man & UVAL64(0x8000000000000000)) == 0) { + man <<= 1; + exp--; + } + wrd2 = (uae_u32)(man >> 32); + wrd3 = (uae_u32)(man & 0xFFFFFFFF); + } + else if (exp != 0x7fff) // zero + exp = FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS; + } + + if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) + exp = 0; + else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) + exp = FP_DOUBLE_EXP_MAX; + else + exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; + + fp_declare_init_shape(srp, double); + srp.ieee.negative = sgn; + srp.ieee.exponent = exp; + // drop the explicit integer bit + srp.ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11; + srp.ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11); +#endif + result = srp.value; + fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); + return result; +} + +/* + Would be so much easier with full size floats :( + ... this is so vague. +*/ +// make_extended_no_normalize +PRIVATE inline void FFPU make_extended_no_normalize( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result +) +{ + // is it zero? + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) { + make_zero(result, (wrd1 & 0x80000000) != 0); + return; + } + // is it NaN? + if ((wrd1 & 0x7fff0000) == 0x7fff0000 && ((wrd2 & 0x7fffffff) != 0 || wrd3 != 0)) { + make_nan(result, (wrd1 & 0x80000000) != 0); + return; + } +#if defined(USE_QUAD_DOUBLE) + // is it inf? + if ((wrd1 & 0x7ffff000) == 0x7fff0000 && (wrd2 & 0x7fffffff) == 0 && wrd3 == 0) { + make_inf(result, (wrd1 & 0x80000000) != 0); + return; + } + fp_declare_init_shape(srp, extended); + srp.ieee.negative = (wrd1 >> 31) & 1; + srp.ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; + srp.ieee.mantissa0 = (wrd2 >> 16) & 0xffff; + srp.ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff); + srp.ieee.mantissa2 = (wrd3 & 0xffff) << 16; + srp.ieee.mantissa3 = 0; +#elif defined(USE_LONG_DOUBLE) + fp_declare_init_shape(srp, extended); + srp.ieee.negative = (wrd1 >> 31) & 1; + srp.ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; + srp.ieee.mantissa0 = wrd2; + srp.ieee.mantissa1 = wrd3; +#else + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) + exp = 0; + else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) + exp = FP_DOUBLE_EXP_MAX; + else + exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; + + fp_declare_init_shape(srp, double); + srp.ieee.negative = (wrd1 >> 31) & 1; + srp.ieee.exponent = exp; + // drop the explicit integer bit + srp.ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11; + srp.ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11); +#endif + result = srp.value; + fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); +} + +// from_exten +PRIVATE inline void FFPU extract_extended(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +) +{ + if (src == 0.0) { + *wrd1 = *wrd2 = *wrd3 = 0; + return; + } +#if defined(USE_QUAD_DOUBLE) + // FIXME: deal with denormals? + fp_declare_init_shape(srp, extended); + srp.value = src; + *wrd1 = (srp.ieee.negative << 31) | (srp.ieee.exponent << 16); + // always set the explicit integer bit. + *wrd2 = 0x80000000 | (srp.ieee.mantissa0 << 15) | ((srp.ieee.mantissa1 & 0xfffe0000) >> 17); + *wrd3 = (srp.ieee.mantissa1 << 15) | ((srp.ieee.mantissa2 & 0xfffe0000) >> 17); +#elif defined(USE_LONG_DOUBLE) + fpu_register_parts p = { src }; +#ifdef WORDS_BIGENDIAN + *wrd1 = p.parts[0]; + *wrd2 = p.parts[1]; + *wrd3 = p.parts[2]; +#else + *wrd3 = p.parts[0]; + *wrd2 = p.parts[1]; + *wrd1 = (p.parts[2] & 0xffff) << 16; +#endif +#else + fp_declare_init_shape(srp, double); + srp.value = src; + fpu_debug(("extract_extended (%d,%d,%X,%X)\n", + srp.ieee.negative , srp.ieee.exponent, + srp.ieee.mantissa0, srp.ieee.mantissa1)); + + uae_u32 exp = srp.ieee.exponent; + + if (exp == FP_DOUBLE_EXP_MAX) + exp = FP_EXTENDED_EXP_MAX; + else + exp += FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS; + + *wrd1 = (srp.ieee.negative << 31) | (exp << 16); + // always set the explicit integer bit. + *wrd2 = 0x80000000 | (srp.ieee.mantissa0 << 11) | ((srp.ieee.mantissa1 & 0xffe00000) >> 21); + *wrd3 = srp.ieee.mantissa1 << 11; +#endif + fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); +} + +// to_double +PRIVATE inline fpu_register FFPU make_double(uae_u32 wrd1, uae_u32 wrd2) +{ + union { + fpu_double value; + uae_u32 parts[2]; + } dest; +#ifdef WORDS_BIGENDIAN + dest.parts[0] = wrd1; + dest.parts[1] = wrd2; +#else + dest.parts[0] = wrd2; + dest.parts[1] = wrd1; +#endif + fpu_debug(("make_double (%X,%X) = %.04f\n",wrd1,wrd2,dest.value)); + return (fpu_register)(dest.value); +} + +// from_double +PRIVATE inline void FFPU extract_double(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2 +) +{ + union { + fpu_double value; + uae_u32 parts[2]; + } dest; +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fpu_register_parts p = { src }; + // always set the explicit integer bit. + p.parts[1] |= 0x80000000; + dest.value = (fpu_double)p.val; +#else + dest.value = (fpu_double)src; +#endif +#ifdef WORDS_BIGENDIAN + *wrd1 = dest.parts[0]; + *wrd2 = dest.parts[1]; +#else + *wrd2 = dest.parts[0]; + *wrd1 = dest.parts[1]; +#endif + fpu_debug(("extract_double (%.04f) = %X,%X\n",(double)src,*wrd1,*wrd2)); +} + +// to_pack +PRIVATE inline fpu_register FFPU make_packed(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +{ + fpu_register d; + bool sm = (wrd1 & 0x80000000) != 0; + bool se = (wrd1 & 0x40000000) != 0; + int exp = (wrd1 & 0x7fff0000) >> 16; + unsigned int dig; + fpu_register pwr; + + if (exp == 0x7fff) + { + if ((wrd2 & 0x7fffffff) == 0 && wrd3 == 0) + { + make_inf(d, sm); + } else + { + make_nan(d, sm); + } + return d; + } + dig = wrd1 & 0x0000000f; + if (dig == 0 && wrd2 == 0 && wrd3 == 0) + { + make_zero(d, sm); + return d; + } + + /* + * Convert the bcd exponent to binary by successive adds and + * muls. Set the sign according to SE. Subtract 16 to compensate + * for the mantissa which is to be interpreted as 17 integer + * digits, rather than 1 integer and 16 fraction digits. + * Note: this operation can never overflow. + */ + exp = ((wrd1 >> 24) & 0xf); + exp = exp * 10 + ((wrd1 >> 20) & 0xf); + exp = exp * 10 + ((wrd1 >> 16) & 0xf); + if (se) + exp = -exp; + /* sub to compensate for shift of mant */ + exp = exp - 16; + + /* + * Convert the bcd mantissa to binary by successive + * adds and muls. Set the sign according to SM. + * The mantissa digits will be converted with the decimal point + * assumed following the least-significant digit. + * Note: this operation can never overflow. + */ + d = wrd1 & 0xf; + d = (d * LD(10.0)) + ((wrd2 >> 28) & 0xf); + d = (d * LD(10.0)) + ((wrd2 >> 24) & 0xf); + d = (d * LD(10.0)) + ((wrd2 >> 20) & 0xf); + d = (d * LD(10.0)) + ((wrd2 >> 16) & 0xf); + d = (d * LD(10.0)) + ((wrd2 >> 12) & 0xf); + d = (d * LD(10.0)) + ((wrd2 >> 8) & 0xf); + d = (d * LD(10.0)) + ((wrd2 >> 4) & 0xf); + d = (d * LD(10.0)) + ((wrd2 ) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 28) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 24) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 20) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 16) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 12) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 8) & 0xf); + d = (d * LD(10.0)) + ((wrd3 >> 4) & 0xf); + d = (d * LD(10.0)) + ((wrd3 ) & 0xf); + + /* Check the sign of the mant and make the value in fp0 the same sign. */ + if (sm) + d = -d; + + /* + * Calculate power-of-ten factor from exponent. + */ + if (exp < 0) + { + exp = -exp; + pwr = POWL(LD(10.0), exp); + d = d / pwr; + } else + { + pwr = POWL(LD(10.0), exp); + d = d * pwr; + } + + fpu_debug(("make_packed(%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)d)); + return d; +} + +// from_pack +PRIVATE inline void FFPU extract_packed(fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) +{ + fpu_register pwr; + int exp; + fpu_register d; + bool sm, se; + int dig; + + *wrd1 = *wrd2 = *wrd3 = 0; + + d = src; + sm = false; + if (isneg(src)) + { + d = -d; + sm = true; + } + + if (isnan(src)) + { + *wrd1 = sm ? 0xffff0000 : 0x7fff0000; + *wrd2 = 0xffffffff; + *wrd3 = 0xffffffff; + return; + } + if (isinf(src)) + { + *wrd1 = sm ? 0xffff0000 : 0x7fff0000; + *wrd2 = *wrd3 = 0; + return; + } + if (iszero(src)) + { + *wrd1 = sm ? 0x80000000 : 0x00000000; + *wrd2 = *wrd3 = 0; + return; + } + sm = false; + if (isneg(src)) + { + d = -d; + sm = true; + } + exp = (int)floor(LOG10L(d)); + se = false; + if (exp < 0) + { + exp = -exp; + se = true; + pwr = POWL(LD(10.0), exp); + d = d * pwr; + } else + { + pwr = POWL(LD(10.0), exp); + d = d / pwr; + } + dig = (int)d; d = LD(10) * (d - dig); *wrd1 |= dig; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 28; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 24; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 20; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 16; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 12; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 8; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig << 4; + dig = (int)d; d = LD(10) * (d - dig); *wrd2 |= dig; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 28; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 24; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 20; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 16; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 12; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 8; + dig = (int)d; d = LD(10) * (d - dig); *wrd3 |= dig << 4; + dig = (int)d; *wrd3 |= dig; + + dig = (exp / 100) % 10; + *wrd1 |= dig << 24; + dig = (exp / 10) % 10; + *wrd1 |= dig << 20; + dig = (exp) % 10; + *wrd1 |= dig << 16; + if (sm) + *wrd1 |= 0x80000000; + if (se) + *wrd1 |= 0x40000000; + fpu_debug(("extract_packed(%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); +} + +PRIVATE inline int FFPU get_fp_value (uae_u32 opcode, uae_u16 extra, fpu_register & src) +{ + uaecptr tmppc; + uae_u16 tmp; + int size; + int mode; + int reg; + uae_u32 ad = 0; + static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + // fpu_debug(("get_fp_value(%X,%X)\n",(int)opcode,(int)extra)); + // dump_first_bytes( regs.pc_p-4, 16 ); + + if ((extra & 0x4000) == 0) { + src = FPU registers[(extra >> 10) & 7]; + return 1; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + + fpu_debug(("get_fp_value mode=%d, reg=%d, size=%d\n",(int)mode,(int)reg,(int)size)); + + switch (mode) { + case 0: + switch (size) { + case 6: + src = (fpu_register) (uae_s8) m68k_dreg (regs, reg); + break; + case 4: + src = (fpu_register) (uae_s16) m68k_dreg (regs, reg); + break; + case 0: + src = (fpu_register) (uae_s32) m68k_dreg (regs, reg); + break; + case 1: + src = make_single(m68k_dreg (regs, reg)); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + break; + case 4: + ad = m68k_areg (regs, reg) - (reg == 7 ? sz2[size] : sz1[size]); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; + case 2: + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + fpu_debug(("get_fp_value next_iword()=%X\n",ad-m68k_getpc()-2)); + break; + case 3: + tmppc = m68k_getpc (); + tmp = (uae_u16)next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + break; + case 4: + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + // Immediate addressing mode && Operation Length == Byte -> + // Use the low-order byte of the extension word. + if(size == 6) ad++; + break; + default: + return 0; + } + } + + fpu_debug(("get_fp_value m68k_getpc()=%X\n",m68k_getpc())); + fpu_debug(("get_fp_value ad=%X\n",ad)); + fpu_debug(("get_fp_value get_long (ad)=%X\n",get_long (ad))); + //dump_first_bytes( get_real_address(ad, 0, 0)-64, 64 ); + //dump_first_bytes( get_real_address(ad, 0, 0), 64 ); + + switch (size) { + case 0: + src = (fpu_register) (uae_s32) get_long (ad); + break; + case 1: + src = make_single(get_long (ad)); + break; + case 2: { + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + src = make_extended(wrd1, wrd2, wrd3); + break; + } + case 3: { + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + src = make_packed(wrd1, wrd2, wrd3); + break; + } + case 4: + src = (fpu_register) (uae_s16) get_word(ad); + break; + case 5: { + uae_u32 wrd1, wrd2; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + src = make_double(wrd1, wrd2); + break; + } + case 6: + src = (fpu_register) (uae_s8) get_byte(ad); + break; + default: + return 0; + } + + switch (mode) { + case 3: + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + break; + } + + // fpu_debug(("get_fp_value result = %.04f\n",(float)src)); + return 1; +} + +/* Convert the FP value to integer according to the current m68k rounding mode */ +PRIVATE inline fpu_register FFPU fp_doround(fpu_register const & src) +{ + fpu_register result; + switch (get_fpcr() & FPCR_ROUNDING_MODE) { + case FPCR_ROUND_ZERO: + result = fp_round_to_zero(src); + break; + case FPCR_ROUND_MINF: + result = fp_round_to_minus_infinity(src); + break; + case FPCR_ROUND_NEAR: + result = fp_round_to_nearest(src); + break; + case FPCR_ROUND_PINF: + result = fp_round_to_plus_infinity(src); + break; + default: + result = src; /* should never be reached */ + break; + } + return result; +} + +PRIVATE inline uae_s32 FFPU toint(fpu_register const & src) +{ + return (uae_s32)fp_doround(src); +} + +PRIVATE inline int FFPU put_fp_value (uae_u32 opcode, uae_u16 extra, fpu_register const & value) +{ + uae_u16 tmp; + uaecptr tmppc; + int size; + int mode; + int reg; + uae_u32 ad; + static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + // fpu_debug(("put_fp_value(%.04f,%X,%X)\n",(float)value,(int)opcode,(int)extra)); + + if ((extra & 0x4000) == 0) { + int dest_reg = (extra >> 10) & 7; + FPU registers[dest_reg] = value; + make_fpsr(FPU registers[dest_reg]); + return 1; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + ad = 0xffffffff; + switch (mode) { + case 0: + switch (size) { + case 6: + m68k_dreg (regs, reg) = ((toint(value) & 0xff) + | (m68k_dreg (regs, reg) & ~0xff)); + break; + case 4: + m68k_dreg (regs, reg) = ((toint(value) & 0xffff) + | (m68k_dreg (regs, reg) & ~0xffff)); + break; + case 0: + m68k_dreg (regs, reg) = toint(value); + break; + case 1: + m68k_dreg (regs, reg) = extract_single(value); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + ad = m68k_areg (regs, reg); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; + case 2: + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: + tmppc = m68k_getpc (); + tmp = (uae_u16)next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + break; + case 4: + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + break; + default: + return 0; + } + } + switch (size) { + case 0: + put_long (ad, toint(value)); + break; + case 1: + put_long (ad, extract_single(value)); + break; + case 2: + { + uae_u32 wrd1, wrd2, wrd3; + extract_extended(value, &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + } + break; + case 3: + { + uae_u32 wrd1, wrd2, wrd3; + extract_packed(value, &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + } + break; + case 4: + put_word(ad, (uae_s16) toint(value)); + break; + case 5: + { + uae_u32 wrd1, wrd2; + extract_double(value, &wrd1, &wrd2); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + } + break; + case 6: + put_byte(ad, (uae_s8) toint(value)); + break; + default: + return 0; + } + return 1; +} + +PRIVATE inline int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) +{ + uae_u16 tmp; + uaecptr tmppc; + int mode; + int reg; + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + switch (mode) { + case 0: + case 1: + return 0; + case 2: + *ad = m68k_areg (regs, reg); + break; + case 3: + *ad = m68k_areg (regs, reg); + break; + case 4: + *ad = m68k_areg (regs, reg); + break; + case 5: + *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + *ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + *ad = next_ilong(); + break; + case 2: + *ad = m68k_getpc (); + *ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: + tmppc = m68k_getpc (); + tmp = (uae_u16)next_iword(); + *ad = get_disp_ea_020 (tmppc, tmp); + break; + default: + return 0; + } + } + return 1; +} + +#if FPU_DEBUG +# define CONDRET(s,x) fpu_debug(("fpp_cond %s = %d\n",s,(uint32)(x))); return (x) +#else +# define CONDRET(s,x) return (x) +#endif + +PRIVATE inline int FFPU fpp_cond(int condition) +{ + int N = (FPU result < 0.0); + int Z = (FPU result == 0.0); + int NaN = isnan(FPU result); + + if (NaN) + N = Z = 0; + + switch (condition & 0x1f) { + case 0x00: CONDRET("False",0); + case 0x01: CONDRET("Equal",Z); + case 0x02: CONDRET("Ordered Greater Than",!(NaN || Z || N)); + case 0x03: CONDRET("Ordered Greater Than or Equal",Z || !(NaN || N)); + case 0x04: CONDRET("Ordered Less Than",N && !(NaN || Z)); + case 0x05: CONDRET("Ordered Less Than or Equal",Z || (N && !NaN)); + case 0x06: CONDRET("Ordered Greater or Less Than",!(NaN || Z)); + case 0x07: CONDRET("Ordered",!NaN); + case 0x08: CONDRET("Unordered",NaN); + case 0x09: CONDRET("Unordered or Equal",NaN || Z); + case 0x0a: CONDRET("Unordered or Greater Than",NaN || !(N || Z)); + case 0x0b: CONDRET("Unordered or Greater or Equal",NaN || Z || !N); + case 0x0c: CONDRET("Unordered or Less Than",NaN || (N && !Z)); + case 0x0d: CONDRET("Unordered or Less or Equal",NaN || Z || N); + case 0x0e: CONDRET("Not Equal",!Z); + case 0x0f: CONDRET("True",1); + case 0x10: CONDRET("Signaling False",0); + case 0x11: CONDRET("Signaling Equal",Z); + case 0x12: CONDRET("Greater Than",!(NaN || Z || N)); + case 0x13: CONDRET("Greater Than or Equal",Z || !(NaN || N)); + case 0x14: CONDRET("Less Than",N && !(NaN || Z)); + case 0x15: CONDRET("Less Than or Equal",Z || (N && !NaN)); + case 0x16: CONDRET("Greater or Less Than",!(NaN || Z)); + case 0x17: CONDRET("Greater, Less or Equal",!NaN); + case 0x18: CONDRET("Not Greater, Less or Equal",NaN); + case 0x19: CONDRET("Not Greater or Less Than",NaN || Z); + case 0x1a: CONDRET("Not Less Than or Equal",NaN || !(N || Z)); + case 0x1b: CONDRET("Not Less Than",NaN || Z || !N); + case 0x1c: CONDRET("Not Greater Than or Equal", NaN || (N && !Z)); + case 0x1d: CONDRET("Not Greater Than",NaN || Z || N); + case 0x1e: CONDRET("Signaling Not Equal",!Z); + case 0x1f: CONDRET("Signaling True",1); + default: CONDRET("",-1); + } +} + +void FFPU fpuop_dbcc(uae_u32 opcode, uae_u32 extra) +{ + fpu_debug(("fdbcc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + uaecptr pc = (uae_u32) m68k_getpc (); + uae_s32 disp = (uae_s32) (uae_s16) next_iword(); + int cc = fpp_cond(extra & 0x3f); + if (cc == -1) { + m68k_setpc (pc - 4); + op_illg (opcode); + } else if (!cc) { + int reg = opcode & 0x7; + + // this may have leaked. + /* + m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff) + | ((m68k_dreg (regs, reg) - 1) & 0xffff)); + */ + m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & 0xffff0000) + | (((m68k_dreg (regs, reg) & 0xffff) - 1) & 0xffff)); + + + // condition reversed. + // if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff) + if ((m68k_dreg (regs, reg) & 0xffff) != 0xffff) + m68k_setpc (pc + disp); + } +} + +void FFPU fpuop_scc(uae_u32 opcode, uae_u32 extra) +{ + fpu_debug(("fscc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + uae_u32 ad = 0; + int cc = fpp_cond(extra & 0x3f); + if (cc == -1) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + else if ((opcode & 0x38) == 0) { + m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | + (cc ? 0xff : 0x00); + } + else if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + else + put_byte(ad, cc ? 0xff : 0x00); +} + +void FFPU fpuop_trapcc(uae_u32 opcode, uaecptr oldpc, uae_u32 extra) +{ + fpu_debug(("ftrapcc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + int cc = fpp_cond(extra & 0x3f); + if (cc == -1) { + m68k_setpc (oldpc); + op_illg (opcode); + } + if (cc) + Exception(7, oldpc - 2); +} + +// NOTE that we get here also when there is a FNOP (nontrapping false, displ 0) +void FFPU fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) +{ + fpu_debug(("fbcc_opp %X, %X at %08lx, jumpto=%X\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra )); + + int cc = fpp_cond(opcode & 0x3f); + if (cc == -1) { + m68k_setpc (pc); + op_illg (opcode); + } + else if (cc) { + if ((opcode & 0x40) == 0) + extra = (uae_s32) (uae_s16) extra; + m68k_setpc (pc + extra); + } +} + +// FSAVE has no post-increment +// 0x1f180000 == IDLE state frame, coprocessor version number 1F +void FFPU fpuop_save(uae_u32 opcode) +{ + fpu_debug(("fsave_opp at %08lx\n", m68k_getpc ())); + + uae_u32 ad = 0; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + int i; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + + if (CPUType == 4) { + // Put 4 byte 68040 IDLE frame. + if (incr < 0) { + ad -= 4; + put_long (ad, 0x41000000); + } + else { + put_long (ad, 0x41000000); + ad += 4; + } + } else { + // Put 28 byte 68881 IDLE frame. + if (incr < 0) { + fpu_debug(("fsave_opp pre-decrement\n")); + ad -= 4; + // What's this? Some BIU flags, or (incorrectly placed) command/condition? + put_long (ad, 0x70000000); + for (i = 0; i < 5; i++) { + ad -= 4; + put_long (ad, 0x00000000); + } + ad -= 4; + put_long (ad, 0x1f180000); // IDLE, vers 1f + } + else { + put_long (ad, 0x1f180000); // IDLE, vers 1f + ad += 4; + for (i = 0; i < 5; i++) { + put_long (ad, 0x00000000); + ad += 4; + } + // What's this? Some BIU flags, or (incorrectly placed) command/condition? + put_long (ad, 0x70000000); + ad += 4; + } + } + if ((opcode & 0x38) == 0x18) { + m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 + fpu_debug(("PROBLEM: fsave_opp post-increment\n")); + } + if ((opcode & 0x38) == 0x20) { + m68k_areg (regs, opcode & 7) = ad; + fpu_debug(("fsave_opp pre-decrement %X -> A%d\n",ad,opcode & 7)); + } +} + +// FRESTORE has no pre-decrement +void FFPU fpuop_restore(uae_u32 opcode) +{ + fpu_debug(("frestore_opp at %08lx\n", m68k_getpc ())); + + uae_u32 ad = 0; + uae_u32 d; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + + if (CPUType == 4) { + // 68040 + if (incr < 0) { + fpu_debug(("PROBLEM: frestore_opp incr < 0\n")); + // this may be wrong, but it's never called. + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) != 0) { // Not a NULL frame? + if ((d & 0x00ff0000) == 0) { // IDLE + fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); + } + else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP + fpu_debug(("PROBLEM: frestore_opp found UNIMP frame at %X\n",ad-4)); + ad -= 44; + } + else if ((d & 0x00ff0000) == 0x00600000) { // BUSY + fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); + ad -= 92; + } + } + } + else { + d = get_long (ad); + fpu_debug(("frestore_opp frame at %X = %X\n",ad,d)); + ad += 4; + if ((d & 0xff000000) != 0) { // Not a NULL frame? + if ((d & 0x00ff0000) == 0) { // IDLE + fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); + } + else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP + fpu_debug(("PROBLEM: frestore_opp found UNIMP frame at %X\n",ad-4)); + ad += 44; + } + else if ((d & 0x00ff0000) == 0x00600000) { // BUSY + fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); + ad += 92; + } + } + } + } + else { + // 68881 + if (incr < 0) { + fpu_debug(("PROBLEM: frestore_opp incr < 0\n")); + // this may be wrong, but it's never called. + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) != 0) { + if ((d & 0x00ff0000) == 0x00180000) + ad -= 6 * 4; + else if ((d & 0x00ff0000) == 0x00380000) + ad -= 14 * 4; + else if ((d & 0x00ff0000) == 0x00b40000) + ad -= 45 * 4; + } + } + else { + d = get_long (ad); + fpu_debug(("frestore_opp frame at %X = %X\n",ad,d)); + ad += 4; + if ((d & 0xff000000) != 0) { // Not a NULL frame? + if ((d & 0x00ff0000) == 0x00180000) { // IDLE + fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); + ad += 6 * 4; + } + else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C? + ad += 14 * 4; + fpu_debug(("PROBLEM: frestore_opp found UNIMP? frame at %X\n",ad-4)); + } + else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY + fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); + ad += 45 * 4; + } + } + } + } + if ((opcode & 0x38) == 0x18) { + m68k_areg (regs, opcode & 7) = ad; + fpu_debug(("frestore_opp post-increment %X -> A%d\n",ad,opcode & 7)); + } + if ((opcode & 0x38) == 0x20) { + m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 + fpu_debug(("PROBLEM: frestore_opp pre-decrement\n")); + } +} + +void FFPU fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) +{ + int reg; + fpu_register src; + + fpu_debug(("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff, + m68k_getpc () - 4)); + + dump_registers( "START"); + + switch ((extra >> 13) & 0x7) { + case 3: + fpu_debug(("FMOVE -> \n")); + if (put_fp_value (opcode, extra, FPU registers[(extra >> 7) & 7]) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + dump_registers( "END "); + return; + case 4: + case 5: + if ((opcode & 0x38) == 0) { + if (extra & 0x2000) { // dr bit + if (extra & 0x1000) { + m68k_dreg (regs, opcode & 7) = get_fpcr(); + fpu_debug(("FMOVEM FPU fpcr (%X) -> D%d\n", get_fpcr(), opcode & 7)); + } + if (extra & 0x0800) { + m68k_dreg (regs, opcode & 7) = get_fpsr(); + fpu_debug(("FMOVEM FPU fpsr (%X) -> D%d\n", get_fpsr(), opcode & 7)); + } + if (extra & 0x0400) { + m68k_dreg (regs, opcode & 7) = FPU instruction_address; + fpu_debug(("FMOVEM FPU instruction_address (%X) -> D%d\n", FPU instruction_address, opcode & 7)); + } + } + else { + if (extra & 0x1000) { + set_fpcr( m68k_dreg (regs, opcode & 7) ); + fpu_debug(("FMOVEM D%d (%X) -> FPU fpcr\n", opcode & 7, get_fpcr())); + } + if (extra & 0x0800) { + set_fpsr( m68k_dreg (regs, opcode & 7) ); + fpu_debug(("FMOVEM D%d (%X) -> FPU fpsr\n", opcode & 7, get_fpsr())); + } + if (extra & 0x0400) { + FPU instruction_address = m68k_dreg (regs, opcode & 7); + fpu_debug(("FMOVEM D%d (%X) -> FPU instruction_address\n", opcode & 7, FPU instruction_address)); + } + } + } + else if ((opcode & 0x38) == 8) { + if (extra & 0x2000) { // dr bit + if (extra & 0x1000) { + m68k_areg (regs, opcode & 7) = get_fpcr(); + fpu_debug(("FMOVEM FPU fpcr (%X) -> A%d\n", get_fpcr(), opcode & 7)); + } + if (extra & 0x0800) { + m68k_areg (regs, opcode & 7) = get_fpsr(); + fpu_debug(("FMOVEM FPU fpsr (%X) -> A%d\n", get_fpsr(), opcode & 7)); + } + if (extra & 0x0400) { + m68k_areg (regs, opcode & 7) = FPU instruction_address; + fpu_debug(("FMOVEM FPU instruction_address (%X) -> A%d\n", FPU instruction_address, opcode & 7)); + } + } else { + if (extra & 0x1000) { + set_fpcr( m68k_areg (regs, opcode & 7) ); + fpu_debug(("FMOVEM A%d (%X) -> FPU fpcr\n", opcode & 7, get_fpcr())); + } + if (extra & 0x0800) { + set_fpsr( m68k_areg (regs, opcode & 7) ); + fpu_debug(("FMOVEM A%d (%X) -> FPU fpsr\n", opcode & 7, get_fpsr())); + } + if (extra & 0x0400) { + FPU instruction_address = m68k_areg (regs, opcode & 7); + fpu_debug(("FMOVEM A%d (%X) -> FPU instruction_address\n", opcode & 7, FPU instruction_address)); + } + } + } + else if ((opcode & 0x3f) == 0x3c) { + if ((extra & 0x2000) == 0) { + if (extra & 0x1000) { + set_fpcr( next_ilong() ); + fpu_debug(("FMOVEM #<%X> -> FPU fpcr\n", get_fpcr())); + } + if (extra & 0x0800) { + set_fpsr( next_ilong() ); + fpu_debug(("FMOVEM #<%X> -> FPU fpsr\n", get_fpsr())); + } + if (extra & 0x0400) { + FPU instruction_address = next_ilong(); + fpu_debug(("FMOVEM #<%X> -> FPU instruction_address\n", FPU instruction_address)); + } + } + } + else if (extra & 0x2000) { + /* FMOVEM FPP->memory */ + uae_u32 ad = 0; + int incr = 0; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + if ((opcode & 0x38) == 0x20) { + if (extra & 0x1000) + incr += 4; + if (extra & 0x0800) + incr += 4; + if (extra & 0x0400) + incr += 4; + } + ad -= incr; + if (extra & 0x1000) { + put_long (ad, get_fpcr()); + fpu_debug(("FMOVEM FPU fpcr (%X) -> mem %X\n", get_fpcr(), ad )); + ad += 4; + } + if (extra & 0x0800) { + put_long (ad, get_fpsr()); + fpu_debug(("FMOVEM FPU fpsr (%X) -> mem %X\n", get_fpsr(), ad )); + ad += 4; + } + if (extra & 0x0400) { + put_long (ad, FPU instruction_address); + fpu_debug(("FMOVEM FPU instruction_address (%X) -> mem %X\n", FPU instruction_address, ad )); + ad += 4; + } + ad -= incr; + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? + m68k_areg (regs, opcode & 7) = ad; + } + else { + /* FMOVEM memory->FPP */ + uae_u32 ad = 0; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + + // ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad; + int incr = 0; + if((opcode & 0x38) == 0x20) { + if (extra & 0x1000) + incr += 4; + if (extra & 0x0800) + incr += 4; + if (extra & 0x0400) + incr += 4; + ad = ad - incr; + } + + if (extra & 0x1000) { + set_fpcr( get_long (ad) ); + fpu_debug(("FMOVEM mem %X (%X) -> FPU fpcr\n", ad, get_fpcr() )); + ad += 4; + } + if (extra & 0x0800) { + set_fpsr( get_long (ad) ); + fpu_debug(("FMOVEM mem %X (%X) -> FPU fpsr\n", ad, get_fpsr() )); + ad += 4; + } + if (extra & 0x0400) { + FPU instruction_address = get_long (ad); + fpu_debug(("FMOVEM mem %X (%X) -> FPU instruction_address\n", ad, FPU instruction_address )); + ad += 4; + } + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? +// m68k_areg (regs, opcode & 7) = ad - 12; + m68k_areg (regs, opcode & 7) = ad - incr; + } + dump_registers( "END "); + return; + case 6: + case 7: { + uae_u32 ad = 0, list = 0; + int incr = 0; + if (extra & 0x2000) { + /* FMOVEM FPP->memory */ + fpu_debug(("FMOVEM FPP->memory\n")); + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + list = extra & 0xff; + incr = -1; + break; + case 1: /* dynamic pred */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 3: /* dynamic postinc */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = 1; + break; + } + + if (incr < 0) { + for(reg=7; reg>=0; reg--) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + extract_extended(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + } + else { + for(reg=0; reg<8; reg++) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + extract_extended(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + } + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? + m68k_areg (regs, opcode & 7) = ad; + } + else { + /* FMOVEM memory->FPP */ + fpu_debug(("FMOVEM memory->FPP\n")); + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + fpu_debug(("memory->FMOVEM FPP not legal mode.\n")); + list = extra & 0xff; + incr = -1; + break; + case 1: /* dynamic pred */ + fpu_debug(("memory->FMOVEM FPP not legal mode.\n")); + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 3: /* dynamic postinc */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = 1; + break; + } + + /**/ + if (incr < 0) { + // not reached + for(reg=7; reg>=0; reg--) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + // FPU registers[reg] = make_extended(wrd1, wrd2, wrd3); + make_extended_no_normalize (wrd1, wrd2, wrd3, FPU registers[reg]); + } + list <<= 1; + } + } + else { + for(reg=0; reg<8; reg++) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + // FPU registers[reg] = make_extended(wrd1, wrd2, wrd3); + make_extended_no_normalize (wrd1, wrd2, wrd3, FPU registers[reg]); + } + list <<= 1; + } + } + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? + m68k_areg (regs, opcode & 7) = ad; + } + dump_registers( "END "); + return; + } + case 0: + case 2: + reg = (extra >> 7) & 7; + if ((extra & 0xfc00) == 0x5c00) { + fpu_debug(("FMOVECR memory->FPP\n")); + switch (extra & 0x7f) { + case 0x00: + // FPU registers[reg] = 4.0 * atan(1.0); + FPU registers[reg] = LD(3.1415926535897932384626433832795029); + fpu_debug(("FP const: Pi\n")); + break; + case 0x0b: + // FPU registers[reg] = log10 (2.0); + FPU registers[reg] = LD(0.30102999566398119521); // 0.3010299956639811952137388947244930L + fpu_debug(("FP const: Log 10 (2)\n")); + break; + case 0x0c: + // FPU registers[reg] = exp (1.0); + FPU registers[reg] = LD(2.7182818284590452353); // 2.7182818284590452353602874713526625L + fpu_debug(("FP const: e\n")); + break; + case 0x0d: + // FPU registers[reg] = log (exp (1.0)) / log (2.0); + FPU registers[reg] = LD(1.4426950408889634073599246810019); + fpu_debug(("FP const: Log 2 (e)\n")); + break; + case 0x0e: + // FPU registers[reg] = log (exp (1.0)) / log (10.0); + FPU registers[reg] = LD(0.4342944819032518276511289189166051); + fpu_debug(("FP const: Log 10 (e)\n")); + break; + case 0x0f: + FPU registers[reg] = 0.0; + fpu_debug(("FP const: zero\n")); + break; + case 0x30: + // FPU registers[reg] = log (2.0); + FPU registers[reg] = LD(0.6931471805599453094172321214581766); + fpu_debug(("FP const: ln(2)\n")); + break; + case 0x31: + // FPU registers[reg] = log (10.0); + FPU registers[reg] = LD(2.3025850929940456840179914546843642); + fpu_debug(("FP const: ln(10)\n")); + break; + case 0x32: + FPU registers[reg] = LD(1.0e0); + fpu_debug(("FP const: 1.0e0\n")); + break; + case 0x33: + FPU registers[reg] = LD(1.0e1); + fpu_debug(("FP const: 1.0e1\n")); + break; + case 0x34: + FPU registers[reg] = LD(1.0e2); + fpu_debug(("FP const: 1.0e2\n")); + break; + case 0x35: + FPU registers[reg] = LD(1.0e4); + fpu_debug(("FP const: 1.0e4\n")); + break; + case 0x36: + FPU registers[reg] = LD(1.0e8); + fpu_debug(("FP const: 1.0e8\n")); + break; + case 0x37: + FPU registers[reg] = LD(1.0e16); + fpu_debug(("FP const: 1.0e16\n")); + break; + case 0x38: + FPU registers[reg] = LD(1.0e32); + fpu_debug(("FP const: 1.0e32\n")); + break; + case 0x39: + FPU registers[reg] = LD(1.0e64); + fpu_debug(("FP const: 1.0e64\n")); + break; + case 0x3a: + FPU registers[reg] = LD(1.0e128); + fpu_debug(("FP const: 1.0e128\n")); + break; + case 0x3b: + FPU registers[reg] = LD(1.0e256); + fpu_debug(("FP const: 1.0e256\n")); + break; +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + case 0x3c: + FPU registers[reg] = LD(1.0e512); + fpu_debug(("FP const: 1.0e512\n")); + break; + case 0x3d: + FPU registers[reg] = LD(1.0e1024); + fpu_debug(("FP const: 1.0e1024\n")); + break; + case 0x3e: + FPU registers[reg] = LD(1.0e2048); + fpu_debug(("FP const: 1.0e2048\n")); + break; + case 0x3f: + FPU registers[reg] = LD(1.0e4096); + fpu_debug(("FP const: 1.0e4096\n")); + break; +#else + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + make_inf(FPU registers[reg], false); + break; +#endif + default: + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + break; + } + // these *do* affect the status reg + make_fpsr(FPU registers[reg]); + dump_registers( "END "); + return; + } + + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + fpu_debug(("returned from get_fp_value m68k_getpc()=%X\n",m68k_getpc())); + + if (FPU is_integral) { + // 68040-specific operations + switch (extra & 0x7f) { + case 0x40: /* FSMOVE */ + fpu_debug(("FSMOVE %.04f\n",(double)src)); + FPU registers[reg] = (float)src; + make_fpsr(FPU registers[reg]); + break; + case 0x44: /* FDMOVE */ + fpu_debug(("FDMOVE %.04f\n",(double)src)); + FPU registers[reg] = (double)src; + make_fpsr(FPU registers[reg]); + break; + case 0x41: /* FSSQRT */ + fpu_debug(("FSQRT %.04f\n",(double)src)); + FPU registers[reg] = (float)fp_sqrt (src); + make_fpsr(FPU registers[reg]); + break; + case 0x45: /* FDSQRT */ + fpu_debug(("FSQRT %.04f\n",(double)src)); + FPU registers[reg] = (double)fp_sqrt (src); + make_fpsr(FPU registers[reg]); + break; + case 0x58: /* FSABS */ + fpu_debug(("FSABS %.04f\n",(double)src)); + FPU registers[reg] = (float)fp_fabs(src); + make_fpsr(FPU registers[reg]); + break; + case 0x5c: /* FDABS */ + fpu_debug(("FDABS %.04f\n",(double)src)); + FPU registers[reg] = (double)fp_fabs(src); + make_fpsr(FPU registers[reg]); + break; + case 0x5a: /* FSNEG */ + fpu_debug(("FSNEG %.04f\n",(double)src)); + FPU registers[reg] = (float)-src; + make_fpsr(FPU registers[reg]); + break; + case 0x5e: /* FDNEG */ + fpu_debug(("FDNEG %.04f\n",(double)src)); + FPU registers[reg] = (double)-src; + make_fpsr(FPU registers[reg]); + break; + case 0x60: /* FSDIV */ + fpu_debug(("FSDIV %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] / src); + make_fpsr(FPU registers[reg]); + break; + case 0x64: /* FDDIV */ + fpu_debug(("FDDIV %.04f\n",(double)src)); + FPU registers[reg] = (double)(FPU registers[reg] / src); + make_fpsr(FPU registers[reg]); + break; + case 0x62: /* FSADD */ + fpu_debug(("FSADD %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] + src); + make_fpsr(FPU registers[reg]); + break; + case 0x66: /* FDADD */ + fpu_debug(("FDADD %.04f\n",(double)src)); + FPU registers[reg] = (double)(FPU registers[reg] + src); + make_fpsr(FPU registers[reg]); + break; + case 0x68: /* FSSUB */ + fpu_debug(("FSSUB %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] - src); + make_fpsr(FPU registers[reg]); + break; + case 0x6c: /* FDSUB */ + fpu_debug(("FDSUB %.04f\n",(double)src)); + FPU registers[reg] = (double)(FPU registers[reg] - src); + make_fpsr(FPU registers[reg]); + break; + case 0x63: /* FSMUL */ + case 0x67: /* FDMUL */ + fpu_debug(("FMUL %.04f\n",(double)src)); + get_dest_flags(FPU registers[reg]); + get_source_flags(src); + if (fl_dest.in_range && fl_source.in_range) { + if ((extra & 0x7f) == 0x63) + FPU registers[reg] = (float)(FPU registers[reg] * src); + else + FPU registers[reg] = (double)(FPU registers[reg] * src); + } + else if (fl_dest.nan || fl_source.nan || + (fl_dest.zero && fl_source.infinity) || + (fl_dest.infinity && fl_source.zero) ) { + make_nan( FPU registers[reg], fl_dest.negative ); + } + else if (fl_dest.zero || fl_source.zero ) { + make_zero(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + else { + make_inf(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + make_fpsr(FPU registers[reg]); + break; + default: + // Continue decode-execute 6888x instructions below + goto process_6888x_instructions; + } + fpu_debug(("END m68k_getpc()=%X\n",m68k_getpc())); + dump_registers( "END "); + return; + } + + process_6888x_instructions: + switch (extra & 0x7f) { + case 0x00: /* FMOVE */ + fpu_debug(("FMOVE %.04f\n",(double)src)); + FPU registers[reg] = src; + make_fpsr(FPU registers[reg]); + break; + case 0x01: /* FINT */ + /* + * FIXME: in round-to-nearest, x87 + * uses round-to-odd, but m68k round-to-even rule + */ + fpu_debug(("FINT %.04f\n",(double)src)); + if (isinf(src)) + FPU registers[reg] = src; + else + FPU registers[reg] = fp_doround(src); + make_fpsr(FPU registers[reg]); + break; + case 0x02: /* FSINH */ + fpu_debug(("FSINH %.04f\n",(double)src)); + if (isinf(src)) + FPU registers[reg] = src; + else + FPU registers[reg] = fp_sinh (src); + make_fpsr(FPU registers[reg]); + break; + case 0x03: /* FINTRZ */ + fpu_debug(("FINTRZ %.04f\n",(double)src)); + if (isinf(src)) + FPU registers[reg] = src; + else + FPU registers[reg] = fp_round_to_zero(src); + make_fpsr(FPU registers[reg]); + break; + case 0x04: /* FSQRT */ + fpu_debug(("FSQRT %.04f\n",(double)src)); + if (isinf(src) && !isneg(src)) + FPU registers[reg] = src; + else + FPU registers[reg] = fp_sqrt (src); + make_fpsr(FPU registers[reg]); + break; + case 0x06: /* FLOGNP1 */ + fpu_debug(("FLOGNP1 %.04f\n",(double)src)); + if (isinf(src) && !isneg(src)) + make_inf(FPU registers[reg], false); + else + FPU registers[reg] = fp_log1p (src); + make_fpsr(FPU registers[reg]); + break; + case 0x08: /* FETOXM1 */ + fpu_debug(("FETOXM1 %.04f\n",(double)src)); + FPU registers[reg] = fp_expm1 (src); + make_fpsr(FPU registers[reg]); + break; + case 0x09: /* FTANH */ + fpu_debug(("FTANH %.04f\n",(double)src)); + if (isinf(src)) + FPU registers[reg] = isneg(src) ? LD(-1.0) : LD(1.0); + else + FPU registers[reg] = fp_tanh (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0a: /* FATAN */ + fpu_debug(("FATAN %.04f\n",(double)src)); + if (isinf(src)) + FPU registers[reg] = isneg (src) ? LD(-1.570796326794896619231321691639751442) : LD(1.570796326794896619231321691639751442); + else + FPU registers[reg] = fp_atan (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0c: /* FASIN */ + fpu_debug(("FASIN %.04f\n",(double)src)); + FPU registers[reg] = fp_asin (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0d: /* FATANH */ + fpu_debug(("FATANH %.04f\n",(double)src)); + FPU registers[reg] = fp_atanh (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0e: /* FSIN */ + fpu_debug(("FSIN %.04f\n",(double)src)); + FPU registers[reg] = fp_sin (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0f: /* FTAN */ + fpu_debug(("FTAN %.04f\n",(double)src)); + FPU registers[reg] = fp_tan (src); + make_fpsr(FPU registers[reg]); + break; + case 0x10: /* FETOX */ + fpu_debug(("FETOX %.04f\n",(double)src)); + if (isinf(src)) + { + make_zero(FPU registers[reg], isneg(src)); + } else + { + FPU registers[reg] = fp_exp (src); + } + make_fpsr(FPU registers[reg]); + break; + case 0x11: /* FTWOTOX */ + fpu_debug(("FTWOTOX %.04f\n",(double)src)); + if (isinf(src)) + { + if (isneg(src)) + make_zero(FPU registers[reg], false); + else + make_inf(FPU registers[reg], true); + } else + { + FPU registers[reg] = fp_pow2(src); + } + make_fpsr(FPU registers[reg]); + break; + case 0x12: /* FTENTOX */ + fpu_debug(("FTENTOX %.04f\n",(double)src)); + if (isinf(src)) + { + if (isneg(src)) + make_zero(FPU registers[reg], false); + else + make_inf(FPU registers[reg], true); + } else + { + FPU registers[reg] = fp_pow10(src); + } + make_fpsr(FPU registers[reg]); + break; + case 0x14: /* FLOGN */ + fpu_debug(("FLOGN %.04f\n",(double)src)); + if (isinf(src) && !isneg(src)) + make_inf(FPU registers[reg], false); + else + FPU registers[reg] = fp_log (src); + make_fpsr(FPU registers[reg]); + break; + case 0x15: /* FLOG10 */ + fpu_debug(("FLOG10 %.04f\n",(double)src)); + if (isinf(src) && !isneg(src)) + make_inf(FPU registers[reg], false); + else + FPU registers[reg] = fp_log10 (src); + make_fpsr(FPU registers[reg]); + break; + case 0x16: /* FLOG2 */ + fpu_debug(("FLOG2 %.04f\n",(double)src)); + if (isinf(src) && !isneg(src)) + make_inf(FPU registers[reg], false); + else + FPU registers[reg] = fp_log2 (src); + make_fpsr(FPU registers[reg]); + break; + case 0x18: /* FABS */ + fpu_debug(("FABS %.04f\n",(double)src)); + FPU registers[reg] = fp_fabs(src); + make_fpsr(FPU registers[reg]); + break; + case 0x19: /* FCOSH */ + fpu_debug(("FCOSH %.04f\n",(double)src)); + if (isinf(src)) + { + make_inf(FPU registers[reg], false); + } else + { + FPU registers[reg] = fp_cosh(src); + } + make_fpsr(FPU registers[reg]); + break; + case 0x1a: /* FNEG */ + fpu_debug(("FNEG %.04f\n",(double)src)); + if (iszero(src)) + make_zero(FPU registers[reg], !isneg(src)); + else + FPU registers[reg] = -src; + make_fpsr(FPU registers[reg]); + break; + case 0x1c: /* FACOS */ + fpu_debug(("FACOS %.04f\n",(double)src)); + FPU registers[reg] = fp_acos(src); + make_fpsr(FPU registers[reg]); + break; + case 0x1d: /* FCOS */ + fpu_debug(("FCOS %.04f\n",(double)src)); + FPU registers[reg] = fp_cos(src); + make_fpsr(FPU registers[reg]); + break; + case 0x1e: /* FGETEXP */ + fpu_debug(("FGETEXP %.04f\n",(double)src)); + if( isinf(src) ) { + make_nan( FPU registers[reg], isneg(src) ); + } + else if( iszero(src) ) { + make_zero(FPU registers[reg], isneg(src)); + } + else { + /* FIXME: subnormals not supported */ + FPU registers[reg] = fast_fgetexp( src ); + } + make_fpsr(FPU registers[reg]); + break; + case 0x1f: /* FGETMAN */ + fpu_debug(("FGETMAN %.04f\n",(double)src)); + if( iszero(src)) { + make_zero(FPU registers[reg], isneg(src)); + } + else if( isinf(src) || isnan(src) ) { + make_nan( FPU registers[reg], 0 ); + } + else { + FPU registers[reg] = src; + fast_remove_exponent( FPU registers[reg] ); + } + make_fpsr(FPU registers[reg]); + break; + case 0x20: /* FDIV */ + fpu_debug(("FDIV %.04f\n",(double)src)); + if (isnan(src) || isnan(FPU registers[reg])) + { + make_nan(FPU registers[reg], false); + } else if (isinf(src)) + { + if (isinf(FPU registers[reg])) + make_nan(FPU registers[reg], false); + else + make_zero(FPU registers[reg], isneg(src) != isneg(FPU registers[reg])); + } else if (isinf(FPU registers[reg])) + { + if (isinf(src)) + make_nan(FPU registers[reg], false); + else + make_inf(FPU registers[reg], isneg(src) != isneg(FPU registers[reg])); + } else if (iszero(FPU registers[reg]) && !iszero(src)) + { + make_zero(FPU registers[reg], isneg(FPU registers[reg]) != isneg(src)); + } else + { + FPU registers[reg] /= src; + } + make_fpsr(FPU registers[reg]); + break; + case 0x21: /* FMOD */ + fpu_debug(("FMOD %.04f\n",(double)src)); + // FPU registers[reg] = FPU registers[reg] - (fpu_register) ((int) (FPU registers[reg] / src)) * src; + { + fpu_register quot = fp_round_to_zero(FPU registers[reg] / src); + uae_u32 sign = get_quotient_sign(FPU registers[reg],src); + FPU registers[reg] = FPU registers[reg] - quot * src; + make_fpsr(FPU registers[reg]); + make_quotient(quot, sign); + } + break; + case 0x23: /* FMUL */ + fpu_debug(("FMUL %.04f\n",(double)src)); + get_dest_flags(FPU registers[reg]); + get_source_flags(src); + if (fl_dest.in_range && fl_source.in_range) { + FPU registers[reg] *= src; + if (unlikely(isinf(FPU registers[reg]))) + { + make_inf(FPU registers[reg], isneg(FPU registers[reg])); + } + } + else if (fl_dest.nan || fl_source.nan || + (fl_dest.zero && fl_source.infinity) || + (fl_dest.infinity && fl_source.zero) ) { + make_nan( FPU registers[reg], fl_dest.negative ); + } + else if (fl_dest.zero || fl_source.zero ) { + make_zero(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + else { + make_inf(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + make_fpsr(FPU registers[reg]); + break; + case 0x24: /* FSGLDIV */ + fpu_debug(("FSGLDIV %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] / src); + make_fpsr(FPU registers[reg]); + break; + case 0x25: /* FREM */ + fpu_debug(("FREM %.04f\n",(double)src)); + // FPU registers[reg] = FPU registers[reg] - (double) ((int) (FPU registers[reg] / src + 0.5)) * src; + { + fpu_register quot = fp_round_to_even(FPU registers[reg] / src); + uae_u32 sign = get_quotient_sign(FPU registers[reg],src); + FPU registers[reg] = FPU registers[reg] - quot * src; + make_fpsr(FPU registers[reg]); + make_quotient(quot,sign); + } + break; + + case 0x26: /* FSCALE */ + fpu_debug(("FSCALE %.04f\n",(double)src)); + // TODO: overflow flags + get_dest_flags(FPU registers[reg]); + get_source_flags(src); + if (fl_source.in_range && fl_dest.in_range) { + // When the absolute value of the source operand is >= 2^14, + // an overflow or underflow always results. + // Here (int) cast is okay. + int scale_factor = (int)fp_round_to_zero(src); +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = FPU registers[reg]; + int exp = sxp.ieee.exponent; + exp += scale_factor; + if (scale_factor >= FP_EXTENDED_EXP_MAX || exp >= FP_EXTENDED_EXP_MAX) /* overflow */ + { + make_inf(FPU registers[reg], isneg(FPU registers[reg])); + FPU fpsr.exception_status |= FPSR_EXCEPTION_OVFL; + } else if (scale_factor < -FP_EXTENDED_EXP_MAX || exp <= -64) /* underflow */ + { + make_zero(FPU registers[reg], isneg(FPU registers[reg])); + FPU fpsr.exception_status |= FPSR_EXCEPTION_UNFL; + } else if (exp >= 0) /* normal result */ + { + sxp.ieee.exponent = exp; + FPU registers[reg] = sxp.value; + } else /* subnormal result */ + { + exp += 64; + sxp.ieee.exponent = exp; + sxp.value = sxp.value * 5.421010862427522170037e-20L; /* 2^-64 */ + } +#else + fp_declare_init_shape(sxp, double); + sxp.value = FPU registers[reg]; + uae_u32 exp = sxp.ieee.exponent + scale_factor; + if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) + exp = 0; + else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) + exp = FP_DOUBLE_EXP_MAX; + else + exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; + sxp.ieee.exponent = exp; + FPU registers[reg] = sxp.value; +#endif + } + else if (fl_source.infinity || fl_source.nan) { + // Returns NaN for any Infinity source + make_nan( FPU registers[reg], fl_source.negative ); + } else { + // source was zero, or dest was inf or nan + // in either case, dest is unchanged + } + make_fpsr(FPU registers[reg]); + break; + case 0x27: /* FSGLMUL */ + fpu_debug(("FSGLMUL %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] * src); + make_fpsr(FPU registers[reg]); + break; + case 0x28: /* FSUB */ + fpu_debug(("FSUB %.04f\n",(double)src)); + if (isnan(src) || isnan(FPU registers[reg])) + { + make_nan(FPU registers[reg], false); + } else if (isinf(src)) + { + if (isinf(FPU registers[reg]) && isneg(src) == isneg(FPU registers[reg])) + make_nan(FPU registers[reg], false); + else + make_inf(FPU registers[reg], isneg(src)); + } else if (isinf(FPU registers[reg])) + { + if (isinf(src) && isneg(src) == isneg(FPU registers[reg])) + make_nan(FPU registers[reg], false); + else + make_inf(FPU registers[reg], isneg(FPU registers[reg])); + } else + { + FPU registers[reg] -= src; + } + make_fpsr(FPU registers[reg]); + break; + case 0x22: /* FADD */ + fpu_debug(("FADD %.04f\n",(double)src)); + /* + * WTF. inf + some value generates NaN on x87, + * but we need inf in most cases + */ + if (isnan(src) || isnan(FPU registers[reg])) + { + make_nan(FPU registers[reg], false); + } else if (isinf(src)) + { + if (isinf(FPU registers[reg]) && isneg(src) != isneg(FPU registers[reg])) + make_nan(FPU registers[reg], false); + else + make_inf(FPU registers[reg], isneg(src)); + } else if (isinf(FPU registers[reg])) + { + if (isinf(src) && isneg(src) != isneg(FPU registers[reg])) + make_nan(FPU registers[reg], false); + else + make_inf(FPU registers[reg], isneg(FPU registers[reg])); + } else + { + FPU registers[reg] += src; + } + make_fpsr(FPU registers[reg]); + break; + case 0x30: /* FSINCOS */ + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + fpu_debug(("FSINCOS %.04f\n",(double)src)); + // Cosine must be calculated first if same register + // note: no need to use special sincos() function here; compiler will optimize that anyway + FPU registers[extra & 7] = fp_cos(src); + FPU registers[reg] = fp_sin (src); + // Set FPU fpsr according to the sine result + make_fpsr(FPU registers[reg]); + break; + case 0x38: /* FCMP */ + fpu_debug(("FCMP %.04f\n",(double)src)); + set_fpsr(0); + if (isnan(src) || isnan(FPU registers[reg])) + { + make_nan(src, false); + make_fpsr(src); + } else if (isinf(FPU registers[reg])) + { + if (isinf(src) && isneg(FPU registers[reg]) == isneg (src)) + { + make_fpsr(0); + } else + { + make_fpsr(FPU registers[reg]); + } + } else if (isinf(src)) + { + make_fpsr(-src); + } else + { + make_fpsr(FPU registers[reg] - src); + } + break; + case 0x3a: /* FTST */ + fpu_debug(("FTST %.04f\n",(double)src)); + set_fpsr(0); + make_fpsr(src); + break; + default: + fpu_debug(("ILLEGAL F OP %X\n",opcode)); + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + break; + } + fpu_debug(("END m68k_getpc()=%X\n",m68k_getpc())); + dump_registers( "END "); + return; + } + + fpu_debug(("ILLEGAL F OP 2 %X\n",opcode)); + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); +} + + +void fpu_set_fpsr(uae_u32 new_fpsr) +{ + set_fpsr(new_fpsr); +} + +uae_u32 fpu_get_fpsr(void) +{ + return get_fpsr(); +} + +void fpu_set_fpcr(uae_u32 new_fpcr) +{ + set_fpcr(new_fpcr); +} + +uae_u32 fpu_get_fpcr(void) +{ + return get_fpcr(); +} + +/* -------------------------- Initialization -------------------------- */ + +PRIVATE uae_u8 m_fpu_state_original[108]; // 90/94/108 + +PUBLIC void FFPU fpu_init (bool integral_68040) +{ + fpu_debug(("fpu_init\n")); + + static bool initialized_lookup_tables = false; + if (!initialized_lookup_tables) { + fpu_init_native_fflags(); + fpu_init_native_exceptions(); + fpu_init_native_accrued_exceptions(); + initialized_lookup_tables = true; + } + + FPU is_integral = integral_68040; + FPU instruction_address = 0; + FPU fpsr.quotient = 0; + set_fpcr(0); + set_fpsr(0); + +#if defined(FPU_USE_X86_ROUNDING) + // Initial state after boot, reset and frestore(null frame) + x86_control_word = CW_INITIAL; +#elif defined(USE_X87_ASSEMBLY) + volatile unsigned short int cw; + __asm__ __volatile__("fnstcw %0" : "=m" (cw)); + cw &= ~0x0300; cw |= 0x0300; // CW_PC_EXTENDED + cw &= ~0x0C00; cw |= 0x0000; // CW_RC_NEAR + __asm__ __volatile__("fldcw %0" : : "m" (cw)); +#endif + + FPU result = 1; + + for (int i = 0; i < 8; i++) + make_nan(FPU registers[i], false); +} + +PUBLIC void FFPU fpu_exit (void) +{ + fpu_debug(("fpu_exit\n")); +} + +PUBLIC void FFPU fpu_reset (void) +{ + fpu_debug(("fpu_reset\n")); + fpu_exit(); + fpu_init(FPU is_integral); +} + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_ieee.h b/BasiliskII/src/uae_cpu_2021/fpu/fpu_ieee.h new file mode 100644 index 000000000..5735874c4 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_ieee.h @@ -0,0 +1,152 @@ +/* + * fpu/fpu_ieee.h - Extra Definitions for the IEEE FPU core + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_IEEE_H +#define FPU_IEEE_H + +/* NOTE: this file shall be included from fpu/fpu_uae.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +// Lauri-- full words to avoid partial register stalls. +struct double_flags { + uae_u32 in_range; + uae_u32 zero; + uae_u32 infinity; + uae_u32 nan; + uae_u32 negative; +}; +PRIVATE double_flags fl_source; +PRIVATE double_flags fl_dest; +PRIVATE inline void FFPU get_dest_flags(fpu_register const & r); +PRIVATE inline void FFPU get_source_flags(fpu_register const & r); + +PRIVATE inline void FFPU make_nan(fpu_register & r, bool negative); +PRIVATE inline void FFPU make_zero(fpu_register & r, bool negative); +PRIVATE inline void FFPU make_inf(fpu_register & r, bool negative); + +// MJ PRIVATE inline void FFPU fast_scale(fpu_register & r, int add); +PRIVATE inline fpu_register FFPU fast_fgetexp(fpu_register const & r); + +// May be optimized for particular processors +#ifndef FPU_USE_NATIVE_FLAGS +PRIVATE inline void FFPU make_fpsr(fpu_register const & r); +#endif + +// Normalize to range 1..2 +PRIVATE inline void FFPU fast_remove_exponent(fpu_register & r); + +// The sign of the quotient is the exclusive-OR of the sign bits +// of the source and destination operands. +PRIVATE inline uae_u32 FFPU get_quotient_sign( + fpu_register const & ra, fpu_register const & rb +); + +// Quotient Byte is loaded with the sign and least significant +// seven bits of the quotient. +PRIVATE inline void FFPU make_quotient( + fpu_register const & quotient, uae_u32 sign +); + +// to_single +PRIVATE inline fpu_register FFPU make_single( + uae_u32 value +); + +// from_single +PRIVATE inline uae_u32 FFPU extract_single( + fpu_register const & src +); + +// to_exten +PRIVATE inline fpu_register FFPU make_extended( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 +); + +/* + Would be so much easier with full size floats :( + ... this is so vague. +*/ +// to_exten_no_normalize +PRIVATE inline void FFPU make_extended_no_normalize( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result +); + +// from_exten +PRIVATE inline void FFPU extract_extended(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +); + +// to_double +PRIVATE inline fpu_register FFPU make_double( + uae_u32 wrd1, uae_u32 wrd2 +); + +// from_double +PRIVATE inline void FFPU extract_double(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2 +); + +PRIVATE inline fpu_register FFPU make_packed( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 +); + +PRIVATE inline void FFPU extract_packed( + fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +); + +PRIVATE inline int FFPU get_fp_value( + uae_u32 opcode, uae_u16 extra, fpu_register & src +); + +PRIVATE inline int FFPU put_fp_value( + uae_u32 opcode, uae_u16 extra, fpu_register const & value +); + +PRIVATE inline int FFPU get_fp_ad( + uae_u32 opcode, uae_u32 * ad +); + +PRIVATE inline int FFPU fpp_cond( + int condition +); + +#endif /* FPU_IEEE_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_mpfr.cpp b/BasiliskII/src/uae_cpu_2021/fpu/fpu_mpfr.cpp new file mode 100644 index 000000000..60352bc19 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_mpfr.cpp @@ -0,0 +1,2115 @@ +/* + * fpu_mpfr.cpp - emulate 68881/68040 fpu with mpfr + * + * Copyright (c) 2012, 2013 Andreas Schwab + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "sysdeps.h" + +#ifdef FPU_MPFR + +#include +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#include "main.h" +#define FPU_IMPLEMENTATION +#include "fpu/fpu.h" + +#include "fpu/flags.h" +#include "fpu/exceptions.h" +#include "fpu/rounding.h" +#include "fpu/impl.h" + +#define SINGLE_PREC 24 +#define SINGLE_MIN_EXP -126 +#define SINGLE_MAX_EXP 127 +#define SINGLE_BIAS 127 +#define DOUBLE_PREC 53 +#define DOUBLE_MIN_EXP -1022 +#define DOUBLE_MAX_EXP 1023 +#define DOUBLE_BIAS 1023 +#define EXTENDED_PREC 64 +#define EXTENDED_MIN_EXP -16383 +#define EXTENDED_MAX_EXP 16383 +#define EXTENDED_BIAS 16383 + +fpu_t fpu; +// The constant ROM +// Constants 48 to 63 are mapped to index 16 to 31 +const int num_fpu_constants = 32; +static mpfr_t fpu_constant_rom[num_fpu_constants]; +#define FPU_CONSTANT_ONE fpu_constant_rom[18] +// Exceptions generated during execution in addition to the ones +// maintained by mpfr +static uae_u32 cur_exceptions; +static uaecptr cur_instruction_address; + +static void +set_format (int prec) +{ + // MPFR represents numbers as 0.m*2^e + switch (prec) + { + case SINGLE_PREC: + mpfr_set_emin (SINGLE_MIN_EXP + 1 - (SINGLE_PREC - 1)); + mpfr_set_emax (SINGLE_MAX_EXP + 1); + break; + case DOUBLE_PREC: + mpfr_set_emin (DOUBLE_MIN_EXP + 1 - (DOUBLE_PREC - 1)); + mpfr_set_emax (DOUBLE_MAX_EXP + 1); + break; + case EXTENDED_PREC: + mpfr_set_emin (EXTENDED_MIN_EXP + 1 - (EXTENDED_PREC - 1)); + mpfr_set_emax (EXTENDED_MAX_EXP + 1); + break; + } +} + +static mpfr_rnd_t +get_cur_rnd () +{ + switch (get_rounding_mode ()) + { + default: + case FPCR_ROUND_NEAR: + return MPFR_RNDN; + case FPCR_ROUND_ZERO: + return MPFR_RNDZ; + case FPCR_ROUND_MINF: + return MPFR_RNDD; + case FPCR_ROUND_PINF: + return MPFR_RNDU; + } +} + +static mpfr_prec_t +get_cur_prec () +{ + switch (get_rounding_precision ()) + { + default: + case FPCR_PRECISION_EXTENDED: + return EXTENDED_PREC; + case FPCR_PRECISION_SINGLE: + return SINGLE_PREC; + case FPCR_PRECISION_DOUBLE: + return DOUBLE_PREC; + } +} + +#define DEFAULT_NAN_BITS 0xffffffffffffffffULL + +static void +set_nan (fpu_register ®, uae_u64 nan_bits, int nan_sign) +{ + mpfr_set_nan (reg.f); + reg.nan_bits = nan_bits; + reg.nan_sign = nan_sign; +} + +static void +set_nan (fpu_register ®) +{ + set_nan (reg, DEFAULT_NAN_BITS, 0); +} + +static bool fpu_inited; + +void +fpu_init (bool integral_68040) +{ + fpu.is_integral = integral_68040; + + mpfr_set_default_prec (EXTENDED_PREC); + mpfr_set_default_rounding_mode (MPFR_RNDN); + set_format (EXTENDED_PREC); + + for (int i = 0; i < 8; i++) + mpfr_init (fpu.registers[i].f); + mpfr_init (fpu.result.f); + + // Initialize constant ROM + for (int i = 0; i < num_fpu_constants; i++) + mpfr_init (fpu_constant_rom[i]); + + // 0: pi + mpfr_const_pi (fpu_constant_rom[0], MPFR_RNDN); + // 11: log10 (2) + mpfr_set_ui (fpu_constant_rom[11], 2, MPFR_RNDN); + mpfr_log10 (fpu_constant_rom[11], fpu_constant_rom[11], MPFR_RNDZ); + // 12: e + mpfr_set_ui (fpu_constant_rom[12], 1, MPFR_RNDN); + mpfr_exp (fpu_constant_rom[12], fpu_constant_rom[12], MPFR_RNDZ); + // 13: log2 (e) + mpfr_log2 (fpu_constant_rom[13], fpu_constant_rom[12], MPFR_RNDU); + // 14: log10 (e) + mpfr_log10 (fpu_constant_rom[14], fpu_constant_rom[12], MPFR_RNDU); + // 15: 0 + mpfr_set_zero (fpu_constant_rom[15], 0); + // 48: ln (2) + mpfr_const_log2 (fpu_constant_rom[16], MPFR_RNDN); + // 49: ln (10) + mpfr_set_ui (fpu_constant_rom[17], 10, MPFR_RNDN); + mpfr_log (fpu_constant_rom[17], fpu_constant_rom[17], MPFR_RNDN); + // 50 to 63: powers of 10 + mpfr_set_ui (fpu_constant_rom[18], 1, MPFR_RNDN); + for (int i = 19; i < 32; i++) + { + mpfr_set_ui (fpu_constant_rom[i], 1L << (i - 19) , MPFR_RNDN); + mpfr_exp10 (fpu_constant_rom[i], fpu_constant_rom[i], MPFR_RNDN); + } + + fpu_inited = true; + + fpu_reset (); +} + +void +fpu_exit () +{ + if (!fpu_inited) return; + + for (int i = 0; i < 8; i++) + mpfr_clear (fpu.registers[i].f); + mpfr_clear (fpu.result.f); + for (int i = 0; i < num_fpu_constants; i++) + mpfr_clear (fpu_constant_rom[i]); +} + +void +fpu_reset () +{ + set_fpcr (0); + set_fpsr (0); + fpu.instruction_address = 0; + + for (int i = 0; i < 8; i++) + set_nan (fpu.registers[i]); +} + +fpu_register::operator long double () +{ + return mpfr_get_ld (f, MPFR_RNDN); +} + +fpu_register & +fpu_register::operator= (long double x) +{ + mpfr_set_ld (f, x, MPFR_RNDN); + nan_bits = DEFAULT_NAN_BITS; + nan_sign = 0; + return *this; +} + +static bool +get_fp_addr (uae_u32 opcode, uae_u32 *addr, bool write) +{ + uaecptr pc; + int mode; + int reg; + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + switch (mode) + { + case 0: + case 1: + return false; + case 2: + *addr = m68k_areg (regs, reg); + break; + case 3: + *addr = m68k_areg (regs, reg); + break; + case 4: + *addr = m68k_areg (regs, reg); + break; + case 5: + *addr = m68k_areg (regs, reg) + (uae_s16) next_iword(); + break; + case 6: + *addr = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) + { + case 0: + *addr = (uae_s16) next_iword(); + break; + case 1: + *addr = next_ilong(); + break; + case 2: + if (write) + return false; + pc = m68k_getpc (); + *addr = pc + (uae_s16) next_iword(); + break; + case 3: + if (write) + return false; + pc = m68k_getpc (); + *addr = get_disp_ea_020 (pc, next_iword()); + break; + default: + return false; + } + } + return true; +} + +static void +set_from_single (fpu_register &value, uae_u32 data) +{ + int s = data >> 31; + int e = (data >> 23) & 0xff; + uae_u32 m = data & 0x7fffff; + + if (e == 0xff) + { + if (m != 0) + { + if (!(m & 0x400000)) + cur_exceptions |= FPSR_EXCEPTION_SNAN; + set_nan (value, (uae_u64) (m | 0xc00000) << (32 + 8), s); + } + else + mpfr_set_inf (value.f, 0); + } + else + { + if (e != 0) + // Add integer bit + m |= 0x800000; + else + e++; + // Remove bias + e -= SINGLE_BIAS; + mpfr_set_ui_2exp (value.f, m, e - (SINGLE_PREC - 1), MPFR_RNDN); + } + mpfr_setsign (value.f, value.f, s, MPFR_RNDN); +} + +static void +set_from_double (fpu_register &value, uae_u32 words[2]) +{ + int s = words[0] >> 31; + int e = (words[0] >> 20) & 0x7ff; + uae_u32 m = words[0] & 0xfffff; + + if (e == 0x7ff) + { + if ((m | words[1]) != 0) + { + if (!(m & 0x80000)) + cur_exceptions |= FPSR_EXCEPTION_SNAN; + set_nan (value, (((uae_u64) (m | 0x180000) << (32 + 11)) + | ((uae_u64) words[1] << 11)), s); + } + else + mpfr_set_inf (value.f, 0); + } + else + { + if (e != 0) + // Add integer bit + m |= 0x100000; + else + e++; + // Remove bias + e -= DOUBLE_BIAS; + mpfr_set_uj_2exp (value.f, ((uintmax_t) m << 32) | words[1], + e - (DOUBLE_PREC - 1), MPFR_RNDN); + } + mpfr_setsign (value.f, value.f, s, MPFR_RNDN); +} + +static void +set_from_extended (fpu_register &value, uae_u32 words[3], bool check_snan) +{ + int s = words[0] >> 31; + int e = (words[0] >> 16) & 0x7fff; + + if (e == 0x7fff) + { + if (((words[1] & 0x7fffffff) | words[2]) != 0) + { + if (check_snan) + { + if ((words[1] & 0x40000000) == 0) + cur_exceptions |= FPSR_EXCEPTION_SNAN; + words[1] |= 0x40000000; + } + set_nan (value, ((uae_u64) words[1] << 32) | words[2], s); + } + else + mpfr_set_inf (value.f, 0); + } + else + { + // Remove bias + e -= EXTENDED_BIAS; + mpfr_set_uj_2exp (value.f, ((uintmax_t) words[1] << 32) | words[2], + e - (EXTENDED_PREC - 1), MPFR_RNDN); + } + mpfr_setsign (value.f, value.f, s, MPFR_RNDN); +} + +#define from_bcd(d) ((d) < 10 ? (d) : (d) - 10) + +static void +set_from_packed (fpu_register &value, uae_u32 words[3]) +{ + char str[32], *p = str; + int sm = words[0] >> 31; + int se = (words[0] >> 30) & 1; + int i; + + if (((words[0] >> 16) & 0x7fff) == 0x7fff) + { + if ((words[1] | words[2]) != 0) + { + if ((words[1] & 0x40000000) == 0) + cur_exceptions |= FPSR_EXCEPTION_SNAN; + set_nan (value, ((uae_u64) (words[1] | 0x40000000) << 32) | words[2], + sm); + } + else + mpfr_set_inf (value.f, 0); + } + else + { + if (sm) + *p++ = '-'; + *p++ = from_bcd (words[0] & 15) + '0'; + *p++ = '.'; + for (i = 0; i < 8; i++) + { + p[i] = from_bcd ((words[1] >> (28 - i * 4)) & 15) + '0'; + p[i + 8] = from_bcd ((words[2] >> (28 - i * 4)) & 15) + '0'; + } + p += 16; + *p++ = 'e'; + if (se) + *p++ = '-'; + *p++ = from_bcd ((words[0] >> 24) & 15) + '0'; + *p++ = from_bcd ((words[0] >> 20) & 15) + '0'; + *p++ = from_bcd ((words[0] >> 16) & 15) + '0'; + *p = 0; + mpfr_set_str (value.f, str, 10, MPFR_RNDN); + } + mpfr_setsign (value.f, value.f, sm, MPFR_RNDN); +} + +static bool +get_fp_value (uae_u32 opcode, uae_u32 extra, fpu_register &value) +{ + int mode, reg, size; + uaecptr pc; + uae_u32 addr; + uae_u32 words[3]; + static const int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static const int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + if ((extra & 0x4000) == 0) + { + mpfr_set (value.f, fpu.registers[(extra >> 10) & 7].f, MPFR_RNDN); + value.nan_bits = fpu.registers[(extra >> 10) & 7].nan_bits; + value.nan_sign = fpu.registers[(extra >> 10) & 7].nan_sign; + /* Check for SNaN. */ + if (mpfr_nan_p (value.f) && (value.nan_bits & (1ULL << 62)) == 0) + { + value.nan_bits |= 1ULL << 62; + cur_exceptions |= FPSR_EXCEPTION_SNAN; + } + return true; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + switch (mode) + { + case 0: + switch (size) + { + case 6: + mpfr_set_si (value.f, (uae_s8) m68k_dreg (regs, reg), MPFR_RNDN); + break; + case 4: + mpfr_set_si (value.f, (uae_s16) m68k_dreg (regs, reg), MPFR_RNDN); + break; + case 0: + mpfr_set_si (value.f, (uae_s32) m68k_dreg (regs, reg), MPFR_RNDN); + break; + case 1: + set_from_single (value, m68k_dreg (regs, reg)); + break; + default: + return false; + } + return true; + case 1: + return false; + case 2: + case 3: + addr = m68k_areg (regs, reg); + break; + case 4: + addr = m68k_areg (regs, reg) - (reg == 7 ? sz2[size] : sz1[size]); + break; + case 5: + addr = m68k_areg (regs, reg) + (uae_s16) next_iword (); + break; + case 6: + addr = get_disp_ea_020 (m68k_areg (regs, reg), next_iword ()); + break; + case 7: + switch (reg) + { + case 0: + addr = (uae_s16) next_iword (); + break; + case 1: + addr = next_ilong (); + break; + case 2: + pc = m68k_getpc (); + addr = pc + (uae_s16) next_iword (); + break; + case 3: + pc = m68k_getpc (); + addr = get_disp_ea_020 (pc, next_iword ()); + break; + case 4: + addr = m68k_getpc (); + m68k_incpc (sz2[size]); + if (size == 6) // Immediate byte + addr++; + break; + default: + return false; + } + } + + switch (size) + { + case 0: + mpfr_set_si (value.f, (uae_s32) get_long (addr), MPFR_RNDN); + break; + case 1: + set_from_single (value, get_long (addr)); + break; + case 2: + words[0] = get_long (addr); + words[1] = get_long (addr + 4); + words[2] = get_long (addr + 8); + set_from_extended (value, words, true); + break; + case 3: + words[0] = get_long (addr); + words[1] = get_long (addr + 4); + words[2] = get_long (addr + 8); + set_from_packed (value, words); + break; + case 4: + mpfr_set_si (value.f, (uae_s16) get_word (addr), MPFR_RNDN); + break; + case 5: + words[0] = get_long (addr); + words[1] = get_long (addr + 4); + set_from_double (value, words); + break; + case 6: + mpfr_set_si (value.f, (uae_s8) get_byte (addr), MPFR_RNDN); + break; + default: + return false; + } + + switch (mode) + { + case 3: + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + break; + } + + return true; +} + +static void +update_exceptions () +{ + uae_u32 exc, aexc; + + exc = cur_exceptions; + // Add any mpfr detected exceptions + if (mpfr_underflow_p ()) + exc |= FPSR_EXCEPTION_UNFL; + if (mpfr_overflow_p ()) + exc |= FPSR_EXCEPTION_OVFL; + if (mpfr_inexflag_p ()) + exc |= FPSR_EXCEPTION_INEX2; + set_exception_status (exc); + + aexc = get_accrued_exception (); + if (exc & (FPSR_EXCEPTION_SNAN|FPSR_EXCEPTION_OPERR)) + aexc |= FPSR_ACCR_IOP; + if (exc & FPSR_EXCEPTION_OVFL) + aexc |= FPSR_ACCR_OVFL; + if ((exc & (FPSR_EXCEPTION_UNFL|FPSR_EXCEPTION_INEX2)) + == (FPSR_EXCEPTION_UNFL|FPSR_EXCEPTION_INEX2)) + aexc |= FPSR_ACCR_UNFL; + if (exc & FPSR_EXCEPTION_DZ) + aexc |= FPSR_ACCR_DZ; + if (exc & (FPSR_EXCEPTION_INEX1|FPSR_EXCEPTION_INEX2|FPSR_EXCEPTION_OVFL)) + aexc |= FPSR_ACCR_INEX; + set_accrued_exception (aexc); + + if ((fpu.fpcr & exc) != 0) + { + fpu.instruction_address = cur_instruction_address; + // TODO: raise exceptions + // Problem: FPSP040 depends on proper FPU stack frames, it would suffer + // undefined behaviour with our dummy FSAVE implementation + } +} + +static void +set_fp_register (int reg, mpfr_t value, uae_u64 nan_bits, int nan_sign, + int t, mpfr_rnd_t rnd, bool do_flags) +{ + mpfr_subnormalize (value, t, rnd); + mpfr_set (fpu.registers[reg].f, value, rnd); + fpu.registers[reg].nan_bits = nan_bits; + fpu.registers[reg].nan_sign = nan_sign; + if (do_flags) + { + uae_u32 flags = 0; + + if (mpfr_zero_p (fpu.registers[reg].f)) + flags |= FPSR_CCB_ZERO; + if (mpfr_signbit (fpu.registers[reg].f)) + flags |= FPSR_CCB_NEGATIVE; + if (mpfr_nan_p (fpu.registers[reg].f)) + flags |= FPSR_CCB_NAN; + if (mpfr_inf_p (fpu.registers[reg].f)) + flags |= FPSR_CCB_INFINITY; + set_fpccr (flags); + } +} + +static void +set_fp_register (int reg, mpfr_t value, int t, mpfr_rnd_t rnd, bool do_flags) +{ + set_fp_register (reg, value, DEFAULT_NAN_BITS, 0, t, rnd, do_flags); +} + +static void +set_fp_register (int reg, fpu_register &value, int t, mpfr_rnd_t rnd, + bool do_flags) +{ + set_fp_register (reg, value.f, value.nan_bits, value.nan_sign, t, rnd, + do_flags); +} + +static uae_u32 +extract_to_single (fpu_register &value) +{ + uae_u32 word; + int t; + mpfr_rnd_t rnd = get_cur_rnd (); + MPFR_DECL_INIT (single, SINGLE_PREC); + + set_format (SINGLE_PREC); + // Round to single + t = mpfr_set (single, value.f, rnd); + t = mpfr_check_range (single, t, rnd); + mpfr_subnormalize (single, t, rnd); + set_format (EXTENDED_PREC); + + if (mpfr_inf_p (single)) + word = 0x7f800000; + else if (mpfr_nan_p (single)) + { + if ((value.nan_bits & (1ULL << 62)) == 0) + { + value.nan_bits |= 1ULL << 62; + cur_exceptions |= FPSR_EXCEPTION_SNAN; + } + word = 0x7f800000 | ((value.nan_bits >> (32 + 8)) & 0x7fffff); + if (value.nan_sign) + word |= 0x80000000; + } + else if (mpfr_zero_p (single)) + word = 0; + else + { + int e; + mpz_t f; + mpz_init (f); + word = 0; + // Get exponent and mantissa + e = mpfr_get_z_2exp (f, single); + // Move binary point + e += SINGLE_PREC - 1; + // Add bias + e += SINGLE_BIAS; + if (e <= 0) + { + // Denormalized number + mpz_tdiv_q_2exp (f, f, -e + 1); + e = 0; + } + mpz_export (&word, 0, 1, 4, 0, 0, f); + // Remove integer bit + word &= 0x7fffff; + word |= e << 23; + mpz_clear (f); + } + if (mpfr_signbit (single)) + word |= 0x80000000; + return word; +} + +static void +extract_to_double (fpu_register &value, uint32_t *words) +{ + int t; + mpfr_rnd_t rnd = get_cur_rnd (); + MPFR_DECL_INIT (dbl, DOUBLE_PREC); + + set_format (DOUBLE_PREC); + // Round to double + t = mpfr_set (dbl, value.f, rnd); + t = mpfr_check_range (dbl, t, rnd); + mpfr_subnormalize (dbl, t, rnd); + set_format (EXTENDED_PREC); + + if (mpfr_inf_p (dbl)) + { + words[0] = 0x7ff00000; + words[1] = 0; + } + else if (mpfr_nan_p (dbl)) + { + if ((value.nan_bits & (1ULL << 62)) == 0) + { + value.nan_bits |= 1ULL << 62; + cur_exceptions |= FPSR_EXCEPTION_SNAN; + } + words[0] = 0x7ff00000 | ((value.nan_bits >> (32 + 11)) & 0xfffff); + words[1] = value.nan_bits >> 11; + if (value.nan_sign) + words[0] |= 0x80000000; + } + else if (mpfr_zero_p (dbl)) + { + words[0] = 0; + words[1] = 0; + } + else + { + int e, off = 0; + mpz_t f; + mpz_init (f); + words[0] = words[1] = 0; + // Get exponent and mantissa + e = mpfr_get_z_2exp (f, dbl); + // Move binary point + e += DOUBLE_PREC - 1; + // Add bias + e += DOUBLE_BIAS; + if (e <= 0) + { + // Denormalized number + mpz_tdiv_q_2exp (f, f, -e + 1); + if (e <= -20) + // No more than 32 bits left + off = 1; + e = 0; + } + mpz_export (&words[off], 0, 1, 4, 0, 0, f); + // Remove integer bit + words[0] &= 0xfffff; + words[0] |= e << 20; + mpz_clear (f); + } + if (mpfr_signbit (dbl)) + words[0] |= 0x80000000; +} + +static void +extract_to_extended (fpu_register &value, uint32_t *words) +{ + if (mpfr_inf_p (value.f)) + { + words[0] = 0x7fff0000; + words[1] = 0; + words[2] = 0; + } + else if (mpfr_nan_p (value.f)) + { + words[0] = 0x7fff0000; + words[1] = value.nan_bits >> 32; + words[2] = value.nan_bits; + if (value.nan_sign) + words[0] |= 0x80000000; + } + else if (mpfr_zero_p (value.f)) + { + words[0] = 0; + words[1] = 0; + words[2] = 0; + } + else + { + int e, off = 0; + mpz_t f; + + mpz_init (f); + words[0] = words[1] = words[2] = 0; + // Get exponent and mantissa + e = mpfr_get_z_2exp (f, value.f); + // Move binary point + e += EXTENDED_PREC - 1; + // Add bias + e += EXTENDED_BIAS; + if (e < 0) + { + // Denormalized number + mpz_tdiv_q_2exp (f, f, -e); + if (e <= -32) + // No more than 32 bits left + off = 1; + e = 0; + } + mpz_export (&words[1 + off], 0, 1, 4, 0, 0, f); + words[0] = e << 16; + mpz_clear (f); + } + if (mpfr_signbit (value.f)) + words[0] |= 0x80000000; +} + +static void +extract_to_packed (fpu_register &value, int k, uae_u32 *words) +{ + if (mpfr_inf_p (value.f)) + { + words[0] = 0x7fff0000; + words[1] = 0; + words[2] = 0; + } + else if (mpfr_nan_p (value.f)) + { + words[0] = 0x7fff0000; + words[1] = value.nan_bits >> 32; + words[2] = value.nan_bits; + if (value.nan_sign) + words[0] |= 0x80000000; + } + else if (mpfr_zero_p (value.f)) + { + words[0] = 0; + words[1] = 0; + words[2] = 0; + } + else + { + char str[100], *p = str; + mpfr_exp_t e; + mpfr_rnd_t rnd = get_cur_rnd (); + + words[0] = words[1] = words[2] = 0; + if (k >= 64) + k -= 128; + else if (k >= 18) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + if (k <= 0) + { + MPFR_DECL_INIT (temp, 16); + + mpfr_log10 (temp, value.f, rnd); + k = mpfr_get_si (temp, MPFR_RNDZ) - k + 1; + } + if (k <= 0) + k = 1; + else if (k >= 18) + k = 17; + mpfr_get_str (str, &e, 10, k, value.f, rnd); + e--; + if (*p == '-') + p++; + // Pad to 17 digits + while (k < 17) + p[k++] = '0'; + if (e < 0) + { + words[0] |= 0x40000000; + e = -e; + } + words[0] |= (e % 10) << 16; + e /= 10; + words[0] |= (e % 10) << 20; + e /= 10; + words[0] |= (e % 10) << 24; + e /= 10; + if (e) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + words[0] |= e << 12; + words[0] |= *p++ & 15; + for (k = 0; k < 8; k++) + words[1] = (words[1] << 4) | (*p++ & 15); + for (k = 0; k < 8; k++) + words[2] = (words[2] << 4) | (*p++ & 15); + + } + if (mpfr_signbit (value.f)) + words[0] |= 0x80000000; +} + +static long +extract_to_integer (mpfr_t value, long min, long max) +{ + long result; + mpfr_rnd_t rnd = get_cur_rnd (); + + if (mpfr_fits_slong_p (value, rnd)) + { + result = mpfr_get_si (value, rnd); + if (result > max) + { + result = max; + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (result < min) + { + result = min; + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + } + else + { + if (!mpfr_signbit (value)) + result = max; + else + result = min; + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + return result; +} + +static bool +fpuop_fmove_memory (uae_u32 opcode, uae_u32 extra) +{ + int mode, reg, size; + uaecptr pc; + uae_u32 addr; + uae_u32 words[3]; + static const int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static const int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + mpfr_clear_flags (); + cur_exceptions = 0; + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + fpu_register &value = fpu.registers[(extra >> 7) & 7]; + + switch (mode) + { + case 0: + switch (size) + { + case 0: + m68k_dreg (regs, reg) = extract_to_integer (value.f, -0x7fffffff-1, 0x7fffffff); + break; + case 1: + m68k_dreg (regs, reg) = extract_to_single (value); + break; + case 4: + m68k_dreg (regs, reg) &= ~0xffff; + m68k_dreg (regs, reg) |= extract_to_integer (value.f, -32768, 32767) & 0xffff; + break; + case 6: + m68k_dreg (regs, reg) &= ~0xff; + m68k_dreg (regs, reg) |= extract_to_integer (value.f, -128, 127) & 0xff; + break; + default: + return false; + } + update_exceptions (); + return true; + case 1: + return false; + case 2: + addr = m68k_areg (regs, reg); + break; + case 3: + addr = m68k_areg (regs, reg); + break; + case 4: + addr = m68k_areg (regs, reg) - (reg == 7 ? sz2[size] : sz1[size]); + break; + case 5: + addr = m68k_areg (regs, reg) + (uae_s16) next_iword(); + break; + case 6: + addr = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) + { + case 0: + addr = (uae_s16) next_iword(); + break; + case 1: + addr = next_ilong(); + break; + case 2: + pc = m68k_getpc (); + addr = pc + (uae_s16) next_iword(); + break; + case 3: + pc = m68k_getpc (); + addr = get_disp_ea_020 (pc, next_iword ()); + break; + case 4: + addr = m68k_getpc (); + m68k_incpc (sz2[size]); + break; + default: + return false; + } + } + + switch (size) + { + case 0: + put_long (addr, extract_to_integer (value.f, -0x7fffffff-1, 0x7fffffff)); + break; + case 1: + put_long (addr, extract_to_single (value)); + break; + case 2: + extract_to_extended (value, words); + put_long (addr, words[0]); + put_long (addr + 4, words[1]); + put_long (addr + 8, words[2]); + break; + case 3: + extract_to_packed (value, extra & 0x7f, words); + put_long (addr, words[0]); + put_long (addr + 4, words[1]); + put_long (addr + 8, words[2]); + break; + case 4: + put_word (addr, extract_to_integer (value.f, -32768, 32767)); + break; + case 5: + extract_to_double (value, words); + put_long (addr, words[0]); + put_long (addr + 4, words[1]); + break; + case 6: + put_byte (addr, extract_to_integer (value.f, -128, 127)); + break; + case 7: + extract_to_packed (value, m68k_dreg (regs, (extra >> 4) & 7) & 0x7f, words); + put_long (addr, words[0]); + put_long (addr + 4, words[1]); + put_long (addr + 8, words[2]); + break; + } + + switch (mode) + { + case 3: + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + break; + } + + update_exceptions (); + return true; +} + +static bool +fpuop_fmovem_control (uae_u32 opcode, uae_u32 extra) +{ + int list, mode, reg; + uae_u32 addr; + + list = (extra >> 10) & 7; + mode = (opcode >> 3) & 7; + reg = opcode & 7; + + if (list == 0) + return false; + + if (extra & 0x2000) + { + // FMOVEM to + if (mode == 0) + { + switch (list) + { + case 1: + m68k_dreg (regs, reg) = fpu.instruction_address; + break; + case 2: + m68k_dreg (regs, reg) = get_fpsr (); + break; + case 4: + m68k_dreg (regs, reg) = get_fpcr (); + break; + default: + return false; + } + } + else if (mode == 1) + { + if (list != 1) + return false; + m68k_areg (regs, reg) = fpu.instruction_address; + } + else + { + int nwords; + + if (!get_fp_addr (opcode, &addr, true)) + return false; + nwords = (list & 1) + ((list >> 1) & 1) + ((list >> 2) & 1); + if (mode == 4) + addr -= nwords * 4; + if (list & 4) + { + put_long (addr, get_fpcr ()); + addr += 4; + } + if (list & 2) + { + put_long (addr, get_fpsr ()); + addr += 4; + } + if (list & 1) + { + put_long (addr, fpu.instruction_address); + addr += 4; + } + if (mode == 4) + m68k_areg (regs, reg) = addr - nwords * 4; + else if (mode == 3) + m68k_areg (regs, reg) = addr; + } + } + else + { + // FMOVEM from + + if (mode == 0) + { + switch (list) + { + case 1: + fpu.instruction_address = m68k_dreg (regs, reg); + break; + case 2: + set_fpsr (m68k_dreg (regs, reg)); + break; + case 4: + set_fpcr (m68k_dreg (regs, reg)); + break; + default: + return false; + } + } + else if (mode == 1) + { + if (list != 1) + return false; + fpu.instruction_address = m68k_areg (regs, reg); + } + else if ((opcode & 077) == 074) + { + switch (list) + { + case 1: + fpu.instruction_address = next_ilong (); + break; + case 2: + set_fpsr (next_ilong ()); + break; + case 4: + set_fpcr (next_ilong ()); + break; + default: + return false; + } + } + else + { + int nwords; + + if (!get_fp_addr (opcode, &addr, false)) + return false; + nwords = (list & 1) + ((list >> 1) & 1) + ((list >> 2) & 1); + if (mode == 4) + addr -= nwords * 4; + if (list & 4) + { + set_fpcr (get_long (addr)); + addr += 4; + } + if (list & 2) + { + set_fpsr (get_long (addr)); + addr += 4; + } + if (list & 1) + { + fpu.instruction_address = get_long (addr); + addr += 4; + } + if (mode == 4) + m68k_areg (regs, reg) = addr - nwords * 4; + else if (mode == 3) + m68k_areg (regs, reg) = addr; + } + } + + return true; +} + +static bool +fpuop_fmovem_register (uae_u32 opcode, uae_u32 extra) +{ + uae_u32 addr; + uae_u32 words[3]; + int list; + int i; + + set_format (EXTENDED_PREC); + if (!get_fp_addr (opcode, &addr, extra & 0x2000)) + return false; + if (extra & 0x800) + list = m68k_dreg (regs, (extra >> 4) & 7) & 0xff; + else + list = extra & 0xff; + + if (extra & 0x2000) + { + // FMOVEM to memory + + switch (opcode & 070) + { + case 030: + return false; + case 040: + if (extra & 0x1000) + return false; + for (i = 7; i >= 0; i--) + if (list & (1 << i)) + { + extract_to_extended (fpu.registers[i], words); + addr -= 12; + put_long (addr, words[0]); + put_long (addr + 4, words[1]); + put_long (addr + 8, words[2]); + } + m68k_areg (regs, opcode & 7) = addr; + break; + default: + if ((extra & 0x1000) == 0) + return false; + for (i = 0; i < 8; i++) + if (list & (0x80 >> i)) + { + extract_to_extended (fpu.registers[i], words); + put_long (addr, words[0]); + put_long (addr + 4, words[1]); + put_long (addr + 8, words[2]); + addr += 12; + } + if ((opcode & 070) == 030) + m68k_areg (regs, opcode & 7) = addr; + break; + } + } + else + { + // FMOVEM from memory + + if ((opcode & 070) == 040) + return false; + + if ((extra & 0x1000) == 0) + return false; + for (i = 0; i < 8; i++) + if (list & (0x80 >> i)) + { + words[0] = get_long (addr); + words[1] = get_long (addr + 4); + words[2] = get_long (addr + 8); + addr += 12; + set_from_extended (fpu.registers[i], words, false); + } + if ((opcode & 070) == 030) + m68k_areg (regs, opcode & 7) = addr; + } + return true; +} + +static int +do_getexp (mpfr_t value, mpfr_rnd_t rnd) +{ + int t = 0; + + if (mpfr_inf_p (value)) + { + mpfr_set_nan (value); + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (!mpfr_nan_p (value) && !mpfr_zero_p (value)) + t = mpfr_set_si (value, mpfr_get_exp (value) - 1, rnd); + return t; +} + +static int +do_getman (mpfr_t value) +{ + if (mpfr_inf_p (value)) + { + mpfr_set_nan (value); + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (!mpfr_nan_p (value) && !mpfr_zero_p (value)) + mpfr_set_exp (value, 1); + return 0; +} + +static int +do_scale (mpfr_t value, mpfr_t reg, mpfr_rnd_t rnd) +{ + long scale; + int t = 0; + + if (mpfr_nan_p (value)) + ; + else if (mpfr_inf_p (value)) + { + mpfr_set_nan (value); + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (mpfr_fits_slong_p (value, rnd)) + { + scale = mpfr_get_si (value, MPFR_RNDZ); + mpfr_clear_inexflag (); + t = mpfr_mul_2si (value, reg, scale, rnd); + } + else + mpfr_set_inf (value, -mpfr_signbit (value)); + return t; +} + +static int +do_remainder (mpfr_t value, mpfr_t reg, mpfr_rnd_t rnd) +{ + long quo; + int t = 0; + + if (mpfr_nan_p (value) || mpfr_nan_p (reg)) + ; + else if (mpfr_zero_p (value) || mpfr_inf_p (reg)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_remquo (value, &quo, reg, value, rnd); + if (quo < 0) + quo = (-quo & 0x7f) | 0x80; + else + quo &= 0x7f; + fpu.fpsr.quotient = quo << 16; + return t; +} + +// Unfortunately, mpfr_fmod does not return the quotient bits, so we +// have to reimplement it here +static int +mpfr_rem1 (mpfr_t rem, int *quo, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd) +{ + mpfr_exp_t ex, ey; + int inex, sign, signx = mpfr_signbit (x); + mpz_t mx, my, r; + + mpz_init (mx); + mpz_init (my); + mpz_init (r); + + ex = mpfr_get_z_2exp (mx, x); /* x = mx*2^ex */ + ey = mpfr_get_z_2exp (my, y); /* y = my*2^ey */ + + /* to get rid of sign problems, we compute it separately: + quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y) + quo(-x,y) = -quo(x,y), rem(-x,y) = -rem(x,y) + thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */ + sign = (signx != mpfr_signbit (y)); + mpz_abs (mx, mx); + mpz_abs (my, my); + + /* divide my by 2^k if possible to make operations mod my easier */ + { + unsigned long k = mpz_scan1 (my, 0); + ey += k; + mpz_fdiv_q_2exp (my, my, k); + } + + if (ex <= ey) + { + /* q = x/y = mx/(my*2^(ey-ex)) */ + mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */ + /* 0 <= |r| <= |my|, r has the same sign as mx */ + mpz_tdiv_qr (mx, r, mx, my); + /* mx is the quotient */ + mpz_tdiv_r_2exp (mx, mx, 7); + *quo = mpz_get_si (mx); + } + else /* ex > ey */ + { + /* to get the low 7 more bits of the quotient, we first compute + R = X mod Y*2^7, where X and Y are defined below. Then the + low 7 of the quotient are floor(R/Y). */ + mpz_mul_2exp (my, my, 7); /* 2^7*Y */ + + mpz_set_ui (r, 2); + mpz_powm_ui (r, r, ex - ey, my); /* 2^(ex-ey) mod my */ + mpz_mul (r, r, mx); + mpz_mod (r, r, my); + + /* now 0 <= r < 2^7*Y */ + mpz_fdiv_q_2exp (my, my, 7); /* back to Y */ + mpz_tdiv_qr (mx, r, r, my); + /* oldr = mx*my + newr */ + *quo = mpz_get_si (mx); + + /* now 0 <= |r| < |my| */ + } + + if (mpz_cmp_ui (r, 0) == 0) + { + inex = mpfr_set_ui (rem, 0, MPFR_RNDN); + /* take into account sign of x */ + if (signx) + mpfr_neg (rem, rem, MPFR_RNDN); + } + else + { + /* take into account sign of x */ + if (signx) + mpz_neg (r, r); + inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd); + } + + if (sign) + *quo |= 0x80; + + mpz_clear (mx); + mpz_clear (my); + mpz_clear (r); + + return inex; +} + +static int +do_fmod (mpfr_t value, mpfr_t reg, mpfr_rnd_t rnd) +{ + int t = 0; + + if (mpfr_nan_p (value) || mpfr_nan_p (reg)) + mpfr_set_nan (value); + else if (mpfr_zero_p (value) || mpfr_inf_p (reg)) + { + mpfr_set_nan (value); + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (mpfr_zero_p (reg) || mpfr_inf_p (value)) + { + fpu.fpsr.quotient = 0; + t = mpfr_set (value, reg, rnd); + } + else + { + int quo; + + t = mpfr_rem1 (value, &quo, reg, value, rnd); + fpu.fpsr.quotient = quo << 16; + } + return t; +} + +static void +do_fcmp (mpfr_t source, mpfr_t dest) +{ + uae_u32 flags = 0; + + if (mpfr_nan_p (source) || mpfr_nan_p (dest)) + flags |= FPSR_CCB_NAN; + else + { + int cmp = mpfr_cmp (dest, source); + if (cmp < 0) + flags |= FPSR_CCB_NEGATIVE; + else if (cmp == 0) + { + flags |= FPSR_CCB_ZERO; + if ((mpfr_zero_p (dest) || mpfr_inf_p (dest)) && mpfr_signbit (dest)) + flags |= FPSR_CCB_NEGATIVE; + } + } + set_fpccr (flags); +} + +static void +do_ftst (mpfr_t value) +{ + uae_u32 flags = 0; + + if (mpfr_signbit (value)) + flags |= FPSR_CCB_NEGATIVE; + if (mpfr_nan_p (value)) + flags |= FPSR_CCB_NAN; + else if (mpfr_zero_p (value)) + flags |= FPSR_CCB_ZERO; + else if (mpfr_inf_p (value)) + flags |= FPSR_CCB_INFINITY; + set_fpccr (flags); +} + +static bool +fpuop_general (uae_u32 opcode, uae_u32 extra) +{ + mpfr_prec_t prec = get_cur_prec (); + mpfr_rnd_t rnd = get_cur_rnd (); + int reg = (extra >> 7) & 7; + int t = 0; + fpu_register value; + bool ret; + + mpfr_init2 (value.f, prec); + value.nan_bits = DEFAULT_NAN_BITS; + value.nan_sign = 0; + + mpfr_clear_flags (); + set_format (prec); + cur_exceptions = 0; + cur_instruction_address = m68k_getpc () - 4; + if ((extra & 0xfc00) == 0x5c00) + { + // FMOVECR + int rom_index = extra & 0x7f; + if (rom_index == 0 || (rom_index >= 11 && rom_index <= 15)) + t = mpfr_set (value.f, fpu_constant_rom[rom_index], rnd); + else if (rom_index >= 48 && rom_index <= 63) + t = mpfr_set (value.f, fpu_constant_rom[rom_index - 32], rnd); + else + mpfr_set_zero (value.f, 0); + set_fp_register (reg, value, t, rnd, true); + } + else if (extra & 0x40) + { + static const char valid[64] = + { + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 1, 1, 0, 1, 1, + 1, 0, 0, 0, 1, 0, 0, 0 + }; + + if (extra & 4) + // FD... + prec = DOUBLE_PREC; + else + // FS... + prec = SINGLE_PREC; + set_format (prec); + MPFR_DECL_INIT (value2, prec); + + if (!fpu.is_integral) + { + ret = false; + goto out; + } + if (!valid[extra & 0x3b]) + { + ret = false; + goto out; + } + if (!get_fp_value (opcode, extra, value)) + { + ret = false; + goto out; + } + + switch (extra & 0x3f) + { + case 0: // FSMOVE + case 4: // FDMOVE + mpfr_set (value2, value.f, rnd); + break; + case 1: // FSSQRT + case 5: // FDSQRT + if (mpfr_sgn (value.f) < 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_sqrt (value2, value.f, rnd); + break; + case 24: // FSABS + case 28: // FDABS + t = mpfr_abs (value2, value.f, rnd); + break; + case 26: // FSNEG + case 30: // FDNEG + t = mpfr_neg (value2, value.f, rnd); + break; + case 32: // FSDIV + case 36: // FDDIV + if (mpfr_zero_p (value.f)) + { + if (mpfr_regular_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (mpfr_zero_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (mpfr_inf_p (value.f) && mpfr_inf_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_div (value2, fpu.registers[reg].f, value.f, rnd); + break; + case 34: // FSADD + case 38: // FDADD + if (mpfr_inf_p (fpu.registers[reg].f) && mpfr_inf_p (value.f) + && mpfr_signbit (fpu.registers[reg].f) != mpfr_signbit (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_add (value2, fpu.registers[reg].f, value.f, rnd); + break; + case 35: // FSMUL + case 39: // FDMUL + if ((mpfr_zero_p (value.f) && mpfr_inf_p (fpu.registers[reg].f)) + || (mpfr_inf_p (value.f) && mpfr_zero_p (fpu.registers[reg].f))) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_mul (value2, fpu.registers[reg].f, value.f, rnd); + break; + case 40: // FSSUB + case 44: // FDSUB + if (mpfr_inf_p (fpu.registers[reg].f) && mpfr_inf_p (value.f) + && mpfr_signbit (fpu.registers[reg].f) == mpfr_signbit (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_sub (value2, fpu.registers[reg].f, value.f, rnd); + break; + } + set_fp_register (reg, value2, t, rnd, true); + } + else if ((extra & 0x30) == 0x30) + { + if ((extra & 15) > 10 || (extra & 15) == 9) + { + ret = false; + goto out; + } + if (!get_fp_value (opcode, extra, value)) + { + ret = false; + goto out; + } + + if ((extra & 15) < 8) + { + // FSINCOS + int reg2 = extra & 7; + MPFR_DECL_INIT (value2, prec); + + if (mpfr_inf_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_sin_cos (value.f, value2, value.f, rnd); + if (reg2 != reg) + set_fp_register (reg2, value2, t >> 2, rnd, false); + set_fp_register (reg, value, t & 3, rnd, true); + } + else if ((extra & 15) == 8) + // FCMP + do_fcmp (value.f, fpu.registers[reg].f); + else + // FTST + do_ftst (value.f); + } + else + { + static const char valid[64] = + { + 1, 1, 1, 1, 1, 0, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1 + }; + if (!valid[extra & 0x3f]) + { + ret = false; + goto out; + } + if (!get_fp_value (opcode, extra, value)) + { + ret = false; + goto out; + } + + switch (extra & 0x3f) + { + case 0: // FMOVE + break; + case 1: // FINT + t = mpfr_rint (value.f, value.f, rnd); + break; + case 2: // FSINH + t = mpfr_sinh (value.f, value.f, rnd); + break; + case 3: // FINTRZ + t = mpfr_rint (value.f, value.f, MPFR_RNDZ); + break; + case 4: // FSQRT + if (mpfr_sgn (value.f) < 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_sqrt (value.f, value.f, rnd); + break; + case 6: // FLOGNP1 + if (!mpfr_nan_p (value.f)) + { + int cmp = mpfr_cmp_si (value.f, -1); + if (cmp == 0) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (cmp < 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + t = mpfr_log1p (value.f, value.f, rnd); + break; + case 8: // FETOXM1 + t = mpfr_expm1 (value.f, value.f, rnd); + break; + case 9: // FTANH + t = mpfr_tanh (value.f, value.f, rnd); + break; + case 10: // FATAN + t = mpfr_atan (value.f, value.f, rnd); + break; + case 12: // FASIN + if (mpfr_cmpabs (value.f, FPU_CONSTANT_ONE) > 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_asin (value.f, value.f, rnd); + break; + case 13: // FATANH + if (mpfr_cmpabs (value.f, FPU_CONSTANT_ONE) > 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_atanh (value.f, value.f, rnd); + break; + case 14: // FSIN + if (mpfr_inf_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_sin (value.f, value.f, rnd); + break; + case 15: // FTAN + if (mpfr_inf_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_tan (value.f, value.f, rnd); + break; + case 16: // FETOX + t = mpfr_exp (value.f, value.f, rnd); + break; + case 17: // FTWOTOX + t = mpfr_ui_pow (value.f, 2, value.f, rnd); + break; + case 18: // FTENTOX + t = mpfr_ui_pow (value.f, 10, value.f, rnd); + break; + case 20: // FLOGN + if (mpfr_zero_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (mpfr_sgn (value.f) < 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_log (value.f, value.f, rnd); + break; + case 21: // FLOG10 + if (mpfr_zero_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (mpfr_sgn (value.f) < 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_log10 (value.f, value.f, rnd); + break; + case 22: // FLOG2 + if (mpfr_zero_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (mpfr_sgn (value.f) < 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_log2 (value.f, value.f, rnd); + break; + case 24: // FABS + t = mpfr_abs (value.f, value.f, rnd); + value.nan_sign = 0; + break; + case 25: // FCOSH + t = mpfr_cosh (value.f, value.f, rnd); + break; + case 26: // FNEG + t = mpfr_neg (value.f, value.f, rnd); + value.nan_sign = !value.nan_sign; + break; + case 28: // FACOS + if (mpfr_cmpabs (value.f, FPU_CONSTANT_ONE) > 0) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_acos (value.f, value.f, rnd); + break; + case 29: // FCOS + if (mpfr_inf_p (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_cos (value.f, value.f, rnd); + break; + case 30: // FGETEXP + t = do_getexp (value.f, rnd); + break; + case 31: // FGETMAN + t = do_getman (value.f); + break; + case 32: // FDIV + if (mpfr_zero_p (value.f)) + { + if (mpfr_regular_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (mpfr_zero_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (mpfr_inf_p (value.f) && mpfr_inf_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_div (value.f, fpu.registers[reg].f, value.f, rnd); + break; + case 33: // FMOD + t = do_fmod (value.f, fpu.registers[reg].f, rnd); + break; + case 34: // FADD + if (mpfr_inf_p (fpu.registers[reg].f) && mpfr_inf_p (value.f) + && mpfr_signbit (fpu.registers[reg].f) != mpfr_signbit (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_add (value.f, fpu.registers[reg].f, value.f, rnd); + break; + case 35: // FMUL + if ((mpfr_zero_p (value.f) && mpfr_inf_p (fpu.registers[reg].f)) + || (mpfr_inf_p (value.f) && mpfr_zero_p (fpu.registers[reg].f))) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_mul (value.f, fpu.registers[reg].f, value.f, rnd); + break; + case 36: // FSGLDIV + { + MPFR_DECL_INIT (value2, SINGLE_PREC); + + set_format (SINGLE_PREC); + if (mpfr_zero_p (value.f)) + { + if (mpfr_regular_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_DZ; + else if (mpfr_zero_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + } + else if (mpfr_inf_p (value.f) && mpfr_inf_p (fpu.registers[reg].f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_div (value2, fpu.registers[reg].f, value.f, rnd); + mpfr_set (value.f, value2, rnd); + } + break; + case 37: // FREM + t = do_remainder (value.f, fpu.registers[reg].f, rnd); + break; + case 38: // FSCALE + t = do_scale (value.f, fpu.registers[reg].f, rnd); + break; + case 39: // FSGLMUL + { + MPFR_DECL_INIT (value2, SINGLE_PREC); + + set_format (SINGLE_PREC); + if ((mpfr_zero_p (value.f) && mpfr_inf_p (fpu.registers[reg].f)) + || (mpfr_inf_p (value.f) && mpfr_zero_p (fpu.registers[reg].f))) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_mul (value2, fpu.registers[reg].f, value.f, rnd); + mpfr_set (value.f, value2, rnd); + } + break; + case 40: // FSUB + if (mpfr_inf_p (fpu.registers[reg].f) && mpfr_inf_p (value.f) + && mpfr_signbit (fpu.registers[reg].f) == mpfr_signbit (value.f)) + cur_exceptions |= FPSR_EXCEPTION_OPERR; + t = mpfr_sub (value.f, fpu.registers[reg].f, value.f, rnd); + break; + } + set_fp_register (reg, value, t, rnd, true); + } + update_exceptions (); + ret = true; + out: + mpfr_clear (value.f); + return ret; +} + +void +fpuop_arithmetic (uae_u32 opcode, uae_u32 extra) +{ + bool valid; + + switch ((extra >> 13) & 7) + { + case 3: + valid = fpuop_fmove_memory (opcode, extra); + break; + case 4: + case 5: + valid = fpuop_fmovem_control (opcode, extra); + break; + case 6: + case 7: + valid = fpuop_fmovem_register (opcode, extra); + break; + case 0: + case 2: + valid = fpuop_general (opcode, extra); + break; + default: + valid = false; + break; + } + + if (!valid) + { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } +} + +static bool +check_fp_cond (uae_u32 pred) +{ + uae_u32 fpcc = get_fpccr (); + + if ((pred & 16) != 0 && (fpcc & FPSR_CCB_NAN) != 0) + { + // IEEE non-aware test + set_exception_status (get_exception_status () | FPSR_EXCEPTION_BSUN); + set_accrued_exception (get_accrued_exception () | FPSR_ACCR_IOP); + } + + switch (pred & 15) + { + case 0: // F / SF + return false; + case 1: // EQ /SEQ + return (fpcc & FPSR_CCB_ZERO) != 0; + case 2: // OGT / GT + return (fpcc & (FPSR_CCB_NAN | FPSR_CCB_ZERO | FPSR_CCB_NEGATIVE)) == 0; + case 3: // OGE / GE + return (fpcc & FPSR_CCB_ZERO) != 0 || (fpcc & (FPSR_CCB_NAN | FPSR_CCB_NEGATIVE)) == 0; + case 4: // OLT / LT + return (fpcc & (FPSR_CCB_NEGATIVE | FPSR_CCB_NAN | FPSR_CCB_ZERO)) == FPSR_CCB_NEGATIVE; + case 5: // OLE / LE + return (fpcc & FPSR_CCB_ZERO) != 0 || (fpcc & (FPSR_CCB_NEGATIVE | FPSR_CCB_NAN)) == FPSR_CCB_NEGATIVE; + case 6: // OGL / GL + return (fpcc & (FPSR_CCB_NAN | FPSR_CCB_ZERO)) == 0; + case 7: // OR / GLE + return (fpcc & FPSR_CCB_NAN) == 0; + case 8: // UN / NGLE + return (fpcc & FPSR_CCB_NAN) != 0; + case 9: // UEQ / NGL + return (fpcc & (FPSR_CCB_NAN | FPSR_CCB_ZERO)) != 0; + case 10: // UGT / NLE + return (fpcc & FPSR_CCB_NAN) != 0 || (fpcc & (FPSR_CCB_NEGATIVE | FPSR_CCB_ZERO)) == 0; + case 11: // UGE / NLT + return (fpcc & (FPSR_CCB_NEGATIVE | FPSR_CCB_NAN | FPSR_CCB_ZERO)) != FPSR_CCB_NEGATIVE; + case 12: // ULT / NGE + return (fpcc & FPSR_CCB_NAN) != 0 || (fpcc & (FPSR_CCB_NEGATIVE | FPSR_CCB_ZERO)) == FPSR_CCB_NEGATIVE; + case 13: // ULE / NGT + return (fpcc & (FPSR_CCB_NAN | FPSR_CCB_ZERO | FPSR_CCB_NEGATIVE)) != 0; + case 14: // NE / SNE + return (fpcc & FPSR_CCB_ZERO) == 0; + case 15: // T / ST + return true; + default: + return false; + } +} + +void +fpuop_bcc (uae_u32 opcode, uaecptr pc, uae_u32 disp) +{ + if (check_fp_cond (opcode)) + { + if (!(opcode & (1 << 6))) + disp = (uae_s16) disp; + m68k_setpc (pc + disp); + } +} + +void +fpuop_scc (uae_u32 opcode, uae_u32 extra) +{ + uae_u32 addr; + int value = check_fp_cond (extra) ? 0xff : 0; + if ((opcode & 070) == 0) + { + int reg = opcode & 7; + m68k_dreg (regs, reg) = (m68k_dreg (regs, reg) & ~0xff) | value; + } + else if (!get_fp_addr (opcode, &addr, true)) + { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + else + { + switch (opcode & 070) + { + case 030: + m68k_areg (regs, opcode & 7) += (opcode & 7) == 7 ? 2 : 1; + break; + case 040: + addr -= (opcode & 7) == 7 ? 2 : 1; + m68k_areg (regs, opcode & 7) = addr; + } + put_byte (addr, value); + } +} + +void +fpuop_dbcc (uae_u32 opcode, uae_u32 extra) +{ + uaecptr pc = m68k_getpc (); + uae_s16 disp = next_iword (); + + if (!check_fp_cond (extra)) + { + int reg = opcode & 7; + uae_u16 cnt = (m68k_dreg (regs, reg) & 0xffff) - 1; + m68k_dreg (regs, reg) = (m68k_dreg (regs, reg) & ~0xffff) | cnt; + if (cnt != 0xffff) + m68k_setpc (pc + disp); + } +} + +void +fpuop_trapcc (uae_u32, uaecptr oldpc, uae_u32 extra) +{ + if (check_fp_cond (extra)) + Exception (7, oldpc - 2); +} + +void +fpuop_save (uae_u32 opcode) +{ + uae_u32 addr; + + if ((opcode & 070) == 030 + || !get_fp_addr (opcode, &addr, true)) + { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + + if (fpu.is_integral) + { + // 4 byte 68040 IDLE frame + // FIXME: generate proper FPU stack frames that does not result + // in undefined behaviour from FPSP040 + if ((opcode & 070) == 040) + { + addr -= 4; + m68k_areg (regs, opcode & 7) = addr; + } + put_long (addr, 0x41000000); + } + else + { + // 28 byte 68881 IDLE frame + if ((opcode & 070) == 040) + { + addr -= 28; + m68k_areg (regs, opcode & 7) = addr; + } + put_long (addr, 0x1f180000); + for (int i = 0; i < 6; i++) + { + addr += 4; + put_long (addr, 0); + } + } +} + +void +fpuop_restore (uae_u32 opcode) +{ + uae_u32 addr; + uae_u32 format; + + if ((opcode & 070) == 040 + || !get_fp_addr (opcode, &addr, false)) + { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + + format = get_long (addr); + addr += 4; + if ((format & 0xff000000) == 0) + // NULL frame + fpu_reset (); + else + addr += (format & 0xff0000) >> 16; + if ((opcode & 070) == 030) + m68k_areg (regs, opcode & 7) = addr; +} + +void fpu_set_fpsr(uae_u32 new_fpsr) +{ + set_fpsr(new_fpsr); +} + +uae_u32 fpu_get_fpsr(void) +{ + return get_fpsr(); +} + +void fpu_set_fpcr(uae_u32 new_fpcr) +{ + set_fpcr(new_fpcr); +} + +uae_u32 fpu_get_fpcr(void) +{ + return get_fpcr(); +} + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_uae.cpp b/BasiliskII/src/uae_cpu_2021/fpu/fpu_uae.cpp new file mode 100644 index 000000000..ca4b841d4 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_uae.cpp @@ -0,0 +1,2514 @@ +/* + * fpu/fpu_uae.cpp - the old UAE FPU + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * UAE - The Un*x Amiga Emulator + * + * MC68881 emulation + * + * Copyright 1996 Herman ten Brugge + * + * + * Following fixes by Lauri Pesonen, July 1999: + * + * FMOVEM list handling: + * The lookup tables did not work correctly, rewritten. + * FINT: + * (int) cast does not work, fixed. + * Further, now honors the FPU fpcr rounding modes. + * FINTRZ: + * (int) cast cannot be used, fixed. + * FGETEXP: + * Input argument value 0 returned erroneous value. + * FMOD: + * (int) cast cannot be used. Replaced by proper rounding. + * Quotient byte handling was missing. + * FREM: + * (int) cast cannot be used. Replaced by proper rounding. + * Quotient byte handling was missing. + * FSCALE: + * Input argument value 0 was not handled correctly. + * FMOVEM Control Registers to/from address FPU registers An: + * A bug caused the code never been called. + * FMOVEM Control Registers pre-decrement: + * Moving of control regs from memory to FPP was not handled properly, + * if not all of the three FPU registers were moved. + * Condition code "Not Greater Than or Equal": + * Returned erroneous value. + * FSINCOS: + * Cosine must be loaded first if same register. + * FMOVECR: + * Status register was not updated (yes, this affects it). + * FMOVE -> reg: + * Status register was not updated (yes, this affects it). + * FMOVE reg -> reg: + * Status register was not updated. + * FDBcc: + * The loop termination condition was wrong. + * Possible leak from int16 to int32 fixed. + * get_fp_value: + * Immediate addressing mode && Operation Length == Byte -> + * Use the low-order byte of the extension word. + * Now FPU fpcr high 16 bits are always read as zeroes, no matter what was + * written to them. + * + * Other: + * - Optimized single/double/extended to/from conversion functions. + * Huge speed boost, but not (necessarily) portable to other systems. + * Enabled/disabled by #define FPU_HAVE_IEEE_DOUBLE 1 + * - Optimized versions of FSCALE, FGETEXP, FGETMAN + * - Conversion routines now handle NaN and infinity better. + * - Some constants precalculated. Not all compilers can optimize the + * expressions previously used. + * + * TODO: + * - Floating point exceptions. + * - More Infinity/NaN/overflow/underflow checking. + * - FPU instruction_address (only needed when exceptions are implemented) + * - Should be written in assembly to support long doubles. + * - Precision rounding single/double + */ + + +#include "sysdeps.h" +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#include "main.h" +#define FPU_IMPLEMENTATION +#include "fpu/fpu.h" +#include "fpu/fpu_uae.h" + +#ifdef HAVE_NEW_HEADERS +#define _GLIBCPP_USE_C99 1 +# include +# include +using namespace __gnu_cxx; +#undef _GLIBCPP_USE_C99 +#else +# include +# include +#endif + +/* Global FPU context */ +fpu_t fpu; + +/* -------------------------------------------------------------------------- */ +/* --- Native Support --- */ +/* -------------------------------------------------------------------------- */ + +#include "fpu/flags.h" +#include "fpu/exceptions.h" +#include "fpu/rounding.h" +#include "fpu/impl.h" + +#include "fpu/flags.cpp" +#include "fpu/exceptions.cpp" + +/* -------------------------------------------------------------------------- */ +/* --- Scopes Definition --- */ +/* -------------------------------------------------------------------------- */ + +#undef PUBLIC +#define PUBLIC /**/ + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* -------------------------------------------------------------------------- */ +/* --- Debugging --- */ +/* -------------------------------------------------------------------------- */ + +PUBLIC void FFPU fpu_dump_registers(void) +{ + for (int i = 0; i < 8; i++){ + printf ("FP%d: %g ", i, fpu_get_register(i)); + if ((i & 3) == 3) + printf ("\n"); + } +} + +PUBLIC void FFPU fpu_dump_flags(void) +{ + printf ("N=%d Z=%d I=%d NAN=%d\n", + (get_fpsr() & FPSR_CCB_NEGATIVE) != 0, + (get_fpsr() & FPSR_CCB_ZERO)!= 0, + (get_fpsr() & FPSR_CCB_INFINITY) != 0, + (get_fpsr() & FPSR_CCB_NAN) != 0); +} + +/* single : S 8*E 23*F */ +/* double : S 11*E 52*F */ +/* extended : S 15*E 64*F */ +/* E = 0 & F = 0 -> 0 */ +/* E = MAX & F = 0 -> Infin */ +/* E = MAX & F # 0 -> NotANumber */ +/* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */ + +#if FPU_DEBUG + +PUBLIC void FFPU dump_registers(const char * str) +{ + char temp_str[512]; + + sprintf(temp_str, "%s: %.04f, %.04f, %.04f, %.04f, %.04f, %.04f, %.04f, %.04f\n", + str, + fpu_get_register(0), fpu_get_register(1), fpu_get_register(2), fpu_get_register(3), + fpu_get_register(4), fpu_get_register(5), fpu_get_register(6), fpu_get_register(7) ); + + fpu_debug((temp_str)); +} + +PUBLIC void FFPU dump_first_bytes(uae_u8 * buffer, uae_s32 actual) +{ + char temp_buf1[256], temp_buf2[10]; + int bytes = sizeof(temp_buf1)/3-1-3; + if (actual < bytes) + bytes = actual; + + temp_buf1[0] = 0; + for (int i = 0; i < bytes; i++) { + sprintf(temp_buf2, "%02x ", (uae_u32)buffer[i]); + strcat(temp_buf1, temp_buf2); + } + + strcat(temp_buf1, "\n"); + fpu_debug((temp_buf1)); +} + +#else + +PUBLIC void FFPU dump_registers(const char *) +{ +} + +#define dump_first_bytes(a,b) + +#endif + +PRIVATE inline fpu_register FFPU round_to_zero(fpu_register const & x) +{ + return (x < 0.0 ? ceil(x) : floor(x)); +} + +PRIVATE inline fpu_register FFPU round_to_nearest(fpu_register const & x) +{ + return floor(x + 0.5); +} + +#if FPU_HAVE_IEEE_DOUBLE + +#ifndef HAVE_ISNAN +#define isnan(x) do_isnan((x)) +#endif + +PRIVATE inline bool FFPU do_isnan(fpu_register const & r) +{ + fpu_register_parts const p = { r }; + if ((p.parts[FHI] & 0x7FF00000) == 0x7FF00000) { + // logical or is faster here. + if ((p.parts[FHI] & 0x000FFFFF) || p.parts[FLO]) { + return true; + } + } + return false; +} + +#ifndef HAVE_ISINF +#define isinf(x) do_isinf((x)) +#endif + +PRIVATE inline bool FFPU do_isinf(fpu_register const & r) +{ + fpu_register_parts const p = { r }; + if ((p.parts[FHI] & 0x7FF00000) == 0x7FF00000 && p.parts[FLO] == 0) { + return true; + } + return false; +} + +#ifndef HAVE_ISNEG +#define isneg(x) do_isneg((x)) +#endif + +PRIVATE inline bool FFPU do_isneg(fpu_register const & r) +{ + fpu_register_parts const p = { r }; + return ((p.parts[FHI] & 0x80000000) != 0); +} + +#ifndef HAVE_ISZERO +#define iszero(x) do_iszero((x)) +#endif + +PRIVATE inline bool FFPU do_iszero(fpu_register const & r) +{ + fpu_register_parts const p = { r }; + return (((p.parts[FHI] & 0x7FF00000) == 0) && p.parts[FLO] == 0); +} + +// May be optimized for particular processors +#ifndef FPU_USE_NATIVE_FLAGS +PRIVATE inline void FFPU make_fpsr(fpu_register const & r) +{ + FPU fpsr.condition_codes + = (iszero(r) ? NATIVE_FFLAG_ZERO : 0) + | (isneg(r) ? NATIVE_FFLAG_NEGATIVE : 0) + | (isnan(r) ? NATIVE_FFLAG_NAN : 0) + | (isinf(r) ? NATIVE_FFLAG_INFINITY : 0) + ; +} +#endif + +PRIVATE inline void FFPU get_dest_flags(fpu_register const & r) +{ + fl_dest.negative = isneg(r); + fl_dest.zero = iszero(r); + fl_dest.infinity = isinf(r); + fl_dest.nan = isnan(r); + fl_dest.in_range = !fl_dest.zero && !fl_dest.infinity && !fl_dest.nan; +} + +PRIVATE inline void FFPU get_source_flags(fpu_register const & r) +{ + fl_source.negative = isneg(r); + fl_source.zero = iszero(r); + fl_source.infinity = isinf(r); + fl_source.nan = isnan(r); + fl_source.in_range = !fl_source.zero && !fl_source.infinity && !fl_source.nan; +} + +PRIVATE inline void FFPU make_nan(fpu_register & r, bool negative) +{ + fpu_register_parts p; + p.parts[FLO] = 0xffffffff; + p.parts[FHI] = negative ? 0xffffffff : 0x7fffffff; + r = p.val; +} + +PRIVATE inline void FFPU make_zero(fpu_register & r, bool negative) +{ + fpu_register_parts p; + p.parts[FLO] = 0; + p.parts[FHI] = negative ? 0x80000000 : 0; + r = p.val; +} + +PRIVATE inline void FFPU make_inf(fpu_register & r, bool negative) +{ + fpu_register_parts p; + p.parts[FLO] = 0; + p.parts[FHI] = negative ? 0xFFF00000 : 0x7FF00000; + r = p.val; +} + +PRIVATE inline void FFPU fast_scale(fpu_register & r, int add) +{ + fpu_register_parts p = { r }; + int exp = (p.parts[FHI] & 0x7FF00000) >> 20; + // TODO: overflow flags + exp += add; + if(exp >= 2047) { + make_inf(r, false); + return; + } else if(exp < 0) { + // keep sign (+/- 0) + p.parts[FHI] &= 0x80000000; + } else { + p.parts[FHI] = (p.parts[FHI] & 0x800FFFFF) | ((uae_u32)exp << 20); + } + r = p.val; +} + +PRIVATE inline fpu_register FFPU fast_fgetexp(fpu_register const & r) +{ + fpu_register_parts const p = { r }; + int exp = (p.parts[FHI] & 0x7FF00000) >> 20; + return( exp - 1023 ); +} + +// Normalize to range 1..2 +PRIVATE inline void FFPU fast_remove_exponent(fpu_register & r) +{ + fpu_register_parts p = { r }; + p.parts[FHI] = (p.parts[FHI] & 0x800FFFFF) | 0x3FF00000; + r = p.val; +} + +// The sign of the quotient is the exclusive-OR of the sign bits +// of the source and destination operands. +PRIVATE inline uae_u32 FFPU get_quotient_sign(fpu_register const & ra, fpu_register const & rb) +{ + fpu_register_parts const a = { ra }; + fpu_register_parts const b = { rb }; + return (((a.parts[FHI] ^ b.parts[FHI]) & 0x80000000) ? FPSR_QUOTIENT_SIGN : 0); +} + +// Quotient Byte is loaded with the sign and least significant +// seven bits of the quotient. +PRIVATE inline void FFPU make_quotient(fpu_register const & quotient, uae_u32 sign) +{ + uae_u32 lsb = (uae_u32)fabs(quotient) & 0x7f; + FPU fpsr.quotient = sign | (lsb << 16); +} + +// to_single +PRIVATE inline fpu_register FFPU make_single(uae_u32 value) +{ + if ((value & 0x7fffffff) == 0) + return (0.0); + + fpu_register result; + fpu_register_parts p; + + uae_u32 sign = (value & 0x80000000); + uae_u32 exp = ((value & 0x7F800000) >> 23) + 1023 - 127; + + p.parts[FLO] = value << 29; + p.parts[FHI] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3); + + result = p.val; + + fpu_debug(("make_single (%X) = %.04f\n",value,(double)result)); + + return(result); +} + +// from_single +PRIVATE inline uae_u32 FFPU extract_single(fpu_register const & src) +{ + if (src == 0.0) + return 0; + + uae_u32 result; + fpu_register_parts const p = { src }; + + uae_u32 sign = (p.parts[FHI] & 0x80000000); + uae_u32 exp = (p.parts[FHI] & 0x7FF00000) >> 20; + + if(exp + 127 < 1023) { + exp = 0; + } else if(exp > 1023 + 127) { + exp = 255; + } else { + exp = exp + 127 - 1023; + } + + result = sign | (exp << 23) | ((p.parts[FHI] & 0x000FFFFF) << 3) | (p.parts[FLO] >> 29); + + fpu_debug(("extract_single (%.04f) = %X\n",(double)src,result)); + + return (result); +} + +// to_exten +PRIVATE inline fpu_register FFPU make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +{ + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) + return 0.0; + + fpu_register result; + fpu_register_parts p; + + uae_u32 sign = wrd1 & 0x80000000; + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + + // The explicit integer bit is not set, must normalize. + if((wrd2 & 0x80000000) == 0) { + fpu_debug(("make_extended denormalized mantissa (%X,%X,%X)\n",wrd1,wrd2,wrd3)); + if( wrd2 | wrd3 ) { + // mantissa, not fraction. + uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; + while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) { + man <<= 1; + exp--; + } + wrd2 = (uae_u32)( man >> 32 ); + wrd3 = (uae_u32)( man & 0xFFFFFFFF ); + } else { + if(exp == 0x7FFF) { + // Infinity. + } else { + // Zero + exp = 16383 - 1023; + } + } + } + + if(exp < 16383 - 1023) { + // should set underflow. + exp = 0; + } else if(exp > 16383 + 1023) { + // should set overflow. + exp = 2047; + } else { + exp = exp + 1023 - 16383; + } + + // drop the explicit integer bit. + p.parts[FLO] = (wrd2 << 21) | (wrd3 >> 11); + p.parts[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11); + + result = p.val; + + fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); + + return(result); +} + +/* + Would be so much easier with full size floats :( + ... this is so vague. +*/ +// make_extended_no_normalize +PRIVATE inline void FFPU make_extended_no_normalize( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result +) +{ + // Is it zero? + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) { + make_zero(result, false); + return; + } + + // Is it NaN? + if( (wrd1 & 0x7FFF0000) == 0x7FFF0000 ) { + if( (wrd1 & 0x0000FFFF) || wrd2 || wrd3 ) { + make_nan(result, (wrd1 & 0x80000000) != 0); + return; + } + } + + uae_u32 sign = wrd1 & 0x80000000; + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + + if(exp < 16383 - 1023) { + // should set underflow. + exp = 0; + } else if(exp > 16383 + 1023) { + // should set overflow. + exp = 2047; + } else { + exp = exp + 1023 - 16383; + } + + // drop the explicit integer bit. + fpu_register_parts p; + p.parts[FLO] = (wrd2 << 21) | (wrd3 >> 11); + p.parts[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11); + + result = p.val; + + fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); +} + +// from_exten +PRIVATE inline void FFPU extract_extended(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +) +{ + if (src == 0.0) { + *wrd1 = *wrd2 = *wrd3 = 0; + return; + } + + fpu_register_parts const p = { src }; + + fpu_debug(("extract_extended (%X,%X)\n",p.parts[FLO],p.parts[FHI])); + + uae_u32 sign = p.parts[FHI] & 0x80000000; + + uae_u32 exp = ((p.parts[FHI] >> 20) & 0x7ff); + // Check for maximum + if(exp == 0x7FF) { + exp = 0x7FFF; + } else { + exp += 16383 - 1023; + } + + *wrd1 = sign | (exp << 16); + // always set the explicit integer bit. + *wrd2 = 0x80000000 | ((p.parts[FHI] & 0x000FFFFF) << 11) | ((p.parts[FLO] & 0xFFE00000) >> 21); + *wrd3 = p.parts[FLO] << 11; + + fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); +} + +// to_double +PRIVATE inline fpu_register FFPU make_double(uae_u32 wrd1, uae_u32 wrd2) +{ + if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) + return 0.0; + + fpu_register result; + fpu_register_parts p; + p.parts[FLO] = wrd2; + p.parts[FHI] = wrd1; + + result = p.val; + + fpu_debug(("make_double (%X,%X) = %.04f\n",wrd1,wrd2,(double)result)); + + return(result); +} + +// from_double +PRIVATE inline void FFPU extract_double(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2 +) +{ +/* + if (src == 0.0) { + *wrd1 = *wrd2 = 0; + return; + } +*/ + fpu_register_parts const p = { src }; + *wrd2 = p.parts[FLO]; + *wrd1 = p.parts[FHI]; + + fpu_debug(("extract_double (%.04f) = %X,%X\n",(double)src,*wrd1,*wrd2)); +} + +#else // !FPU_HAVE_IEEE_DOUBLE + +#ifndef FPU_USE_NATIVE_FLAGS +PRIVATE inline void FFPU make_fpsr(fpu_register const & r) +{ + FPU fpsr.condition_codes + = (iszero(r) ? NATIVE_FFLAG_ZERO : 0) + | (isneg(r) ? NATIVE_FFLAG_NEGATIVE : 0) + ; +} +#endif + +// make_single +PRIVATE inline fpu_register FFPU make_single(uae_u32 value) +{ + if ((value & 0x7fffffff) == 0) + return (0.0); + + fpu_register frac = (fpu_register) ((value & 0x7fffff) | 0x800000) / 8388608.0; + if (value & 0x80000000) + frac = -frac; + + fpu_register result = ldexp (frac, (int)((value >> 23) & 0xff) - 127); + fpu_debug(("make_single (%X) = %.04f\n",value,(double)result)); + + return (result); +} + +// extract_single +PRIVATE inline uae_u32 FFPU extract_single(fpu_register const & src) +{ + int expon; + uae_u32 tmp, result; + fpu_register frac; +#if FPU_DEBUG + fpu_register src0 = src; +#endif + + if (src == 0.0) + return 0; + if (src < 0) { + tmp = 0x80000000; + src = -src; + } else { + tmp = 0; + } + frac = frexp (src, &expon); + frac += 0.5 / 16777216.0; + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + result = tmp | (((expon + 127 - 1) & 0xff) << 23) | (((int) (frac * 16777216.0)) & 0x7fffff); + + // fpu_debug(("extract_single (%.04f) = %X\n",(float)src0,result)); + + return (result); +} + +// to exten +PRIVATE inline fpu_register FFPU make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +{ + fpu_register frac, result; + + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) + return 0.0; + frac = (fpu_register) wrd2 / 2147483648.0 + + (fpu_register) wrd3 / 9223372036854775808.0; + if (wrd1 & 0x80000000) + frac = -frac; + result = ldexp (frac, (int)((wrd1 >> 16) & 0x7fff) - 16383); + + fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); + + return result; +} + +// extract_extended +PRIVATE inline void FFPU extract_extended(fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) +{ + int expon; + fpu_register frac; +#if FPU_DEBUG + fpu_register src0 = src; +#endif + + if (src == 0.0) { + *wrd1 = 0; + *wrd2 = 0; + *wrd3 = 0; + return; + } + if (src < 0) { + *wrd1 = 0x80000000; + src = -src; + } else { + *wrd1 = 0; + } + frac = frexp (src, &expon); + frac += 0.5 / 18446744073709551616.0; + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); + *wrd2 = (uae_u32) (frac * 4294967296.0); + *wrd3 = (uae_u32) (frac * 18446744073709551616.0 - *wrd2 * 4294967296.0); + + // fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(float)src0,*wrd1,*wrd2,*wrd3)); +} + +// make_double +PRIVATE inline fpu_register FFPU make_double(uae_u32 wrd1, uae_u32 wrd2) +{ + if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) + return 0.0; + + fpu_register frac = + (fpu_register) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 + + (fpu_register) wrd2 / 4503599627370496.0; + + if (wrd1 & 0x80000000) + frac = -frac; + + fpu_register result = ldexp (frac, (int)((wrd1 >> 20) & 0x7ff) - 1023); + fpu_debug(("make_double (%X,%X) = %.04f\n",wrd1,wrd2,(double)result)); + + return result; +} + +// extract_double +PRIVATE inline void FFPU extract_double(fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2) +{ + int expon; + int tmp; + fpu_register frac frac; +#if FPU_DEBUG + fpu_register src0 = src; +#endif + + if (src == 0.0) { + *wrd1 = 0; + *wrd2 = 0; + return; + } + if (src < 0) { + *wrd1 = 0x80000000; + src = -src; + } else { + *wrd1 = 0; + } + frac = frexp (src, &expon); + frac += 0.5 / 9007199254740992.0; + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + tmp = (uae_u32) (frac * 2097152.0); + *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff); + *wrd2 = (uae_u32) (frac * 9007199254740992.0 - tmp * 4294967296.0); + + // fpu_debug(("extract_double (%.04f) = %X,%X\n",(float)src0,*wrd1,*wrd2)); +} + +#endif + +// to_pack +PRIVATE inline fpu_register FFPU make_packed(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +{ + fpu_double d; + char *cp; + char str[100]; + + cp = str; + if (wrd1 & 0x80000000) + *cp++ = '-'; + *cp++ = (char)((wrd1 & 0xf) + '0'); + *cp++ = '.'; + *cp++ = (char)(((wrd2 >> 28) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 24) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 20) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 16) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 12) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 8) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 4) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 0) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 28) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 24) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 20) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 16) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 12) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 8) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 4) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 0) & 0xf) + '0'); + *cp++ = 'E'; + if (wrd1 & 0x40000000) + *cp++ = '-'; + *cp++ = (char)(((wrd1 >> 24) & 0xf) + '0'); + *cp++ = (char)(((wrd1 >> 20) & 0xf) + '0'); + *cp++ = (char)(((wrd1 >> 16) & 0xf) + '0'); + *cp = 0; + sscanf(str, "%le", &d); + + fpu_debug(("make_packed str = %s\n",str)); + + fpu_debug(("make_packed(%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)d)); + return d; +} + +// from_pack +PRIVATE inline void FFPU extract_packed(fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) +{ + int i; + int t; + char *cp; + char str[100]; + + sprintf(str, "%.16e", src); + + fpu_debug(("extract_packed(%.04f,%s)\n",(double)src,str)); + + cp = str; + *wrd1 = *wrd2 = *wrd3 = 0; + if (*cp == '-') { + cp++; + *wrd1 = 0x80000000; + } + if (*cp == '+') + cp++; + *wrd1 |= (*cp++ - '0'); + if (*cp == '.') + cp++; + for (i = 0; i < 8; i++) { + *wrd2 <<= 4; + if (*cp >= '0' && *cp <= '9') + *wrd2 |= *cp++ - '0'; + } + for (i = 0; i < 8; i++) { + *wrd3 <<= 4; + if (*cp >= '0' && *cp <= '9') + *wrd3 |= *cp++ - '0'; + } + if (*cp == 'e' || *cp == 'E') { + cp++; + if (*cp == '-') { + cp++; + *wrd1 |= 0x40000000; + } + if (*cp == '+') + cp++; + t = 0; + for (i = 0; i < 3; i++) { + if (*cp >= '0' && *cp <= '9') + t = (t << 4) | (*cp++ - '0'); + } + *wrd1 |= t << 16; + } + + fpu_debug(("extract_packed(%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); +} + +PRIVATE inline int FFPU get_fp_value (uae_u32 opcode, uae_u16 extra, fpu_register & src) +{ + uaecptr tmppc; + uae_u16 tmp; + int size; + int mode; + int reg; + uae_u32 ad = 0; + static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + // fpu_debug(("get_fp_value(%X,%X)\n",(int)opcode,(int)extra)); + // dump_first_bytes( regs.pc_p-4, 16 ); + + if ((extra & 0x4000) == 0) { + src = FPU registers[(extra >> 10) & 7]; + return 1; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + + fpu_debug(("get_fp_value mode=%d, reg=%d, size=%d\n",(int)mode,(int)reg,(int)size)); + + switch (mode) { + case 0: + switch (size) { + case 6: + src = (fpu_register) (uae_s8) m68k_dreg (regs, reg); + break; + case 4: + src = (fpu_register) (uae_s16) m68k_dreg (regs, reg); + break; + case 0: + src = (fpu_register) (uae_s32) m68k_dreg (regs, reg); + break; + case 1: + src = make_single(m68k_dreg (regs, reg)); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + break; + case 4: + ad = m68k_areg (regs, reg) - (reg == 7 ? sz2[size] : sz1[size]); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; + case 2: + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + fpu_debug(("get_fp_value next_iword()=%X\n",ad-m68k_getpc()-2)); + break; + case 3: + tmppc = m68k_getpc (); + tmp = (uae_u16)next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + break; + case 4: + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + // Immediate addressing mode && Operation Length == Byte -> + // Use the low-order byte of the extension word. + if(size == 6) ad++; + break; + default: + return 0; + } + } + + fpu_debug(("get_fp_value m68k_getpc()=%X\n",m68k_getpc())); + fpu_debug(("get_fp_value ad=%X\n",ad)); + fpu_debug(("get_fp_value get_long (ad)=%X\n",get_long (ad))); + dump_first_bytes( get_real_address(ad, 0, 0)-64, 64 ); + dump_first_bytes( get_real_address(ad, 0, 0), 64 ); + + switch (size) { + case 0: + src = (fpu_register) (uae_s32) get_long (ad); + break; + case 1: + src = make_single(get_long (ad)); + break; + case 2: { + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + src = make_extended(wrd1, wrd2, wrd3); + break; + } + case 3: { + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + src = make_packed(wrd1, wrd2, wrd3); + break; + } + case 4: + src = (fpu_register) (uae_s16) get_word(ad); + break; + case 5: { + uae_u32 wrd1, wrd2; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + src = make_double(wrd1, wrd2); + break; + } + case 6: + src = (fpu_register) (uae_s8) get_byte(ad); + break; + default: + return 0; + } + + switch (mode) { + case 3: + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + break; + } + + // fpu_debug(("get_fp_value result = %.04f\n",(float)src)); + return 1; +} + +PRIVATE inline int FFPU put_fp_value (uae_u32 opcode, uae_u16 extra, fpu_register const & value) +{ + uae_u16 tmp; + uaecptr tmppc; + int size; + int mode; + int reg; + uae_u32 ad; + static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + // fpu_debug(("put_fp_value(%.04f,%X,%X)\n",(float)value,(int)opcode,(int)extra)); + + if ((extra & 0x4000) == 0) { + int dest_reg = (extra >> 10) & 7; + FPU registers[dest_reg] = value; + make_fpsr(FPU registers[dest_reg]); + return 1; + } + mode = (opcode >> 3) & 7; + reg = opcode & 7; + size = (extra >> 10) & 7; + ad = 0xffffffff; + switch (mode) { + case 0: + switch (size) { + case 6: + m68k_dreg (regs, reg) + = (((uae_s32) value & 0xff) + | (m68k_dreg (regs, reg) & ~0xff)); + break; + case 4: + m68k_dreg (regs, reg) + = (((uae_s32) value & 0xffff) + | (m68k_dreg (regs, reg) & ~0xffff)); + break; + case 0: + m68k_dreg (regs, reg) = (uae_s32) value; + break; + case 1: + m68k_dreg (regs, reg) = extract_single(value); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + ad = m68k_areg (regs, reg); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; + case 2: + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: + tmppc = m68k_getpc (); + tmp = (uae_u16)next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + break; + case 4: + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + break; + default: + return 0; + } + } + switch (size) { + case 0: + put_long (ad, (uae_s32) value); + break; + case 1: + put_long (ad, extract_single(value)); + break; + case 2: { + uae_u32 wrd1, wrd2, wrd3; + extract_extended(value, &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + break; + } + case 3: { + uae_u32 wrd1, wrd2, wrd3; + extract_packed(value, &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + break; + } + case 4: + put_word(ad, (uae_s16) value); + break; + case 5: { + uae_u32 wrd1, wrd2; + extract_double(value, &wrd1, &wrd2); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + break; + } + case 6: + put_byte(ad, (uae_s8) value); + break; + default: + return 0; + } + return 1; +} + +PRIVATE inline int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) +{ + uae_u16 tmp; + uaecptr tmppc; + int mode; + int reg; + + mode = (opcode >> 3) & 7; + reg = opcode & 7; + switch (mode) { + case 0: + case 1: + return 0; + case 2: + *ad = m68k_areg (regs, reg); + break; + case 3: + *ad = m68k_areg (regs, reg); + break; + case 4: + *ad = m68k_areg (regs, reg); + break; + case 5: + *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch (reg) { + case 0: + *ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + *ad = next_ilong(); + break; + case 2: + *ad = m68k_getpc (); + *ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: + tmppc = m68k_getpc (); + tmp = (uae_u16)next_iword(); + *ad = get_disp_ea_020 (tmppc, tmp); + break; + default: + return 0; + } + } + return 1; +} + +#if FPU_DEBUG +# define CONDRET(s,x) fpu_debug(("fpp_cond %s = %d\n",s,(uint32)(x))); return (x) +#else +# define CONDRET(s,x) return (x) +#endif + +PRIVATE inline int FFPU fpp_cond(int condition) +{ +#if 1 +# define N ((FPU fpsr.condition_codes & NATIVE_FFLAG_NEGATIVE) == NATIVE_FFLAG_NEGATIVE) +# define Z ((FPU fpsr.condition_codes & NATIVE_FFLAG_ZERO) == NATIVE_FFLAG_ZERO) +# define I ((FPU fpsr.condition_codes & NATIVE_FFLAG_INFINITY) == NATIVE_FFLAG_INFINITY) +# define NaN ((FPU fpsr.condition_codes & NATIVE_FFLAG_NAN) == NATIVE_FFLAG_NAN) +#else +# define N ((FPU fpsr.condition_codes & NATIVE_FFLAG_NEGATIVE) != 0) +# define Z ((FPU fpsr.condition_codes & NATIVE_FFLAG_ZERO) != 0) +# define I ((FPU fpsr.condition_codes & NATIVE_FFLAG_INFINITY) != 0) +# define NaN ((FPU fpsr.condition_codes & NATIVE_FFLAG_NAN) != 0) +#endif + +#if 0 + return fpcctrue(condition); +#else + switch (condition & 0x1f) { + case 0x00: CONDRET("False",0); + case 0x01: CONDRET("Equal",Z); + case 0x02: CONDRET("Ordered Greater Than",!(NaN || Z || N)); + case 0x03: CONDRET("Ordered Greater Than or Equal",Z || !(NaN || N)); + case 0x04: CONDRET("Ordered Less Than",N && !(NaN || Z)); + case 0x05: CONDRET("Ordered Less Than or Equal",Z || (N && !NaN)); + case 0x06: CONDRET("Ordered Greater or Less Than",!(NaN || Z)); + case 0x07: CONDRET("Ordered",!NaN); + case 0x08: CONDRET("Unordered",NaN); + case 0x09: CONDRET("Unordered or Equal",NaN || Z); + case 0x0a: CONDRET("Unordered or Greater Than",NaN || !(N || Z)); + case 0x0b: CONDRET("Unordered or Greater or Equal",NaN || Z || !N); + case 0x0c: CONDRET("Unordered or Less Than",NaN || (N && !Z)); + case 0x0d: CONDRET("Unordered or Less or Equal",NaN || Z || N); + case 0x0e: CONDRET("Not Equal",!Z); + case 0x0f: CONDRET("True",1); + case 0x10: CONDRET("Signaling False",0); + case 0x11: CONDRET("Signaling Equal",Z); + case 0x12: CONDRET("Greater Than",!(NaN || Z || N)); + case 0x13: CONDRET("Greater Than or Equal",Z || !(NaN || N)); + case 0x14: CONDRET("Less Than",N && !(NaN || Z)); + case 0x15: CONDRET("Less Than or Equal",Z || (N && !NaN)); + case 0x16: CONDRET("Greater or Less Than",!(NaN || Z)); + case 0x17: CONDRET("Greater, Less or Equal",!NaN); + case 0x18: CONDRET("Not Greater, Less or Equal",NaN); + case 0x19: CONDRET("Not Greater or Less Than",NaN || Z); + case 0x1a: CONDRET("Not Less Than or Equal",NaN || !(N || Z)); + case 0x1b: CONDRET("Not Less Than",NaN || Z || !N); + case 0x1c: CONDRET("Not Greater Than or Equal", NaN || (N && !Z)); +// case 0x1c: CONDRET("Not Greater Than or Equal",!Z && (NaN || N)); + case 0x1d: CONDRET("Not Greater Than",NaN || Z || N); + case 0x1e: CONDRET("Signaling Not Equal",!Z); + case 0x1f: CONDRET("Signaling True",1); + default: CONDRET("",-1); + } +#endif + +# undef N +# undef Z +# undef I +# undef NaN +} + +void FFPU fpuop_dbcc(uae_u32 opcode, uae_u32 extra) +{ + fpu_debug(("fdbcc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + uaecptr pc = (uae_u32) m68k_getpc (); + uae_s32 disp = (uae_s32) (uae_s16) next_iword(); + int cc = fpp_cond(extra & 0x3f); + if (cc == -1) { + m68k_setpc (pc - 4); + op_illg (opcode); + } else if (!cc) { + int reg = opcode & 0x7; + + // this may have leaked. + /* + m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & ~0xffff) + | ((m68k_dreg (regs, reg) - 1) & 0xffff)); + */ + m68k_dreg (regs, reg) = ((m68k_dreg (regs, reg) & 0xffff0000) + | (((m68k_dreg (regs, reg) & 0xffff) - 1) & 0xffff)); + + + // condition reversed. + // if ((m68k_dreg (regs, reg) & 0xffff) == 0xffff) + if ((m68k_dreg (regs, reg) & 0xffff) != 0xffff) + m68k_setpc (pc + disp); + } +} + +void FFPU fpuop_scc(uae_u32 opcode, uae_u32 extra) +{ + fpu_debug(("fscc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + uae_u32 ad; + int cc = fpp_cond(extra & 0x3f); + if (cc == -1) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + else if ((opcode & 0x38) == 0) { + m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | + (cc ? 0xff : 0x00); + } + else if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + else + put_byte(ad, cc ? 0xff : 0x00); +} + +void FFPU fpuop_trapcc(uae_u32 opcode, uaecptr oldpc, uae_u32 extra) +{ + fpu_debug(("ftrapcc_opp %X, %X at %08lx\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + int cc = fpp_cond(extra & 0x3f); + if (cc == -1) { + m68k_setpc (oldpc); + op_illg (opcode); + } + if (cc) + Exception(7, oldpc - 2); +} + +// NOTE that we get here also when there is a FNOP (nontrapping false, displ 0) +void FFPU fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) +{ + fpu_debug(("fbcc_opp %X, %X at %08lx, jumpto=%X\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra )); + + int cc = fpp_cond(opcode & 0x3f); + if (cc == -1) { + m68k_setpc (pc); + op_illg (opcode); + } + else if (cc) { + if ((opcode & 0x40) == 0) + extra = (uae_s32) (uae_s16) extra; + m68k_setpc (pc + extra); + } +} + +// FSAVE has no post-increment +// 0x1f180000 == IDLE state frame, coprocessor version number 1F +void FFPU fpuop_save(uae_u32 opcode) +{ + fpu_debug(("fsave_opp at %08lx\n", m68k_getpc ())); + + uae_u32 ad; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + int i; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + + if (CPUType == 4) { + // Put 4 byte 68040 IDLE frame. + if (incr < 0) { + ad -= 4; + put_long (ad, 0x41000000); + } + else { + put_long (ad, 0x41000000); + ad += 4; + } + } else { + // Put 28 byte 68881 IDLE frame. + if (incr < 0) { + fpu_debug(("fsave_opp pre-decrement\n")); + ad -= 4; + // What's this? Some BIU flags, or (incorrectly placed) command/condition? + put_long (ad, 0x70000000); + for (i = 0; i < 5; i++) { + ad -= 4; + put_long (ad, 0x00000000); + } + ad -= 4; + put_long (ad, 0x1f180000); // IDLE, vers 1f + } + else { + put_long (ad, 0x1f180000); // IDLE, vers 1f + ad += 4; + for (i = 0; i < 5; i++) { + put_long (ad, 0x00000000); + ad += 4; + } + // What's this? Some BIU flags, or (incorrectly placed) command/condition? + put_long (ad, 0x70000000); + ad += 4; + } + } + if ((opcode & 0x38) == 0x18) { + m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 + fpu_debug(("PROBLEM: fsave_opp post-increment\n")); + } + if ((opcode & 0x38) == 0x20) { + m68k_areg (regs, opcode & 7) = ad; + fpu_debug(("fsave_opp pre-decrement %X -> A%d\n",ad,opcode & 7)); + } +} + +// FRESTORE has no pre-decrement +void FFPU fpuop_restore(uae_u32 opcode) +{ + fpu_debug(("frestore_opp at %08lx\n", m68k_getpc ())); + + uae_u32 ad; + uae_u32 d; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 2); + op_illg (opcode); + return; + } + + if (CPUType == 4) { + // 68040 + if (incr < 0) { + fpu_debug(("PROBLEM: frestore_opp incr < 0\n")); + // this may be wrong, but it's never called. + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) != 0) { // Not a NULL frame? + if ((d & 0x00ff0000) == 0) { // IDLE + fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); + } + else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP + fpu_debug(("PROBLEM: frestore_opp found UNIMP frame at %X\n",ad-4)); + ad -= 44; + } + else if ((d & 0x00ff0000) == 0x00600000) { // BUSY + fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); + ad -= 92; + } + } + } + else { + d = get_long (ad); + fpu_debug(("frestore_opp frame at %X = %X\n",ad,d)); + ad += 4; + if ((d & 0xff000000) != 0) { // Not a NULL frame? + if ((d & 0x00ff0000) == 0) { // IDLE + fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); + } + else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP + fpu_debug(("PROBLEM: frestore_opp found UNIMP frame at %X\n",ad-4)); + ad += 44; + } + else if ((d & 0x00ff0000) == 0x00600000) { // BUSY + fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); + ad += 92; + } + } + } + } + else { + // 68881 + if (incr < 0) { + fpu_debug(("PROBLEM: frestore_opp incr < 0\n")); + // this may be wrong, but it's never called. + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) != 0) { + if ((d & 0x00ff0000) == 0x00180000) + ad -= 6 * 4; + else if ((d & 0x00ff0000) == 0x00380000) + ad -= 14 * 4; + else if ((d & 0x00ff0000) == 0x00b40000) + ad -= 45 * 4; + } + } + else { + d = get_long (ad); + fpu_debug(("frestore_opp frame at %X = %X\n",ad,d)); + ad += 4; + if ((d & 0xff000000) != 0) { // Not a NULL frame? + if ((d & 0x00ff0000) == 0x00180000) { // IDLE + fpu_debug(("frestore_opp found IDLE frame at %X\n",ad-4)); + ad += 6 * 4; + } + else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C? + ad += 14 * 4; + fpu_debug(("PROBLEM: frestore_opp found UNIMP? frame at %X\n",ad-4)); + } + else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY + fpu_debug(("PROBLEM: frestore_opp found BUSY frame at %X\n",ad-4)); + ad += 45 * 4; + } + } + } + } + if ((opcode & 0x38) == 0x18) { + m68k_areg (regs, opcode & 7) = ad; + fpu_debug(("frestore_opp post-increment %X -> A%d\n",ad,opcode & 7)); + } + if ((opcode & 0x38) == 0x20) { + m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 + fpu_debug(("PROBLEM: frestore_opp pre-decrement\n")); + } +} + +void FFPU fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) +{ + int reg; + fpu_register src; + + fpu_debug(("FPP %04lx %04x at %08lx\n", opcode & 0xffff, extra & 0xffff, + m68k_getpc () - 4)); + + dump_registers( "START"); + + switch ((extra >> 13) & 0x7) { + case 3: + fpu_debug(("FMOVE -> \n")); + if (put_fp_value (opcode, extra, FPU registers[(extra >> 7) & 7]) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + dump_registers( "END "); + return; + case 4: + case 5: + if ((opcode & 0x38) == 0) { + if (extra & 0x2000) { // dr bit + if (extra & 0x1000) { + m68k_dreg (regs, opcode & 7) = get_fpcr(); + fpu_debug(("FMOVEM FPU fpcr (%X) -> D%d\n", get_fpcr(), opcode & 7)); + } + if (extra & 0x0800) { + m68k_dreg (regs, opcode & 7) = get_fpsr(); + fpu_debug(("FMOVEM FPU fpsr (%X) -> D%d\n", get_fpsr(), opcode & 7)); + } + if (extra & 0x0400) { + m68k_dreg (regs, opcode & 7) = FPU instruction_address; + fpu_debug(("FMOVEM FPU instruction_address (%X) -> D%d\n", FPU instruction_address, opcode & 7)); + } + } + else { + if (extra & 0x1000) { + set_fpcr( m68k_dreg (regs, opcode & 7) ); + fpu_debug(("FMOVEM D%d (%X) -> FPU fpcr\n", opcode & 7, get_fpcr())); + } + if (extra & 0x0800) { + set_fpsr( m68k_dreg (regs, opcode & 7) ); + fpu_debug(("FMOVEM D%d (%X) -> FPU fpsr\n", opcode & 7, get_fpsr())); + } + if (extra & 0x0400) { + FPU instruction_address = m68k_dreg (regs, opcode & 7); + fpu_debug(("FMOVEM D%d (%X) -> FPU instruction_address\n", opcode & 7, FPU instruction_address)); + } + } +// } else if ((opcode & 0x38) == 1) { + } + else if ((opcode & 0x38) == 8) { + if (extra & 0x2000) { // dr bit + if (extra & 0x1000) { + m68k_areg (regs, opcode & 7) = get_fpcr(); + fpu_debug(("FMOVEM FPU fpcr (%X) -> A%d\n", get_fpcr(), opcode & 7)); + } + if (extra & 0x0800) { + m68k_areg (regs, opcode & 7) = get_fpsr(); + fpu_debug(("FMOVEM FPU fpsr (%X) -> A%d\n", get_fpsr(), opcode & 7)); + } + if (extra & 0x0400) { + m68k_areg (regs, opcode & 7) = FPU instruction_address; + fpu_debug(("FMOVEM FPU instruction_address (%X) -> A%d\n", FPU instruction_address, opcode & 7)); + } + } else { + if (extra & 0x1000) { + set_fpcr( m68k_areg (regs, opcode & 7) ); + fpu_debug(("FMOVEM A%d (%X) -> FPU fpcr\n", opcode & 7, get_fpcr())); + } + if (extra & 0x0800) { + set_fpsr( m68k_areg (regs, opcode & 7) ); + fpu_debug(("FMOVEM A%d (%X) -> FPU fpsr\n", opcode & 7, get_fpsr())); + } + if (extra & 0x0400) { + FPU instruction_address = m68k_areg (regs, opcode & 7); + fpu_debug(("FMOVEM A%d (%X) -> FPU instruction_address\n", opcode & 7, FPU instruction_address)); + } + } + } + else if ((opcode & 0x3f) == 0x3c) { + if ((extra & 0x2000) == 0) { + if (extra & 0x1000) { + set_fpcr( next_ilong() ); + fpu_debug(("FMOVEM #<%X> -> FPU fpcr\n", get_fpcr())); + } + if (extra & 0x0800) { + set_fpsr( next_ilong() ); + fpu_debug(("FMOVEM #<%X> -> FPU fpsr\n", get_fpsr())); + } + if (extra & 0x0400) { + FPU instruction_address = next_ilong(); + fpu_debug(("FMOVEM #<%X> -> FPU instruction_address\n", FPU instruction_address)); + } + } + } + else if (extra & 0x2000) { + /* FMOVEM FPP->memory */ + uae_u32 ad; + int incr = 0; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + if ((opcode & 0x38) == 0x20) { + if (extra & 0x1000) + incr += 4; + if (extra & 0x0800) + incr += 4; + if (extra & 0x0400) + incr += 4; + } + ad -= incr; + if (extra & 0x1000) { + put_long (ad, get_fpcr()); + fpu_debug(("FMOVEM FPU fpcr (%X) -> mem %X\n", get_fpcr(), ad )); + ad += 4; + } + if (extra & 0x0800) { + put_long (ad, get_fpsr()); + fpu_debug(("FMOVEM FPU fpsr (%X) -> mem %X\n", get_fpsr(), ad )); + ad += 4; + } + if (extra & 0x0400) { + put_long (ad, FPU instruction_address); + fpu_debug(("FMOVEM FPU instruction_address (%X) -> mem %X\n", FPU instruction_address, ad )); + ad += 4; + } + ad -= incr; + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? + m68k_areg (regs, opcode & 7) = ad; + } + else { + /* FMOVEM memory->FPP */ + uae_u32 ad; + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + + // ad = (opcode & 0x38) == 0x20 ? ad - 12 : ad; + int incr = 0; + if((opcode & 0x38) == 0x20) { + if (extra & 0x1000) + incr += 4; + if (extra & 0x0800) + incr += 4; + if (extra & 0x0400) + incr += 4; + ad = ad - incr; + } + + if (extra & 0x1000) { + set_fpcr( get_long (ad) ); + fpu_debug(("FMOVEM mem %X (%X) -> FPU fpcr\n", ad, get_fpcr() )); + ad += 4; + } + if (extra & 0x0800) { + set_fpsr( get_long (ad) ); + fpu_debug(("FMOVEM mem %X (%X) -> FPU fpsr\n", ad, get_fpsr() )); + ad += 4; + } + if (extra & 0x0400) { + FPU instruction_address = get_long (ad); + fpu_debug(("FMOVEM mem %X (%X) -> FPU instruction_address\n", ad, FPU instruction_address )); + ad += 4; + } + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? +// m68k_areg (regs, opcode & 7) = ad - 12; + m68k_areg (regs, opcode & 7) = ad - incr; + } + dump_registers( "END "); + return; + case 6: + case 7: { + uae_u32 ad, list = 0; + int incr = 0; + if (extra & 0x2000) { + /* FMOVEM FPP->memory */ + fpu_debug(("FMOVEM FPP->memory\n")); + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + list = extra & 0xff; + incr = -1; + break; + case 1: /* dynamic pred */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 3: /* dynamic postinc */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = 1; + break; + } + + if (incr < 0) { + for(reg=7; reg>=0; reg--) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + extract_extended(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + } + else { + for(reg=0; reg<8; reg++) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + extract_extended(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + } + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? + m68k_areg (regs, opcode & 7) = ad; + } + else { + /* FMOVEM memory->FPP */ + fpu_debug(("FMOVEM memory->FPP\n")); + + if (get_fp_ad(opcode, &ad) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + fpu_debug(("memory->FMOVEM FPP not legal mode.\n")); + list = extra & 0xff; + incr = -1; + break; + case 1: /* dynamic pred */ + fpu_debug(("memory->FMOVEM FPP not legal mode.\n")); + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = -1; + break; + case 2: /* static postinc */ + list = extra & 0xff; + incr = 1; + break; + case 3: /* dynamic postinc */ + list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + incr = 1; + break; + } + + /**/ + if (incr < 0) { + // not reached + for(reg=7; reg>=0; reg--) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + // FPU registers[reg] = make_extended(wrd1, wrd2, wrd3); + make_extended_no_normalize (wrd1, wrd2, wrd3, FPU registers[reg]); + } + list <<= 1; + } + } + else { + for(reg=0; reg<8; reg++) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + // FPU registers[reg] = make_extended(wrd1, wrd2, wrd3); + make_extended_no_normalize (wrd1, wrd2, wrd3, FPU registers[reg]); + } + list <<= 1; + } + } + if ((opcode & 0x38) == 0x18) // post-increment? + m68k_areg (regs, opcode & 7) = ad; + if ((opcode & 0x38) == 0x20) // pre-decrement? + m68k_areg (regs, opcode & 7) = ad; + } + dump_registers( "END "); + return; + } + case 0: + case 2: + reg = (extra >> 7) & 7; + if ((extra & 0xfc00) == 0x5c00) { + fpu_debug(("FMOVECR memory->FPP\n")); + switch (extra & 0x7f) { + case 0x00: + // FPU registers[reg] = 4.0 * atan(1.0); + FPU registers[reg] = 3.1415926535897932384626433832795; + fpu_debug(("FP const: Pi\n")); + break; + case 0x0b: + // FPU registers[reg] = log10 (2.0); + FPU registers[reg] = 0.30102999566398119521373889472449; + fpu_debug(("FP const: Log 10 (2)\n")); + break; + case 0x0c: + // FPU registers[reg] = exp (1.0); + FPU registers[reg] = 2.7182818284590452353602874713527; + fpu_debug(("FP const: e\n")); + break; + case 0x0d: + // FPU registers[reg] = log (exp (1.0)) / log (2.0); + FPU registers[reg] = 1.4426950408889634073599246810019; + fpu_debug(("FP const: Log 2 (e)\n")); + break; + case 0x0e: + // FPU registers[reg] = log (exp (1.0)) / log (10.0); + FPU registers[reg] = 0.43429448190325182765112891891661; + fpu_debug(("FP const: Log 10 (e)\n")); + break; + case 0x0f: + FPU registers[reg] = 0.0; + fpu_debug(("FP const: zero\n")); + break; + case 0x30: + // FPU registers[reg] = log (2.0); + FPU registers[reg] = 0.69314718055994530941723212145818; + fpu_debug(("FP const: ln(2)\n")); + break; + case 0x31: + // FPU registers[reg] = log (10.0); + FPU registers[reg] = 2.3025850929940456840179914546844; + fpu_debug(("FP const: ln(10)\n")); + break; + case 0x32: + // ?? + FPU registers[reg] = 1.0e0; + fpu_debug(("FP const: 1.0e0\n")); + break; + case 0x33: + FPU registers[reg] = 1.0e1; + fpu_debug(("FP const: 1.0e1\n")); + break; + case 0x34: + FPU registers[reg] = 1.0e2; + fpu_debug(("FP const: 1.0e2\n")); + break; + case 0x35: + FPU registers[reg] = 1.0e4; + fpu_debug(("FP const: 1.0e4\n")); + break; + case 0x36: + FPU registers[reg] = 1.0e8; + fpu_debug(("FP const: 1.0e8\n")); + break; + case 0x37: + FPU registers[reg] = 1.0e16; + fpu_debug(("FP const: 1.0e16\n")); + break; + case 0x38: + FPU registers[reg] = 1.0e32; + fpu_debug(("FP const: 1.0e32\n")); + break; + case 0x39: + FPU registers[reg] = 1.0e64; + fpu_debug(("FP const: 1.0e64\n")); + break; + case 0x3a: + FPU registers[reg] = 1.0e128; + fpu_debug(("FP const: 1.0e128\n")); + break; + case 0x3b: + FPU registers[reg] = 1.0e256; + fpu_debug(("FP const: 1.0e256\n")); + break; + + // Valid for 64 bits only (see fpu.cpp) +#if 0 + case 0x3c: + FPU registers[reg] = 1.0e512; + fpu_debug(("FP const: 1.0e512\n")); + break; + case 0x3d: + FPU registers[reg] = 1.0e1024; + fpu_debug(("FP const: 1.0e1024\n")); + break; + case 0x3e: + FPU registers[reg] = 1.0e2048; + fpu_debug(("FP const: 1.0e2048\n")); + break; + case 0x3f: + FPU registers[reg] = 1.0e4096; + fpu_debug(("FP const: 1.0e4096\n")); + break; +#endif + default: + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + break; + } + // these *do* affect the status reg + make_fpsr(FPU registers[reg]); + dump_registers( "END "); + return; + } + + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + fpu_debug(("returned from get_fp_value m68k_getpc()=%X\n",m68k_getpc())); +#if 0 // MJ added, not tested now + if (FPU is_integral) { + // 68040-specific operations + switch (extra & 0x7f) { + case 0x40: /* FSMOVE */ + fpu_debug(("FSMOVE %.04f\n",(double)src)); + FPU registers[reg] = (float)src; + make_fpsr(FPU registers[reg]); + break; + case 0x44: /* FDMOVE */ + fpu_debug(("FDMOVE %.04f\n",(double)src)); + FPU registers[reg] = (double)src; + make_fpsr(FPU registers[reg]); + break; + case 0x41: /* FSSQRT */ + fpu_debug(("FSQRT %.04f\n",(double)src)); + FPU registers[reg] = (float)sqrt (src); + make_fpsr(FPU registers[reg]); + break; + case 0x45: /* FDSQRT */ + fpu_debug(("FSQRT %.04f\n",(double)src)); + FPU registers[reg] = (double)sqrt (src); + make_fpsr(FPU registers[reg]); + break; + case 0x58: /* FSABS */ + fpu_debug(("FSABS %.04f\n",(double)src)); + FPU registers[reg] = (float)fabs(src); + make_fpsr(FPU registers[reg]); + break; + case 0x5c: /* FDABS */ + fpu_debug(("FDABS %.04f\n",(double)src)); + FPU registers[reg] = (double)fabs(src); + make_fpsr(FPU registers[reg]); + break; + case 0x5a: /* FSNEG */ + fpu_debug(("FSNEG %.04f\n",(double)src)); + FPU registers[reg] = (float)-src; + make_fpsr(FPU registers[reg]); + break; + case 0x5e: /* FDNEG */ + fpu_debug(("FDNEG %.04f\n",(double)src)); + FPU registers[reg] = (double)-src; + make_fpsr(FPU registers[reg]); + break; + case 0x60: /* FSDIV */ + fpu_debug(("FSDIV %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] / src); + make_fpsr(FPU registers[reg]); + break; + case 0x64: /* FDDIV */ + fpu_debug(("FDDIV %.04f\n",(double)src)); + FPU registers[reg] = (double)(FPU registers[reg] / src); + make_fpsr(FPU registers[reg]); + break; + case 0x62: /* FSADD */ + fpu_debug(("FSADD %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] + src); + make_fpsr(FPU registers[reg]); + break; + case 0x66: /* FDADD */ + fpu_debug(("FDADD %.04f\n",(double)src)); + FPU registers[reg] = (double)(FPU registers[reg] + src); + make_fpsr(FPU registers[reg]); + break; + case 0x68: /* FSSUB */ + fpu_debug(("FSSUB %.04f\n",(double)src)); + FPU registers[reg] = (float)(FPU registers[reg] - src); + make_fpsr(FPU registers[reg]); + break; + case 0x6c: /* FDSUB */ + fpu_debug(("FDSUB %.04f\n",(double)src)); + FPU registers[reg] = (double)(FPU registers[reg] - src); + make_fpsr(FPU registers[reg]); + break; + case 0x63: /* FSMUL */ + case 0x67: /* FDMUL */ + get_dest_flags(FPU registers[reg]); + get_source_flags(src); + if(fl_dest.in_range && fl_source.in_range) { + if ((extra & 0x7f) == 0x63) + FPU registers[reg] = (float)(FPU registers[reg] * src); + else + FPU registers[reg] = (double)(FPU registers[reg] * src); + } + else if (fl_dest.nan || fl_source.nan || + fl_dest.zero && fl_source.infinity || + fl_dest.infinity && fl_source.zero ) { + make_nan( FPU registers[reg], fl_dest.negative ); + } + else if (fl_dest.zero || fl_source.zero ) { + make_zero(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + else { + make_inf(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + make_fpsr(FPU registers[reg]); + break; + default: + // Continue decode-execute 6888x instructions below + goto process_6888x_instructions; + } + fpu_debug(("END m68k_getpc()=%X\n",m68k_getpc())); + dump_registers( "END "); + return; + } + + process_6888x_instructions: +#endif + switch (extra & 0x7f) { + case 0x00: /* FMOVE */ + fpu_debug(("FMOVE %.04f\n",(double)src)); + FPU registers[reg] = src; + // -> reg DOES affect the status reg + make_fpsr(FPU registers[reg]); + break; + case 0x01: /* FINT */ + fpu_debug(("FINT %.04f\n",(double)src)); + // FPU registers[reg] = (int) (src + 0.5); + // FIXME: use native rounding mode flags + switch (get_fpcr() & FPCR_ROUNDING_MODE) { + case FPCR_ROUND_ZERO: + FPU registers[reg] = round_to_zero(src); + break; + case FPCR_ROUND_MINF: + FPU registers[reg] = floor(src); + break; + case FPCR_ROUND_NEAR: + FPU registers[reg] = round_to_nearest(src); + break; + case FPCR_ROUND_PINF: + FPU registers[reg] = ceil(src); + break; + } + make_fpsr(FPU registers[reg]); + break; + case 0x02: /* FSINH */ + fpu_debug(("FSINH %.04f\n",(double)src)); + FPU registers[reg] = sinh (src); + make_fpsr(FPU registers[reg]); + break; + case 0x03: /* FINTRZ */ + fpu_debug(("FINTRZ %.04f\n",(double)src)); + // FPU registers[reg] = (int) src; + FPU registers[reg] = round_to_zero(src); + make_fpsr(FPU registers[reg]); + break; + case 0x04: /* FSQRT */ + fpu_debug(("FSQRT %.04f\n",(double)src)); + FPU registers[reg] = sqrt (src); + make_fpsr(FPU registers[reg]); + break; + case 0x06: /* FLOGNP1 */ + fpu_debug(("FLOGNP1 %.04f\n",(double)src)); + FPU registers[reg] = log (src + 1.0); + make_fpsr(FPU registers[reg]); + break; + case 0x08: /* FETOXM1 */ + fpu_debug(("FETOXM1 %.04f\n",(double)src)); + FPU registers[reg] = exp (src) - 1.0; + make_fpsr(FPU registers[reg]); + break; + case 0x09: /* FTANH */ + fpu_debug(("FTANH %.04f\n",(double)src)); + FPU registers[reg] = tanh (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0a: /* FATAN */ + fpu_debug(("FATAN %.04f\n",(double)src)); + FPU registers[reg] = atan (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0c: /* FASIN */ + fpu_debug(("FASIN %.04f\n",(double)src)); + FPU registers[reg] = asin (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0d: /* FATANH */ + fpu_debug(("FATANH %.04f\n",(double)src)); +#if HAVE_ATANH + FPU registers[reg] = atanh (src); +#else + /* The BeBox doesn't have atanh, and it isn't in the HPUX libm either */ + FPU registers[reg] = log ((1 + src) / (1 - src)) / 2; +#endif + make_fpsr(FPU registers[reg]); + break; + case 0x0e: /* FSIN */ + fpu_debug(("FSIN %.04f\n",(double)src)); + FPU registers[reg] = sin (src); + make_fpsr(FPU registers[reg]); + break; + case 0x0f: /* FTAN */ + fpu_debug(("FTAN %.04f\n",(double)src)); + FPU registers[reg] = tan (src); + make_fpsr(FPU registers[reg]); + break; + case 0x10: /* FETOX */ + fpu_debug(("FETOX %.04f\n",(double)src)); + FPU registers[reg] = exp (src); + make_fpsr(FPU registers[reg]); + break; + case 0x11: /* FTWOTOX */ + fpu_debug(("FTWOTOX %.04f\n",(double)src)); + FPU registers[reg] = pow(2.0, src); + make_fpsr(FPU registers[reg]); + break; + case 0x12: /* FTENTOX */ + fpu_debug(("FTENTOX %.04f\n",(double)src)); + FPU registers[reg] = pow(10.0, src); + make_fpsr(FPU registers[reg]); + break; + case 0x14: /* FLOGN */ + fpu_debug(("FLOGN %.04f\n",(double)src)); + FPU registers[reg] = log (src); + make_fpsr(FPU registers[reg]); + break; + case 0x15: /* FLOG10 */ + fpu_debug(("FLOG10 %.04f\n",(double)src)); + FPU registers[reg] = log10 (src); + make_fpsr(FPU registers[reg]); + break; + case 0x16: /* FLOG2 */ + fpu_debug(("FLOG2 %.04f\n",(double)src)); + FPU registers[reg] = log (src) / log (2.0); + make_fpsr(FPU registers[reg]); + break; + case 0x18: /* FABS */ + case 0x58: /* single precision rounding */ + case 0x5C: /* double precision rounding */ + fpu_debug(("FABS %.04f\n",(double)src)); + FPU registers[reg] = src < 0 ? -src : src; + make_fpsr(FPU registers[reg]); + break; + case 0x19: /* FCOSH */ + fpu_debug(("FCOSH %.04f\n",(double)src)); + FPU registers[reg] = cosh(src); + make_fpsr(FPU registers[reg]); + break; + case 0x1a: /* FNEG */ + fpu_debug(("FNEG %.04f\n",(double)src)); + if (iszero(src)) + make_zero(FPU registers[reg], !isneg(src)); + else + FPU registers[reg] = -src; + make_fpsr(FPU registers[reg]); + break; + case 0x1c: /* FACOS */ + fpu_debug(("FACOS %.04f\n",(double)src)); + FPU registers[reg] = acos(src); + make_fpsr(FPU registers[reg]); + break; + case 0x1d: /* FCOS */ + fpu_debug(("FCOS %.04f\n",(double)src)); + FPU registers[reg] = cos(src); + make_fpsr(FPU registers[reg]); + break; + case 0x1e: /* FGETEXP */ + fpu_debug(("FGETEXP %.04f\n",(double)src)); +#if FPU_HAVE_IEEE_DOUBLE + if( isinf(src) ) { + make_nan( FPU registers[reg], isneg(src) ); + } + else { + FPU registers[reg] = fast_fgetexp( src ); + } +#else + if(src == 0) { + FPU registers[reg] = (fpu_register)0; + } + else { + int expon; + frexp (src, &expon); + FPU registers[reg] = (fpu_register) (expon - 1); + } +#endif + make_fpsr(FPU registers[reg]); + break; + case 0x1f: /* FGETMAN */ + fpu_debug(("FGETMAN %.04f\n",(double)src)); +#if FPU_HAVE_IEEE_DOUBLE + if( src == 0 ) { + FPU registers[reg] = 0; + } + else if( isinf(src) ) { + make_nan( FPU registers[reg], isneg(src) ); + } + else { + FPU registers[reg] = src; + fast_remove_exponent( FPU registers[reg] ); + } +#else + { + int expon; + FPU registers[reg] = frexp (src, &expon) * 2.0; + } +#endif + make_fpsr(FPU registers[reg]); + break; + case 0x20: /* FDIV */ + fpu_debug(("FDIV %.04f\n",(double)src)); + FPU registers[reg] /= src; + make_fpsr(FPU registers[reg]); + break; + case 0x21: /* FMOD */ + fpu_debug(("FMOD %.04f\n",(double)src)); + // FPU registers[reg] = FPU registers[reg] - (fpu_register) ((int) (FPU registers[reg] / src)) * src; + { + fpu_register quot = round_to_zero(FPU registers[reg] / src); +#if FPU_HAVE_IEEE_DOUBLE + uae_u32 sign = get_quotient_sign(FPU registers[reg],src); +#endif + FPU registers[reg] = FPU registers[reg] - quot * src; + make_fpsr(FPU registers[reg]); +#if FPU_HAVE_IEEE_DOUBLE + make_quotient(quot, sign); +#endif + } + break; + case 0x22: /* FADD */ + case 0x62: /* single */ + case 0x66: /* double */ + fpu_debug(("FADD %.04f\n",(double)src)); + FPU registers[reg] += src; + make_fpsr(FPU registers[reg]); + break; + case 0x23: /* FMUL */ + fpu_debug(("FMUL %.04f\n",(double)src)); +#if FPU_HAVE_IEEE_DOUBLE + get_dest_flags(FPU registers[reg]); + get_source_flags(src); + if(fl_dest.in_range && fl_source.in_range) { + FPU registers[reg] *= src; + } + else if (fl_dest.nan || fl_source.nan || + (fl_dest.zero && fl_source.infinity) || + (fl_dest.infinity && fl_source.zero) ) { + make_nan( FPU registers[reg], fl_dest.negative ); + } + else if (fl_dest.zero || fl_source.zero ) { + make_zero(FPU registers[reg], fl_dest.negative != fl_source.negative); + } + else { + make_inf(FPU registers[reg], fl_dest.negative != fl_source.negative); + } +#else + fpu_debug(("FMUL %.04f\n",(double)src)); + FPU registers[reg] *= src; +#endif + make_fpsr(FPU registers[reg]); + break; + case 0x24: /* FSGLDIV */ + fpu_debug(("FSGLDIV %.04f\n",(double)src)); + // TODO: round to float. + FPU registers[reg] /= src; + make_fpsr(FPU registers[reg]); + break; + case 0x25: /* FREM */ + fpu_debug(("FREM %.04f\n",(double)src)); + // FPU registers[reg] = FPU registers[reg] - (double) ((int) (FPU registers[reg] / src + 0.5)) * src; + { + fpu_register quot = round_to_nearest(FPU registers[reg] / src); +#if FPU_HAVE_IEEE_DOUBLE + uae_u32 sign = get_quotient_sign(FPU registers[reg],src); +#endif + FPU registers[reg] = FPU registers[reg] - quot * src; + make_fpsr(FPU registers[reg]); +#if FPU_HAVE_IEEE_DOUBLE + make_quotient(quot,sign); +#endif + } + break; + + case 0x26: /* FSCALE */ + fpu_debug(("FSCALE %.04f\n",(double)src)); + + // TODO: + // Overflow, underflow + +#if FPU_HAVE_IEEE_DOUBLE + if( isinf(src) ) { + make_nan( FPU registers[reg], isneg(src) ); + } + else { + // When the absolute value of the source operand is >= 2^14, + // an overflow or underflow always results. + // Here (int) cast is okay. + fast_scale( FPU registers[reg], (int)round_to_zero(src) ); + } +#else + if (src != 0) { // Manual says: src==0 -> FPn + FPU registers[reg] *= exp (log (2.0) * src); + } +#endif + make_fpsr(FPU registers[reg]); + break; + case 0x27: /* FSGLMUL */ + fpu_debug(("FSGLMUL %.04f\n",(double)src)); + FPU registers[reg] *= src; + make_fpsr(FPU registers[reg]); + break; + case 0x28: /* FSUB */ + fpu_debug(("FSUB %.04f\n",(double)src)); + FPU registers[reg] -= src; + make_fpsr(FPU registers[reg]); + break; + case 0x30: /* FSINCOS */ + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + fpu_debug(("FSINCOS %.04f\n",(double)src)); + // Cosine must be calculated first if same register + FPU registers[extra & 7] = cos(src); + FPU registers[reg] = sin (src); + // Set FPU fpsr according to the sine result + make_fpsr(FPU registers[reg]); + break; + case 0x38: /* FCMP */ + fpu_debug(("FCMP %.04f\n",(double)src)); + + // The infinity bit is always cleared by the FCMP + // instruction since it is not used by any of the + // conditional predicate equations. + +#if FPU_HAVE_IEEE_DOUBLE + if( isinf(src) ) { + if( isneg(src) ) { + // negative infinity + if( isinf(FPU registers[reg]) && isneg(FPU registers[reg]) ) { + // Zero, Negative + FPU fpsr.condition_codes = NATIVE_FFLAG_ZERO | NATIVE_FFLAG_NEGATIVE; + fpu_debug(("-INF cmp -INF -> NZ\n")); + } + else { + // None + FPU fpsr.condition_codes = 0; + fpu_debug(("x cmp -INF -> None\n")); + } + } + else { + // positive infinity + if( isinf(FPU registers[reg]) && !isneg(FPU registers[reg]) ) { + // Zero + FPU fpsr.condition_codes = NATIVE_FFLAG_ZERO; + fpu_debug(("+INF cmp +INF -> Z\n")); + } + else { + // Negative + FPU fpsr.condition_codes = NATIVE_FFLAG_NEGATIVE; + fpu_debug(("X cmp +INF -> N\n")); + } + } + } + else { + fpu_register tmp = FPU registers[reg] - src; + FPU fpsr.condition_codes + = (iszero(tmp) ? NATIVE_FFLAG_ZERO : 0) + | (isneg(tmp) ? NATIVE_FFLAG_NEGATIVE : 0) + ; + } +#else + { + fpu_register tmp = FPU registers[reg] - src; + make_fpsr(tmp); + } +#endif + break; + case 0x3a: /* FTST */ + fpu_debug(("FTST %.04f\n",(double)src)); + // make_fpsr(FPU registers[reg]); + make_fpsr(src); + break; + default: + fpu_debug(("ILLEGAL F OP %X\n",opcode)); + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + break; + } + fpu_debug(("END m68k_getpc()=%X\n",m68k_getpc())); + dump_registers( "END "); + return; + } + + fpu_debug(("ILLEGAL F OP 2 %X\n",opcode)); + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); +} + + +void fpu_set_fpsr(uae_u32 new_fpsr) +{ + set_fpsr(new_fpsr); +} + +uae_u32 fpu_get_fpsr(void) +{ + return get_fpsr(); +} + +void fpu_set_fpcr(uae_u32 new_fpcr) +{ + set_fpcr(new_fpcr); +} + +uae_u32 fpu_get_fpcr(void) +{ + return get_fpcr(); +} + +/* -------------------------- Initialization -------------------------- */ + +void FFPU fpu_init (bool integral_68040) +{ + fpu_debug(("fpu_init\n")); + + static bool initialized_lookup_tables = false; + if (!initialized_lookup_tables) { + fpu_init_native_fflags(); + fpu_init_native_exceptions(); + fpu_init_native_accrued_exceptions(); + initialized_lookup_tables = true; + } + + FPU is_integral = integral_68040; + set_fpcr(0); + set_fpsr(0); + FPU instruction_address = 0; +} + +void FFPU fpu_exit (void) +{ + fpu_debug(("fpu_exit\n")); +} + +void FFPU fpu_reset (void) +{ + fpu_debug(("fpu_reset\n")); + fpu_exit(); + fpu_init(FPU is_integral); +} diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_uae.h b/BasiliskII/src/uae_cpu_2021/fpu/fpu_uae.h new file mode 100644 index 000000000..822fc2207 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_uae.h @@ -0,0 +1,215 @@ +/* + * fpu/fpu_uae.h - Extra Definitions for the old UAE FPU core + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_UAE_H +#define FPU_UAE_H + +// Only define if you have IEEE 64 bit doubles. +#define FPU_HAVE_IEEE_DOUBLE 1 + +/* NOTE: this file shall be included from fpu/fpu_uae.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +enum { +#ifdef WORDS_BIGENDIAN + FHI = 0, + FLO = 1 +#else + FHI = 1, + FLO = 0 +#endif +}; + +// Floating-point rounding support +PRIVATE inline fpu_register round_to_zero(fpu_register const & x); +PRIVATE inline fpu_register round_to_nearest(fpu_register const & x); + +#if FPU_HAVE_IEEE_DOUBLE + +// Lauri-- full words to avoid partial register stalls. +struct double_flags { + uae_u32 in_range; + uae_u32 zero; + uae_u32 infinity; + uae_u32 nan; + uae_u32 negative; +}; +PRIVATE double_flags fl_source; +PRIVATE double_flags fl_dest; +PRIVATE inline void FFPU get_dest_flags(fpu_register const & r); +PRIVATE inline void FFPU get_source_flags(fpu_register const & r); + +PRIVATE inline bool FFPU do_isnan(fpu_register const & r); +PRIVATE inline bool FFPU do_isinf(fpu_register const & r); +PRIVATE inline bool FFPU do_isneg(fpu_register const & r); +PRIVATE inline bool FFPU do_iszero(fpu_register const & r); + +PRIVATE inline void FFPU make_nan(fpu_register & r, bool negative); +PRIVATE inline void FFPU make_zero(fpu_register & r, bool negative); +PRIVATE inline void FFPU make_inf(fpu_register & r, bool negative); + +PRIVATE inline void FFPU fast_scale(fpu_register & r, int add); +PRIVATE inline fpu_register FFPU fast_fgetexp(fpu_register const & r); + +// May be optimized for particular processors +#ifndef FPU_USE_NATIVE_FLAGS +PRIVATE inline void FFPU make_fpsr(fpu_register const & r); +#endif + +// Normalize to range 1..2 +PRIVATE inline void FFPU fast_remove_exponent(fpu_register & r); + +// The sign of the quotient is the exclusive-OR of the sign bits +// of the source and destination operands. +PRIVATE inline uae_u32 FFPU get_quotient_sign( + fpu_register const & ra, fpu_register const & rb +); + +// Quotient Byte is loaded with the sign and least significant +// seven bits of the quotient. +PRIVATE inline void FFPU make_quotient( + fpu_register const & quotient, uae_u32 sign +); + +// to_single +PRIVATE inline fpu_register FFPU make_single( + uae_u32 value +); + +// from_single +PRIVATE inline uae_u32 FFPU extract_single( + fpu_register const & src +); + +// to_exten +PRIVATE inline fpu_register FFPU make_extended( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 +); + +/* + Would be so much easier with full size floats :( + ... this is so vague. +*/ +// to_exten_no_normalize +PRIVATE inline void FFPU make_extended_no_normalize( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result +); + +// from_exten +PRIVATE inline void FFPU extract_extended(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +); + +// to_double +PRIVATE inline fpu_register FFPU make_double( + uae_u32 wrd1, uae_u32 wrd2 +); + +// from_double +PRIVATE inline void FFPU extract_double(fpu_register const & src, + uae_u32 * wrd1, uae_u32 * wrd2 +); + +#else /* !FPU_HAVE_IEEE_DOUBLE */ + +// FIXME: may be optimized for particular processors +#ifndef FPU_USE_NATIVE_FLAGS +PRIVATE inline void FFPU make_fpsr(fpu_register const & r); +#endif + +// to_single +PRIVATE inline fpu_register make_single( + uae_u32 value +); + +// from_single +PRIVATE inline uae_u32 FFPU extract_single( + fpu_register const & src +); + +// to exten +PRIVATE inline fpu_register FFPU make_extended( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 +); + +// from_exten +PRIVATE inline void FFPU extract_extended( + fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +); + +// to_double +PRIVATE inline fpu_register FFPU make_double( + uae_u32 wrd1, uae_u32 wrd2 +); + +// from_double +PRIVATE inline void FFPU extract_double( + fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2 +); + +#endif /* FPU_HAVE_IEEE_DOUBLE */ + +PRIVATE inline fpu_register FFPU make_packed( + uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3 +); + +PRIVATE inline void FFPU extract_packed( + fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 +); + +PRIVATE inline int FFPU get_fp_value( + uae_u32 opcode, uae_u16 extra, fpu_register & src +); + +PRIVATE inline int FFPU put_fp_value( + uae_u32 opcode, uae_u16 extra, fpu_register const & value +); + +PRIVATE inline int FFPU get_fp_ad( + uae_u32 opcode, uae_u32 * ad +); + +PRIVATE inline int FFPU fpp_cond( + int condition +); + +#endif /* FPU_UAE_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86.cpp b/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86.cpp new file mode 100644 index 000000000..29af7ddb9 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86.cpp @@ -0,0 +1,6791 @@ +/* + * fpu/fpu_x86.cpp - 68881/68040 fpu code for x86/Windows an Linux/x86. + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * Interface + * Almost the same as original. Please see the comments in "fpu.h". + * + * + * Why assembly? + * The reason is not really speed, but to get infinities, + * NANs and flags finally working. + * + * + * How to maintain Mac and x86 FPU flags -- plan B + * + * regs.piar is not updated. + * + * regs.FPU fpcr always contains the real 68881/68040 control word. + * + * regs.FPU fpsr is not kept up-to-date, for efficiency reasons. + * Most of the FPU commands update this in a way or another, but it is not + * read nearly that often. Therefore, three host-specific words hold the + * status byte and exception byte ("x86_status_word"), accrued exception + * byte ("x86_status_word_accrued") and the quotient byte ("FPU fpsr.quotient"), + * as explained below. + * + * CONDITION CODE - QUOTIENT - EXCEPTION STATUS - ACCRUED EXCEPTION + * CONDITION CODE (N,Z,I,NAN) + * - updated after each opcode, if needed. + * - x86 assembly opcodes call FXAM and store the status word to + * "x86_status_word". + * - When regs.FPU fpsr is actually used, the value of "x86_status_word" + * is translated. + * QUOTIENT BYTE + * - Updated by frem, fmod, frestore(null frame) + * - Stored in "FPU fpsr.quotient" in correct bit position, combined when + * regs.FPU fpsr is actually used. + * EXCEPTION STATUS (BSUN,SNAN,OPERR,OVFL,UNFL,DZ,INEX2,INEX1) + * - updated after each opcode, if needed. + * - Saved in x86 form in "x86_status_word". + * - When regs.FPU fpsr is actually used, the value of "x86_status_word" + * is translated. + * - Only fcc_op can set BSUN + * ACCRUED EXCEPTION (ACCR_IOP,ACCR_OVFL,ACCR_UNFL,ACCR_DZ,ACCR_INEX) + * - updated after each opcode, if needed. + * - Logically OR'ed in x86 form to "x86_status_word_accrued". + * - When regs.FPU fpsr is actually used, the value of + * "x86_status_word_accrued" is translated. + * + * When "x86_status_word" and "x86_status_word_accrued" are stored, + * all pending x86 FPU exceptions are cleared, if there are any. + * + * Writing to "regs.FPU fpsr" reverse-maps to x86 status/exception values and + * stores the values in "x86_status_word", "x86_status_word_accrued" + * and "FPU fpsr.quotient". + * + * So, "x86_status_word" and "x86_status_word_accrued" are not in + * correct bit positions and have x86 values, but "FPU fpsr.quotient" is at + * correct position. + * + * Note that it does not matter that the reverse-mapping is not exact + * (both SW_IE and SW_DE are mapped to ACCR_IOP, but ACCR_IOP maps to + * SW_IE only), the MacOS always sees the correct exception bits. + * + * Also note the usage of the fake BSUN flag SW_FAKE_BSUN. If you change + * the x86 FPU code, you must make sure that you don't generate any FPU + * stack faults. + * + * + * x86 co-processor initialization: + * + * Bit Code Use + * 0 IM Invalid operation exception mask 1 Disabled + * 1 DM Denormalized operand exception mask 1 Disabled + * 2 ZM Zerodivide exception mask 1 Disabled + * 3 OM Overflow exception mask 1 Disabled + * 4 UM Underflow exception mask 1 Disabled + * 5 PM Precision exception mask 1 Disabled + * 6 - - - - + * 7 IEM Interrupt enable mask 0 Enabled + * 8 PC Precision control\ 1 - 64 bits + * 9 PC Precision control/ 1 / + * 10 RC Rounding control\ 0 - Nearest even + * 11 RC Rounding control/ 0 / + * 12 IC Infinity control 1 Affine + * 13 - - - - + * 14 - - - - + * 15 - - - - + * + * + * TODO: + * - Exceptions are not implemented. + * - All tbyte variables should be aligned to 16-byte boundaries. + * (for best efficiency). + * - FTRAPcc code looks like broken. + * - If USE_3_BIT_QUOTIENT is 0, exceptions should be checked after + * float -> int rounding (frem,fmod). + * - The speed can be greatly improved. Do this only after you are sure + * that there are no major bugs. + * - Support for big-endian byte order (but all assembly code needs to + * be rewritten anyway) + * I have some non-portable code like *((uae_u16 *)&m68k_dreg(regs, reg)) = newv; + * Sorry about that, you need to change these. I could do it myself, but better + * not, I would have no way to test them out. + * I tried to mark all spots with a comment TODO_BIGENDIAN. + * - to_double() may need renormalization code. Or then again, maybe not. + * - Signaling NANs should be handled better. The current mapping of + * signaling nan exception to denormalized operand exception is only + * based on the idea that the (possible) handler sees that "something + * seriously wrong" and takes the same action. Should not really get (m)any + * of those since normalization is handled on to_exten() + * + */ + +# include +# include + +#include "sysdeps.h" +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#define FPU_IMPLEMENTATION +#include "fpu/fpu.h" +#include "fpu/fpu_x86.h" +#include "fpu/fpu_x86_asm.h" + +/* Global FPU context */ +fpu_t fpu; + +/* -------------------------------------------------------------------------- */ +/* --- Native Support --- */ +/* -------------------------------------------------------------------------- */ + +#include "fpu/flags.h" +#include "fpu/exceptions.h" +#include "fpu/rounding.h" +#include "fpu/impl.h" + +#include "fpu/flags.cpp" +#include "fpu/exceptions.cpp" +#include "fpu/rounding.cpp" + +/* -------------------------------------------------------------------------- */ +/* --- Scopes Definition --- */ +/* -------------------------------------------------------------------------- */ + +#undef PUBLIC +#define PUBLIC /**/ + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* ---------------------------- Compatibility ---------------------------- */ + +#define BYTE uint8 +#define WORD uint16 +#define DWORD uint32 +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +/* ---------------------------- Configuration ---------------------------- */ + +/* +If USE_3_BIT_QUOTIENT is set to 1, FREM and FMOD use a faster version +with only 3 quotient bits (those provided by the x86 FPU). If set to 0, +they calculate the same 7 bits that m68k does. It seems (as for now) that +3 bits suffice for all Mac programs I have tried. + +If you decide that you need all 7 bits (USE_3_BIT_QUOTIENT is 0), +consider checking the host exception flags after FISTP (search for +"TODO:Quotient". The result may be too large to fit into a dword. +*/ +/* +gb-- I only tested the following configurations: + USE_3_BIT_QUOTIENT 1 -- still changes to apply if no 3-bit quotient + FPU_DEBUG 1 or 0 + USE_CONSISTENCY_CHECKING 0 + I3_ON_ILLEGAL_FPU_OP 0 -- and this won't change + I3_ON_FTRAPCC 0 -- and this won't change +*/ +#define USE_3_BIT_QUOTIENT 1 + +//#define FPU_DEBUG 0 -- now defined in "fpu/fpu.h" +#define USE_CONSISTENCY_CHECKING 0 + +#define I3_ON_ILLEGAL_FPU_OP 0 +#define I3_ON_FTRAPCC 0 + +/* ---------------------------- Debugging ---------------------------- */ + +PUBLIC void FFPU fpu_dump_registers(void) +{ + for (int i = 0; i < 8; i++){ + printf ("FP%d: %g ", i, fpu_get_register(i)); + if ((i & 3) == 3) + printf ("\n"); + } +} + +PUBLIC void FFPU fpu_dump_flags(void) +{ + printf ("N=%d Z=%d I=%d NAN=%d\n", + (get_fpsr() & FPSR_CCB_NEGATIVE) != 0, + (get_fpsr() & FPSR_CCB_ZERO)!= 0, + (get_fpsr() & FPSR_CCB_INFINITY) != 0, + (get_fpsr() & FPSR_CCB_NAN) != 0); +} + +#include "debug.h" + +#if FPU_DEBUG + +PRIVATE void FFPU dump_first_bytes_buf(char *b, uae_u8* buf, uae_s32 actual) +{ + char bb[10]; + int32 i, bytes = min(actual,100); + + *b = 0; + for (i=0; i= 10) _ix = 0; + + sprintf( _s[_ix], "%.04f", (float)f ); + return( _s[_ix] ); +} + +PUBLIC void FFPU dump_registers(const char *s) +{ + char b[512]; + + sprintf( + b, + "%s: %s, %s, %s, %s, %s, %s, %s, %s\r\n", + s, + etos(FPU registers[0]), + etos(FPU registers[1]), + etos(FPU registers[2]), + etos(FPU registers[3]), + etos(FPU registers[4]), + etos(FPU registers[5]), + etos(FPU registers[6]), + etos(FPU registers[7]) + ); + D(bug((char*)b)); +} + +#else + +PUBLIC void FFPU dump_registers(const char *) +{ +} + +PUBLIC void FFPU dump_first_bytes(uae_u8 *, uae_s32) +{ +} + +#endif + + +/* ---------------------------- FPU consistency ---------------------------- */ + +#if USE_CONSISTENCY_CHECKING +PRIVATE void FFPU FPU_CONSISTENCY_CHECK_START(void) +{ +/* _asm { + FNSTSW checked_sw_atstart + } */ + __asm__ __volatile__("fnstsw %0" : "=m" (checked_sw_atstart)); +} + +PRIVATE void FFPU FPU_CONSISTENCY_CHECK_STOP(const char *name) +{ + uae_u16 checked_sw_atend; +// _asm FNSTSW checked_sw_atend + __asm__ __volatile__("fnstsw %0" : "=m" (checked_sw_attend)); + char msg[256]; + + // Check for FPU stack overflows/underflows. + if( (checked_sw_atend & 0x3800) != (checked_sw_atstart & 0x3800) ) { + wsprintf( + msg, + "FPU stack leak at %s, %X, %X\r\n", + name, + (int)(checked_sw_atstart & 0x3800) >> 11, + (int)(checked_sw_atend & 0x3800) >> 11 + ); + OutputDebugString(msg); + } + + // Observe status mapping. + /* + if(checked_sw_atstart != 0x400 || checked_sw_atend != 0x400) { + wsprintf( + msg, "Op %s, x86_status_word before=%X, x86_status_word after=%X\r\n", + name, (int)checked_sw_atstart, (int)checked_sw_atend + ); + OutputDebugString(msg); + } + */ +} +#else +PRIVATE void FFPU FPU_CONSISTENCY_CHECK_START(void) +{ +} + +PRIVATE void FFPU FPU_CONSISTENCY_CHECK_STOP(const char *) +{ +} +#endif + + +/* ---------------------------- Status byte ---------------------------- */ + +// Map x86 FXAM codes -> m68k fpu status byte +#define SW_Z_I_NAN_MASK (SW_C0|SW_C2|SW_C3) +#define SW_Z (SW_C3) +#define SW_I (SW_C0|SW_C2) +#define SW_NAN (SW_C0) +#define SW_FINITE (SW_C2) +#define SW_EMPTY_REGISTER (SW_C0|SW_C3) +#define SW_DENORMAL (SW_C2|SW_C3) +#define SW_UNSUPPORTED (0) +#define SW_N (SW_C1) + +// Initial state after boot, reset and frestore(null frame) +#define SW_INITIAL SW_FINITE + + +/* ---------------------------- Status functions ---------------------------- */ + +PRIVATE void inline FFPU SET_BSUN_ON_NAN () +{ + if( (x86_status_word & (SW_Z_I_NAN_MASK)) == SW_NAN ) { + x86_status_word |= SW_FAKE_BSUN; + x86_status_word_accrued |= SW_IE; + } +} + +PRIVATE void inline FFPU build_ex_status () +{ + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } +} + +// TODO_BIGENDIAN; all of these. +/* ---------------------------- Type functions ---------------------------- */ + +/* +When the FPU creates a NAN, the NAN always contains the same bit pattern +in the mantissa. All bits of the mantissa are ones for any precision. +When the user creates a NAN, any nonzero bit pattern can be stored in the mantissa. +*/ +PRIVATE inline void FFPU MAKE_NAN (fpu_register & f, bool negative) +{ + // Make it non-signaling. + uae_u8 * p = (uae_u8 *) &f; + memset( p, 0xFF, sizeof(fpu_register) - 1 ); + p[9] = negative ? 0xff : 0x7F; +} + +/* +For single- and double-precision infinities the fraction is a zero. +For extended-precision infinities, the mantissa�s MSB, the explicit +integer bit, can be either one or zero. +*/ +PRIVATE inline uae_u32 FFPU IS_INFINITY (fpu_register const & f) +{ + uae_u8 * p = (uae_u8 *) &f; + if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) { + if ((*((uae_u32 *)&p[0]) == 0) && + ((*((uae_u32 *)&p[4]) & 0x7FFFFFFF) == 0)) + return(1); + } + return(0); +} + +PRIVATE inline uae_u32 FFPU IS_NAN (fpu_register const & f) +{ + uae_u8 * p = (uae_u8 *) &f; + if( ((p[9] & 0x7F) == 0x7F) && p[8] == 0xFF ) { + if ((*((uae_u32 *)&p[0]) == 0) && + ((*((uae_u32 *)&p[4]) & 0x7FFFFFFF) != 0)) + return(1); + } + return(0); +} + +PRIVATE inline uae_u32 FFPU IS_ZERO (fpu_register const & f) +{ + uae_u8 * p = (uae_u8 *) &f; + return *((uae_u32 *)p) == 0 && + *((uae_u32 *)&p[4]) == 0 && + ( *((uae_u16 *)&p[8]) & 0x7FFF ) == 0; +} + +PRIVATE inline void FFPU MAKE_INF_POSITIVE (fpu_register & f) +{ + uae_u8 * p = (uae_u8 *) &f; + memset( p, 0, sizeof(fpu_register)-2 ); + *((uae_u16 *)&p[8]) = 0x7FFF; +} + +PRIVATE inline void FFPU MAKE_INF_NEGATIVE (fpu_register & f) +{ + uae_u8 * p = (uae_u8 *) &f; + memset( p, 0, sizeof(fpu_register)-2 ); + *((uae_u16 *)&p[8]) = 0xFFFF; +} + +PRIVATE inline void FFPU MAKE_ZERO_POSITIVE (fpu_register & f) +{ + uae_u32 * const p = (uae_u32 *) &f; + memset( p, 0, sizeof(fpu_register) ); +} + +PRIVATE inline void FFPU MAKE_ZERO_NEGATIVE (fpu_register & f) +{ + uae_u32 * const p = (uae_u32 *) &f; + memset( p, 0, sizeof(fpu_register) ); + *((uae_u32 *)&p[4]) = 0x80000000; +} + +PRIVATE inline uae_u32 FFPU IS_NEGATIVE (fpu_register const & f) +{ + uae_u8 * p = (uae_u8 *) &f; + return( (p[9] & 0x80) != 0 ); +} + + +/* ---------------------------- Conversions ---------------------------- */ + +PRIVATE void FFPU signed_to_extended ( uae_s32 x, fpu_register & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + +/* _asm { + MOV ESI, [f] + FILD DWORD PTR [x] + FSTP TBYTE PTR [ESI] + } */ + + __asm__ __volatile__("fildl %1\n\tfstpt %0" : "=m" (f) : "m" (x)); + D(bug("signed_to_extended (%X) = %s\r\n",(int)x,etos(f))); + FPU_CONSISTENCY_CHECK_STOP("signed_to_extended"); +} + +PRIVATE uae_s32 FFPU extended_to_signed_32 ( fpu_register const & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + volatile uae_s32 tmp; + volatile WORD sw_temp; + +/* _asm { + MOV EDI, [f] + FLD TBYTE PTR [EDI] + FISTP DWORD PTR tmp + FNSTSW sw_temp + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fistpl %0\n" + "fnstsw %1\n" + : "=m" (tmp), "=m" (sw_temp) + : "m" (f) + ); + + if(sw_temp & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR. + x86_status_word |= SW_IE; + x86_status_word_accrued |= SW_IE; + // Setting the value to zero might not be the right way to go, + // but I'll leave it like this for now. + tmp = 0; + } + if(sw_temp & SW_PE) { + x86_status_word |= SW_PE; + x86_status_word_accrued |= SW_PE; + } + } + + D(bug("extended_to_signed_32 (%s) = %X\r\n",etos(f),(int)tmp)); + FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_32"); + return tmp; +} + +PRIVATE uae_s16 FFPU extended_to_signed_16 ( fpu_register const & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + volatile uae_s16 tmp; + volatile WORD sw_temp; + +/* _asm { + MOV EDI, [f] + FLD TBYTE PTR [EDI] + FISTP WORD PTR tmp + FNSTSW sw_temp + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fistp %0\n" + "fnstsw %1\n" + : "=m" (tmp), "=m" (sw_temp) + : "m" (f) + ); + + if(sw_temp & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR. + x86_status_word |= SW_IE; + x86_status_word_accrued |= SW_IE; + tmp = 0; + } + if(sw_temp & SW_PE) { + x86_status_word |= SW_PE; + x86_status_word_accrued |= SW_PE; + } + } + + D(bug("extended_to_signed_16 (%s) = %X\r\n",etos(f),(int)tmp)); + FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_16"); + return tmp; +} + +PRIVATE uae_s8 FFPU extended_to_signed_8 ( fpu_register const & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + volatile uae_s16 tmp; + volatile WORD sw_temp; + +/* _asm { + MOV EDI, [f] + FLD TBYTE PTR [EDI] + FISTP WORD PTR tmp + FNSTSW sw_temp + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fistp %0\n" + "fnstsw %1\n" + : "=m" (tmp), "=m" (sw_temp) + : "m" (f) + ); + + if(sw_temp & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + if(sw_temp & (SW_OE|SW_UE|SW_DE|SW_IE)) { // Map SW_OE to OPERR. + x86_status_word |= SW_IE; + x86_status_word_accrued |= SW_IE; + tmp = 0; + } + if(sw_temp & SW_PE) { + x86_status_word |= SW_PE; + x86_status_word_accrued |= SW_PE; + } + } + + if(tmp > 127 || tmp < -128) { // OPERR + x86_status_word |= SW_IE; + x86_status_word_accrued |= SW_IE; + } + + D(bug("extended_to_signed_8 (%s) = %X\r\n",etos(f),(int)tmp)); + FPU_CONSISTENCY_CHECK_STOP("extended_to_signed_8"); + return (uae_s8)tmp; +} + +PRIVATE void FFPU double_to_extended ( double x, fpu_register & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + +/* _asm { + MOV EDI, [f] + FLD QWORD PTR [x] + FSTP TBYTE PTR [EDI] + } */ + + __asm__ __volatile__( + "fldl %1\n" + "fstpt %0\n" + : "=m" (f) + : "m" (x) + ); + + FPU_CONSISTENCY_CHECK_STOP("double_to_extended"); +} + +PRIVATE fpu_double FFPU extended_to_double( fpu_register const & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + double result; + +/* _asm { + MOV ESI, [f] + FLD TBYTE PTR [ESI] + FSTP QWORD PTR result + } */ + + __asm__ __volatile__( + "fldt %1\n" + "fstpl %0\n" + : "=m" (result) + : "m" (f) + ); + + FPU_CONSISTENCY_CHECK_STOP("extended_to_double"); + return result; +} + +PRIVATE void FFPU to_single ( uae_u32 src, fpu_register & f ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [f] + FLD DWORD PTR src + FSTP TBYTE PTR [ESI] + } */ + + __asm__ __volatile__( + "flds %1\n" + "fstpt %0\n" + : "=m" (f) + : "m" (src) + ); + + D(bug("to_single (%X) = %s\r\n",src,etos(f))); + FPU_CONSISTENCY_CHECK_STOP("to_single"); +} + +// TODO_BIGENDIAN +PRIVATE void FFPU to_exten_no_normalize ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + uae_u32 *p = (uae_u32 *)&f; + + uae_u32 sign = (wrd1 & 0x80000000) >> 16; + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + p[0] = wrd3; + p[1] = wrd2; + *((uae_u16 *)&p[2]) = (uae_u16)(sign | exp); + + D(bug("to_exten_no_normalize (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f))); + FPU_CONSISTENCY_CHECK_STOP("to_exten_no_normalize"); +} + +PRIVATE void FFPU to_exten ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + uae_u32 *p = (uae_u32 *)&f; + + uae_u32 sign = (wrd1 & 0x80000000) >> 16; + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + + // The explicit integer bit is not set, must normalize. + // Don't do it for zeroes, infinities or nans. + if( (wrd2 & 0x80000000) == 0 && exp != 0 && exp != 0x7FFF ) { + D(bug("to_exten denormalized mantissa (%X,%X,%X)\r\n",wrd1,wrd2,wrd3)); + if( wrd2 | wrd3 ) { + // mantissa, not fraction. + uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; + while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) { + man <<= 1; + exp--; + } + wrd2 = (uae_u32)( man >> 32 ); + wrd3 = (uae_u32)( man & 0xFFFFFFFF ); + if( exp == 0 || (wrd2 & 0x80000000) == 0 ) { + // underflow + wrd2 = wrd3 = exp = 0; + sign = 0; + } + } else { + if(exp != 0x7FFF && exp != 0) { + // Make a non-signaling nan. + exp = 0x7FFF; + sign = 0; + wrd2 = 0x80000000; + } + } + } + + p[0] = wrd3; + p[1] = wrd2; + *((uae_u16 *)&p[2]) = (uae_u16)(sign | exp); + + D(bug("to_exten (%X,%X,%X) = %s\r\n",wrd1,wrd2,wrd3,etos(f))); + FPU_CONSISTENCY_CHECK_STOP("to_exten"); +} + +PRIVATE void FFPU to_double ( uae_u32 wrd1, uae_u32 wrd2, fpu_register & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + + // gb-- make GCC happy + union { + uae_u64 q; + uae_u32 l[2]; + } src; + + // Should renormalize if needed. I'm not sure that x86 and m68k FPU's + // do it the sama way. This should be extremely rare however. + // to_exten() is often called with denormalized values. + + src.l[0] = wrd2; + src.l[1] = wrd1; + +/* _asm { + FLD QWORD PTR src + MOV EDI, [f] + FSTP TBYTE PTR [EDI] + } */ + + __asm__ __volatile__( + "fldl %1\n" + "fstpt %0\n" + : "=m" (f) + : "m" (src.q) + ); + + D(bug("to_double (%X,%X) = %s\r\n",wrd1,wrd2,etos(f))); + FPU_CONSISTENCY_CHECK_STOP("to_double"); +} + +PRIVATE uae_u32 FFPU from_single ( fpu_register const & f ) +{ + FPU_CONSISTENCY_CHECK_START(); + volatile uae_u32 dest; + volatile WORD sw_temp; + +/* _asm { + MOV EDI, [f] + FLD TBYTE PTR [EDI] + FSTP DWORD PTR dest + FNSTSW sw_temp + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fstps %0\n" + "fnstsw %1\n" + : "=m" (dest), "=m" (sw_temp) + : "m" (f) + ); + + sw_temp &= SW_EXCEPTION_MASK; + if(sw_temp) { +// _asm FNCLEX + asm("fnclex"); + x86_status_word = (x86_status_word & ~SW_EXCEPTION_MASK) | sw_temp; + x86_status_word_accrued |= sw_temp; + } + + D(bug("from_single (%s) = %X\r\n",etos(f),dest)); + FPU_CONSISTENCY_CHECK_STOP("from_single"); + return dest; +} + +// TODO_BIGENDIAN +PRIVATE void FFPU from_exten ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3 ) +{ + FPU_CONSISTENCY_CHECK_START(); + uae_u32 *p = (uae_u32 *)&f; + *wrd3 = p[0]; + *wrd2 = p[1]; + *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16; + + D(bug("from_exten (%s) = %X,%X,%X\r\n",etos(f),*wrd1,*wrd2,*wrd3)); + FPU_CONSISTENCY_CHECK_STOP("from_exten"); +} + +PRIVATE void FFPU from_double ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2 ) +{ + FPU_CONSISTENCY_CHECK_START(); + volatile uae_u32 dest[2]; + volatile WORD sw_temp; + +/* _asm { + MOV EDI, [f] + FLD TBYTE PTR [EDI] + FSTP QWORD PTR dest + FNSTSW sw_temp + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fstpl %0\n" + "fnstsw %1\n" + : "=m" (dest), "=m" (sw_temp) + : "m" (f) + ); + + sw_temp &= SW_EXCEPTION_MASK; + if(sw_temp) { +// _asm FNCLEX + asm("fnclex"); + x86_status_word = (x86_status_word & ~SW_EXCEPTION_MASK) | sw_temp; + x86_status_word_accrued |= sw_temp; + } + + // TODO: There is a partial memory stall, nothing happens until FSTP retires. + // On PIII, could use MMX move w/o any penalty. + *wrd2 = dest[0]; + *wrd1 = dest[1]; + + D(bug("from_double (%s) = %X,%X\r\n",etos(f),dest[1],dest[0])); + FPU_CONSISTENCY_CHECK_STOP("from_double"); +} + +PRIVATE void FFPU do_fmove ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fmove"); +} + +PRIVATE void FFPU do_fsmove ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fsmove"); +} + +PRIVATE void FFPU do_fdmove ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fdmove"); +} + +/* +PRIVATE void FFPU do_fmove_no_status ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FSTP TBYTE PTR [EDI] + } + FPU_CONSISTENCY_CHECK_STOP("do_fmove_no_status"); +} +*/ + + +/* ---------------------------- Operations ---------------------------- */ + +PRIVATE void FFPU do_fint ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FRNDINT + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "frndint\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fint"); +} + +PRIVATE void FFPU do_fintrz ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + WORD cw_temp; + +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FSTCW cw_temp + and cw_temp, ~X86_ROUNDING_MODE + or cw_temp, CW_RC_ZERO + FLDCW cw_temp + FLD TBYTE PTR [ESI] + FRNDINT + FXAM + FNSTSW x86_status_word + FLDCW x86_control_word + FSTP TBYTE PTR [EDI] + } */ + + __asm__ __volatile__( + "fstcw %0\n" + "andl $(~X86_ROUNDING_MODE), %0\n" + "orl $CW_RC_ZERO, %0\n" + "fldcw %0\n" + "fldt %3\n" + "frndint\n" + "fxam \n" + "fnstsw %1\n" + "fldcw %4\n" + "fstpt %2\n" + : "+m" (cw_temp), "=m" (x86_status_word), "=m" (dest) + : "m" (src), "m" (x86_control_word) + ); + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fintrz"); +} + +PRIVATE void FFPU do_fsqrt ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FSQRT + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + + __asm__ __volatile__( + "fldt %2\n" + "fsqrt \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsqrt"); +} + +PRIVATE void FFPU do_fssqrt ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fsqrt \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fssqrt"); +} + +PRIVATE void FFPU do_fdsqrt ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fsqrt \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdsqrt"); +} + +PRIVATE void FFPU do_ftst ( fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + FLD TBYTE PTR [ESI] + FXAM + FNSTSW x86_status_word + FSTP ST(0) + } */ + + __asm__ __volatile__( + "fldt %1\n" + "fxam \n" + "fnstsw %0\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word) + : "m" (src) + ); + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_ftst"); +} + +// These functions are calculated in 53 bits accuracy only. +// Exception checking is not complete. +PRIVATE void FFPU do_fsinh ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = sinh(x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fsinh"); +} + +PRIVATE void FFPU do_flognp1 ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = log (x + 1.0); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_flognp1"); +} + +PRIVATE void FFPU do_fetoxm1 ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = exp (x) - 1.0; + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fetoxm1"); +} + +PRIVATE void FFPU do_ftanh ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = tanh (x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_ftanh"); +} + +PRIVATE void FFPU do_fatan ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = atan (x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fatan"); +} + +PRIVATE void FFPU do_fasin ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = asin (x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fasin"); +} + +PRIVATE void FFPU do_fatanh ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = log ((1 + x) / (1 - x)) / 2; + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fatanh"); +} + +PRIVATE void FFPU do_fetox ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = exp (x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fetox"); +} + +PRIVATE void FFPU do_ftwotox ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = pow(2.0, x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_ftwotox"); +} + +PRIVATE void FFPU do_ftentox ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = pow(10.0, x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_ftentox"); +} + +PRIVATE void FFPU do_flogn ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = log (x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_flogn"); +} + +PRIVATE void FFPU do_flog10 ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = log10 (x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_flog10"); +} + +PRIVATE void FFPU do_flog2 ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = log (x) / log (2.0); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_flog2"); +} + +PRIVATE void FFPU do_facos ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = acos(x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_facos"); +} + +PRIVATE void FFPU do_fcosh ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + double x, y; + x = extended_to_double( src ); + y = cosh(x); + double_to_extended( y, dest ); + do_ftst( dest ); + FPU_CONSISTENCY_CHECK_STOP("do_fcosh"); +} + +PRIVATE void FFPU do_fsin ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FSIN + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fsin \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsin"); +} + +// TODO: Should check for out-of-range condition (partial tangent) +PRIVATE void FFPU do_ftan ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FPTAN + FSTP ST(0) ; pop 1.0 (the 8087/287 compatibility thing) + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fptan \n" + "fstp %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE - SW_UE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_ftan"); +} + +PRIVATE void FFPU do_fabs ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FABS + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fabs \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + // x86 fabs should not rise any exceptions (except stack underflow) + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fabs"); +} + +PRIVATE void FFPU do_fsabs ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fabs \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + // x86 fabs should not rise any exceptions (except stack underflow) + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsabs"); +} + +PRIVATE void FFPU do_fdabs ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fabs \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + // x86 fabs should not rise any exceptions (except stack underflow) + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdabs"); +} + +PRIVATE void FFPU do_fneg ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FCHS + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fchs \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + // x86 fchs should not rise any exceptions (except stack underflow) + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fneg"); +} + +PRIVATE void FFPU do_fsneg ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fchs \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + // x86 fchs should not rise any exceptions (except stack underflow) + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsneg"); +} + +PRIVATE void FFPU do_fdneg ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fchs \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + // x86 fchs should not rise any exceptions (except stack underflow) + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdneg"); +} + +PRIVATE void FFPU do_fcos ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FCOS + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fcos \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fcos"); +} + +PRIVATE void FFPU do_fgetexp ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FXTRACT + FSTP ST(0) ; pop mantissa + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fxtract\n" + "fstp %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fgetexp"); +} + +PRIVATE void FFPU do_fgetman ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FXTRACT + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) ; pop exponent + } */ + __asm__ __volatile__( + "fldt %2\n" + "fxtract\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "=m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fgetman"); +} + +PRIVATE void FFPU do_fdiv ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FDIV ST(0),ST(1) + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } */ + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fdiv %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdiv"); +} + +PRIVATE void FFPU do_fsdiv ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fdiv %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsdiv"); +} + +PRIVATE void FFPU do_fddiv ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fdiv %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fddiv"); +} + +// The sign of the quotient is the exclusive-OR of the sign bits +// of the source and destination operands. +// Quotient Byte is loaded with the sign and least significant +// seven bits of the quotient. + +PRIVATE void FFPU do_fmod ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + + volatile uint16 status; + uae_u32 quot; +#if !USE_3_BIT_QUOTIENT + WORD cw_temp; +#endif + + uae_u8 * dest_p = (uae_u8 *)&dest; + uae_u8 * src_p = (uae_u8 *)&src; + uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; + +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + +#if !USE_3_BIT_QUOTIENT + MOV CX, x86_control_word + AND CX, ~X86_ROUNDING_MODE + OR CX, CW_RC_ZERO + MOV cw_temp, CX + FLDCW cw_temp + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FDIV ST(0),ST(1) + FABS + FISTP DWORD PTR quot + FSTP ST(0) + FLDCW x86_control_word + // TODO:Quotient + // Should clear any possible exceptions here +#endif + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + +// loop until the remainder is not partial any more. +partial_loop: + FPREM + FNSTSW status + TEST status, SW_C2 + JNE partial_loop + + + FXAM + FNSTSW x86_status_word + + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } */ + +#if !USE_3_BIT_QUOTIENT + + __asm__ __volatile__( + "movl %6, %%ecx\n" // %6: x86_control_word (read) + "andl $(~X86_ROUNDING_MODE), %%ecx\n" + "orl $CW_RC_ZERO, %%ecx\n" + "movl %%ecx, %0\n" // %0: cw_temp (read/write) + "fldcw %0\n" + "fldt %5\n" + "fldt %4\n" + "fdiv %%st(1), %%st(0)\n" + "fabs \n" + "fistpl %1\n" // %1: quot (read/write) + "fstp %%st(0)\n" + "fldcw %6\n" + "fldt %5\n" + "fldt %4\n" + "0:\n" // partial_loop + "fprem \n" + "fnstsw %2\n" // %2: status (read/write) + "testl $SW_C2, %2\n" + "jne 0b\n" + "fxam \n" + "fnstsw %3\n" // %3: x86_status_word (write) + "fstpt %4\n" + "fstp %%st(0)\n" + : "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (x86_status_word), "+m" (dest) + : "m" (src), "m" (x86_control_word) + : "ecx" + ); + +#else + + __asm__ __volatile__( + "fldt %3\n" + "fldt %2\n" + "0:\n" // partial_loop + "fprem \n" + "fnstsw %0\n" // %0: status (read/write) + "testl $SW_C2, %0\n" + "jne 0b\n" + "fxam \n" + "fnstsw %1\n" // %1: x86_status_word (write) + "fstpt %2\n" + "fstp %%st(0)\n" + : "+m" (status), "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + +#endif + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); + x86_status_word_accrued |= x86_status_word; + } + +#if USE_3_BIT_QUOTIENT + // SW_C1 Set to least significant bit of quotient (Q0). + // SW_C3 Set to bit 1 (Q1) of the quotient. + // SW_C0 Set to bit 2 (Q2) of the quotient. + quot = ((status & SW_C0) >> 6) | ((status & SW_C3) >> 13) | ((status & SW_C1) >> 9); + FPU fpsr.quotient = (sign | quot) << 16; +#else + FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; +#endif + + FPU_CONSISTENCY_CHECK_STOP("do_fmod"); +} + +PRIVATE void FFPU do_frem ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + + volatile uint16 status; + uae_u32 quot; +#if !USE_3_BIT_QUOTIENT + WORD cw_temp; +#endif + + uae_u8 * dest_p = (uae_u8 *)&dest; + uae_u8 * src_p = (uae_u8 *)&src; + uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; + +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + +#if !USE_3_BIT_QUOTIENT + MOV CX, x86_control_word + AND CX, ~X86_ROUNDING_MODE + OR CX, CW_RC_NEAR + MOV cw_temp, CX + FLDCW cw_temp + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FDIV ST(0),ST(1) + FABS + FISTP DWORD PTR quot + FSTP ST(0) + FLDCW x86_control_word + // TODO:Quotient + // Should clear any possible exceptions here +#endif + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + +// loop until the remainder is not partial any more. +partial_loop: + FPREM1 + FNSTSW status + TEST status, SW_C2 + JNE partial_loop + + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } */ + +#if !USE_3_BIT_QUOTIENT + + __asm__ __volatile__( + "movl %6, %%ecx\n" // %6: x86_control_word (read) + "andl $(~X86_ROUNDING_MODE), %%ecx\n" + "orl $CW_RC_NEAR, %%ecx\n" + "movl %%ecx, %0\n" // %0: cw_temp (read/write) + "fldcw %0\n" + "fldt %5\n" + "fldt %4\n" + "fdiv %%st(1), %%st(0)\n" + "fabs \n" + "fistpl %1\n" // %1: quot (read/write) + "fstp %%st(0)\n" + "fldcw %6\n" + "fldt %5\n" + "fldt %4\n" + "0:\n" // partial_loop + "fprem1 \n" + "fnstsw %2\n" // %2: status (read/write) + "testl $SW_C2, %2\n" + "jne 0b\n" + "fxam \n" + "fnstsw %3\n" // %3: x86_status_word (write) + "fstpt %4\n" + "fstp %%st(0)\n" + : "+m" (cw_temp), "+m" (quot), "+m" (status), "=m" (x86_status_word), "+m" (dest) + : "m" (src), "m" (x86_control_word) + : "ecx" + ); + +#else + + __asm__ __volatile__( + "fldt %3\n" + "fldt %2\n" + "0:\n" // partial_loop + "fprem1 \n" + "fnstsw %0\n" // %0: status (read/write) + "testl $SW_C2, %0\n" + "jne 0b\n" + "fxam \n" + "fnstsw %1\n" // %1: x86_status_word (write) + "fstpt %2\n" + "fstp %%st(0)\n" + : "+m" (status), "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + +#endif + + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); + x86_status_word_accrued |= x86_status_word; + } + +#if USE_3_BIT_QUOTIENT + // SW_C1 Set to least significant bit of quotient (Q0). + // SW_C3 Set to bit 1 (Q1) of the quotient. + // SW_C0 Set to bit 2 (Q2) of the quotient. + quot = ((status & SW_C0) >> 6) | ((status & SW_C3) >> 13) | ((status & SW_C1) >> 9); + FPU fpsr.quotient = (sign | quot) << 16; +#else + FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; +#endif + + FPU_CONSISTENCY_CHECK_STOP("do_frem"); +} + +// Faster versions. The current rounding mode is already correct. +#if !USE_3_BIT_QUOTIENT +PRIVATE void FFPU do_fmod_dont_set_cw ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + + volatile uint16 status; + uae_u32 quot; + + uae_u8 * dest_p = (uae_u8 *)&dest; + uae_u8 * src_p = (uae_u8 *)&src; + uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; + + _asm { + MOV ESI, [src] + MOV EDI, [dest] + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FDIV ST(0),ST(1) + FABS + FISTP DWORD PTR quot + FSTP ST(0) + // TODO:Quotient + // Should clear any possible exceptions here + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + +// loop until the remainder is not partial any more. +partial_loop: + FPREM + FNSTSW status + TEST status, SW_C2 + JNE partial_loop + + FXAM + FNSTSW x86_status_word + + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } + if(x86_status_word & SW_EXCEPTION_MASK) { + _asm FNCLEX + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); + x86_status_word_accrued |= x86_status_word; + } + FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; + FPU_CONSISTENCY_CHECK_STOP("do_fmod_dont_set_cw"); +} + +PRIVATE void FFPU do_frem_dont_set_cw ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + + volatile uint16 status; + uae_u32 quot; + + uae_u8 * dest_p = (uae_u8 *)&dest; + uae_u8 * src_p = (uae_u8 *)&src; + uae_u32 sign = (dest_p[9] ^ src_p[9]) & 0x80; + + _asm { + MOV ESI, [src] + MOV EDI, [dest] + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FDIV ST(0),ST(1) + FABS + FISTP DWORD PTR quot + FSTP ST(0) + // TODO:Quotient + // Should clear any possible exceptions here + + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + +// loop until the remainder is not partial any more. +partial_loop: + FPREM1 + FNSTSW status + TEST status, SW_C2 + JNE partial_loop + + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } + if(x86_status_word & SW_EXCEPTION_MASK) { + _asm FNCLEX + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE); + x86_status_word_accrued |= x86_status_word; + } + FPU fpsr.quotient = (sign | (quot&0x7F)) << 16; + FPU_CONSISTENCY_CHECK_STOP("do_frem_dont_set_cw"); +} +#endif //USE_3_BIT_QUOTIENT + +PRIVATE void FFPU do_fadd ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FADD + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fadd \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fadd"); +} + +PRIVATE void FFPU do_fsadd ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fadd \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsadd"); +} + +PRIVATE void FFPU do_fdadd ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fadd \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdadd"); +} + +PRIVATE void FFPU do_fmul ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FMUL + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fmul \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fmul"); +} + +PRIVATE void FFPU do_fsmul ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fmul \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsmul"); +} + +PRIVATE void FFPU do_fdmul ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fmul \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdmul"); +} + +PRIVATE void FFPU do_fsgldiv ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + WORD cw_temp; +/* _asm { + FSTCW cw_temp + and cw_temp, ~X86_ROUNDING_PRECISION + or cw_temp, PRECISION_CONTROL_SINGLE + FLDCW cw_temp + + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FDIV ST(0),ST(1) + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + FLDCW x86_control_word + } */ + __asm__ __volatile__( + "fstcw %0\n" + "andl $(~X86_ROUNDING_PRECISION), %0\n" + "orl $PRECISION_CONTROL_SINGLE, %0\n" + "fldcw %0\n" + "fldt %3\n" + "fldt %2\n" + "fdiv %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %1\n" + "fstpt %2\n" + "fstp %%st(0)\n" + "fldcw %4\n" + : "+m" (cw_temp), "=m" (x86_status_word), "+m" (dest) + : "m" (src), "m" (x86_control_word) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsgldiv"); +} + +PRIVATE void FFPU do_fscale ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FSCALE + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } */ + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fscale \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_UE - SW_OE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fscale"); +} + +PRIVATE void FFPU do_fsglmul ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + WORD cw_temp; + +/* _asm { + FSTCW cw_temp + and cw_temp, ~X86_ROUNDING_PRECISION + or cw_temp, PRECISION_CONTROL_SINGLE + FLDCW cw_temp + + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FMUL + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + + FLDCW x86_control_word + } */ + __asm__ __volatile__( + "fstcw %0\n" + "andl $(~X86_ROUNDING_PRECISION), %0\n" + "orl $PRECISION_CONTROL_SINGLE, %0\n" + "fldcw %0\n" + "fldt %3\n" + "fldt %2\n" + "fmul \n" + "fxam \n" + "fnstsw %1\n" + "fstpt %2\n" + "fldcw %4\n" + : "+m" (cw_temp), "=m" (x86_status_word), "+m" (dest) + : "m" (src), "m" (x86_status_word) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsglmul"); +} + +PRIVATE void FFPU do_fsub ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FSUB ST(0),ST(1) + FXAM + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } */ + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fsub %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsub"); +} + +PRIVATE void FFPU do_fssub ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fsub %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fssub"); +} + +PRIVATE void FFPU do_fdsub ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fsub %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "+m" (dest) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_OE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fdsub"); +} + +PRIVATE void FFPU do_fsincos ( fpu_register & dest_sin, fpu_register & dest_cos, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest_cos] + FLD TBYTE PTR [ESI] + FSINCOS + FSTP TBYTE PTR [EDI] + FXAM + MOV EDI, [dest_sin] + FNSTSW x86_status_word + FSTP TBYTE PTR [EDI] + FSTP ST(0) + } */ + __asm__ __volatile__( + "fldt %3\n" + "fsincos\n" + "fstpt %1\n" + "fxam \n" + "fnstsw %0\n" + "fstpt %2\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word), "=m" (dest_cos), "=m" (dest_sin) + : "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~(SW_EXCEPTION_MASK - SW_IE - SW_UE - SW_PE); + x86_status_word_accrued |= x86_status_word; + } + FPU_CONSISTENCY_CHECK_STOP("do_fsincos"); +} + +PRIVATE void FFPU do_fcmp ( fpu_register & dest, fpu_register const & src ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + MOV ESI, [src] + MOV EDI, [dest] + FLD TBYTE PTR [ESI] + FLD TBYTE PTR [EDI] + FSUB ST(0),ST(1) + FXAM + FNSTSW x86_status_word + FSTP ST(0) + FSTP ST(0) + } */ + __asm__ __volatile__( + "fldt %2\n" + "fldt %1\n" + "fsub %%st(1), %%st(0)\n" + "fxam \n" + "fnstsw %0\n" + "fstp %%st(0)\n" + "fstp %%st(0)\n" + : "=m" (x86_status_word) + : "m" (dest), "m" (src) + ); + if(x86_status_word & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + x86_status_word &= ~SW_EXCEPTION_MASK; + } + FPU_CONSISTENCY_CHECK_STOP("do_fcmp"); +} + +// More or less original. Should be reviewed. +PRIVATE fpu_double FFPU to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) +{ + FPU_CONSISTENCY_CHECK_START(); + + double d; + char *cp; + char str[100]; + + cp = str; + if (wrd1 & 0x80000000) + *cp++ = '-'; + *cp++ = (char)((wrd1 & 0xf) + '0'); + *cp++ = '.'; + *cp++ = (char)(((wrd2 >> 28) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 24) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 20) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 16) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 12) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 8) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 4) & 0xf) + '0'); + *cp++ = (char)(((wrd2 >> 0) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 28) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 24) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 20) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 16) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 12) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 8) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 4) & 0xf) + '0'); + *cp++ = (char)(((wrd3 >> 0) & 0xf) + '0'); + *cp++ = 'E'; + if (wrd1 & 0x40000000) + *cp++ = '-'; + *cp++ = (char)(((wrd1 >> 24) & 0xf) + '0'); + *cp++ = (char)(((wrd1 >> 20) & 0xf) + '0'); + *cp++ = (char)(((wrd1 >> 16) & 0xf) + '0'); + *cp = 0; + sscanf(str, "%le", &d); + + D(bug("to_pack str = %s\r\n",str)); + + D(bug("to_pack(%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)d)); + + FPU_CONSISTENCY_CHECK_STOP("to_pack"); + + return d; +} + +// More or less original. Should be reviewed. +PRIVATE void FFPU from_pack (fpu_double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) +{ + FPU_CONSISTENCY_CHECK_START(); + + int i; + int t; + char *cp; + char str[100]; + int exponent_digit_count = 0; + + sprintf(str, "%.16e", src); + + D(bug("from_pack(%.04f,%s)\r\n",(float)src,str)); + + cp = str; + *wrd1 = *wrd2 = *wrd3 = 0; + if (*cp == '-') { + cp++; + *wrd1 = 0x80000000; + } + if (*cp == '+') + cp++; + *wrd1 |= (*cp++ - '0'); + if (*cp == '.') + cp++; + for (i = 0; i < 8; i++) { + *wrd2 <<= 4; + if (*cp >= '0' && *cp <= '9') + *wrd2 |= *cp++ - '0'; + } + for (i = 0; i < 8; i++) { + *wrd3 <<= 4; + if (*cp >= '0' && *cp <= '9') + *wrd3 |= *cp++ - '0'; + } + if (*cp == 'e' || *cp == 'E') { + cp++; + if (*cp == '-') { + cp++; + *wrd1 |= 0x40000000; + } + if (*cp == '+') + cp++; + t = 0; + for (i = 0; i < 3; i++) { + if (*cp >= '0' && *cp <= '9') { + t = (t << 4) | (*cp++ - '0'); + exponent_digit_count++; + } + } + *wrd1 |= t << 16; + } + + D(bug("from_pack(%.04f) = %X,%X,%X\r\n",(float)src,*wrd1,*wrd2,*wrd3)); + + WORD sw_temp; +// _asm FNSTSW sw_temp + __asm__ __volatile__("fnstsw %0" : "=m" (sw_temp)); + if(sw_temp & SW_EXCEPTION_MASK) { +// _asm FNCLEX + __asm__ __volatile__("fnclex"); + if(sw_temp & SW_PE) { + x86_status_word |= SW_PE; + x86_status_word_accrued |= SW_PE; + } + } + + /* + OPERR is set if the k-factor > + 17 or the magnitude of + the decimal exponent exceeds three digits; + cleared otherwise. + */ + if(exponent_digit_count > 3) { + x86_status_word |= SW_IE; + x86_status_word_accrued |= SW_IE; + } + + FPU_CONSISTENCY_CHECK_STOP("from_pack"); +} + +PRIVATE int FFPU get_fp_value (uae_u32 opcode, uae_u32 extra, fpu_register & src) +{ + static const int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static const int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + // D(bug("get_fp_value(%X,%X)\r\n",(int)opcode,(int)extra)); + // dump_first_bytes( regs.pc_p-4, 16 ); + + if ((extra & 0x4000) == 0) { + memcpy( &src, &FPU registers[(extra >> 10) & 7], sizeof(fpu_register) ); +// do_fmove_no_status( src, FPU registers[(extra >> 10) & 7] ); + return 1; + } + + int mode = (opcode >> 3) & 7; + int reg = opcode & 7; + int size = (extra >> 10) & 7; + uae_u32 ad = 0; + + // D(bug("get_fp_value mode=%d, reg=%d, size=%d\r\n",(int)mode,(int)reg,(int)size)); + + switch ((uae_u8)mode) { + case 0: + switch ((uae_u8)size) { + case 6: + signed_to_extended( (uae_s32)(uae_s8) m68k_dreg (regs, reg), src ); + break; + case 4: + signed_to_extended( (uae_s32)(uae_s16) m68k_dreg (regs, reg), src ); + break; + case 0: + signed_to_extended( (uae_s32) m68k_dreg (regs, reg), src ); + break; + case 1: + to_single( m68k_dreg (regs, reg), src ); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + break; + case 4: + ad = m68k_areg (regs, reg) - (reg == 7 ? sz2[size] : sz1[size]); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch ((uae_u8)reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; + case 2: + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: { + uaecptr tmppc = m68k_getpc (); + uae_u16 tmp = (uae_u16)next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + } + break; + case 4: + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + + /* + +0000 000004 FSCALE.B #$01,FP2 | F23C 5926 0001 + F23C 1111001000111100 + 5926 0101100100100110 + 0001 0000000000000001 + mode = 7 + reg = 4 + size = 6 + */ + // Immediate addressing mode && Operation Length == Byte -> + // Use the low-order byte of the extension word. + + if(size == 6) ad++; + + // May be faster on a PII(I), sz2[size] is already in register + // ad += sz2[size] - sz1[size]; + + break; + default: + return 0; + } + } + + switch ((uae_u8)size) { + case 0: + signed_to_extended( (uae_s32) get_long (ad), src ); + break; + case 1: + to_single( get_long (ad), src ); + break; + + case 2:{ + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + to_exten( wrd1, wrd2, wrd3, src ); + } + break; + case 3:{ + uae_u32 wrd1, wrd2, wrd3; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + double_to_extended( to_pack(wrd1, wrd2, wrd3), src ); + } + break; + case 4: + signed_to_extended( (uae_s32)(uae_s16) get_word(ad), src ); + break; + case 5:{ + uae_u32 wrd1, wrd2; + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + to_double(wrd1, wrd2, src); + } + break; + case 6: + signed_to_extended( (uae_s32)(uae_s8) get_byte(ad), src ); + break; + default: + return 0; + } + + switch (mode) { + case 3: + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + break; + } + + // D(bug("get_fp_value result = %.04f\r\n",(float)src)); + + return 1; +} + +PRIVATE int FFPU put_fp_value (fpu_register const & value, uae_u32 opcode, uae_u32 extra) +{ + static const int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0}; + static const int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0}; + + // D(bug("put_fp_value(%.04f,%X,%X)\r\n",(float)value,(int)opcode,(int)extra)); + + if ((extra & 0x4000) == 0) { + int dest_reg = (extra >> 10) & 7; + do_fmove( FPU registers[dest_reg], value ); + build_ex_status(); + return 1; + } + + int mode = (opcode >> 3) & 7; + int reg = opcode & 7; + int size = (extra >> 10) & 7; + uae_u32 ad = 0xffffffff; + + // Clear exception status + x86_status_word &= ~SW_EXCEPTION_MASK; + + switch ((uae_u8)mode) { + case 0: + switch ((uae_u8)size) { + case 6: + *((uae_u8 *)&m68k_dreg(regs, reg)) = extended_to_signed_8(value); + break; + case 4: + // TODO_BIGENDIAN + *((uae_u16 *)&m68k_dreg(regs, reg)) = extended_to_signed_16(value); + break; + case 0: + m68k_dreg (regs, reg) = extended_to_signed_32(value); + break; + case 1: + m68k_dreg (regs, reg) = from_single(value); + break; + default: + return 0; + } + return 1; + case 1: + return 0; + case 2: + ad = m68k_areg (regs, reg); + break; + case 3: + ad = m68k_areg (regs, reg); + m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size]; + break; + case 4: + m68k_areg (regs, reg) -= reg == 7 ? sz2[size] : sz1[size]; + ad = m68k_areg (regs, reg); + break; + case 5: + ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch ((uae_u8)reg) { + case 0: + ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + ad = next_ilong(); + break; + case 2: + ad = m68k_getpc (); + ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: { + uaecptr tmppc = m68k_getpc (); + uae_u16 tmp = (uae_u16)next_iword(); + ad = get_disp_ea_020 (tmppc, tmp); + } + break; + case 4: + ad = m68k_getpc (); + m68k_setpc (ad + sz2[size]); + break; + default: + return 0; + } + } + switch ((uae_u8)size) { + case 0: + put_long (ad, (uae_s32) extended_to_signed_32(value)); + break; + case 1: + put_long (ad, from_single(value)); + break; + case 2: { + uae_u32 wrd1, wrd2, wrd3; + from_exten(value, &wrd1, &wrd2, &wrd3); + + x86_status_word &= ~SW_EXCEPTION_MASK; + if(wrd3) { // TODO: not correct! Just a "smart" guess. + x86_status_word |= SW_PE; + x86_status_word_accrued |= SW_PE; + } + + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + } + break; + case 3: { + uae_u32 wrd1, wrd2, wrd3; + from_pack(extended_to_double(value), &wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + } + break; + case 4: + put_word(ad, extended_to_signed_16(value)); + break; + case 5:{ + uae_u32 wrd1, wrd2; + from_double(value, &wrd1, &wrd2); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + } + break; + case 6: + put_byte(ad, extended_to_signed_8(value)); + + break; + default: + return 0; + } + return 1; +} + +PRIVATE int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) +{ + int mode = (opcode >> 3) & 7; + int reg = opcode & 7; + switch ( (uae_u8)mode ) { + case 0: + case 1: + if( (opcode & 0xFF00) == 0xF300 ) { + // fsave, frestore + m68k_setpc (m68k_getpc () - 2); + } else { + m68k_setpc (m68k_getpc () - 4); + } + op_illg (opcode); + dump_registers( "END "); + return 0; + case 2: + *ad = m68k_areg (regs, reg); + break; + case 3: + *ad = m68k_areg (regs, reg); + break; + case 4: + *ad = m68k_areg (regs, reg); + break; + case 5: + *ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) next_iword(); + break; + case 6: + *ad = get_disp_ea_020 (m68k_areg (regs, reg), next_iword()); + break; + case 7: + switch ( (uae_u8)reg ) { + case 0: + *ad = (uae_s32) (uae_s16) next_iword(); + break; + case 1: + *ad = next_ilong(); + break; + case 2: + *ad = m68k_getpc (); + *ad += (uae_s32) (uae_s16) next_iword(); + break; + case 3: { + uaecptr tmppc = m68k_getpc (); + uae_u16 tmp = (uae_u16)next_iword(); + *ad = get_disp_ea_020 (tmppc, tmp); + } + break; + default: + if( (opcode & 0xFF00) == 0xF300 ) { + // fsave, frestore + m68k_setpc (m68k_getpc () - 2); + } else { + m68k_setpc (m68k_getpc () - 4); + } + op_illg (opcode); + dump_registers( "END "); + return 0; + } + } + return 1; +} + +#if FPU_DEBUG +#define CONDRET(s,x) D(bug("fpp_cond %s = %d\r\n",s,(uint32)(x))); return (x) +#else +#define CONDRET(s,x) return (x) +#endif + +PRIVATE int FFPU fpp_cond(uae_u32 opcode, int condition) +{ + +#define N (x86_status_word & SW_N) +#define Z ((x86_status_word & (SW_Z_I_NAN_MASK)) == SW_Z) +#define I ((x86_status_word & (SW_Z_I_NAN_MASK)) == (SW_I)) +#define NotANumber ((x86_status_word & (SW_Z_I_NAN_MASK)) == SW_NAN) + + switch (condition & 0x1f) { + // Common Tests, no BSUN + case 0x01: + CONDRET("Equal",Z); + case 0x0e: + CONDRET("Not Equal",!Z); + + // IEEE Nonaware Tests, BSUN + case 0x12: + SET_BSUN_ON_NAN(); + CONDRET("Greater Than",!(NotANumber || Z || N)); + case 0x1d: + SET_BSUN_ON_NAN(); + CONDRET("Not Greater Than",NotANumber || Z || N); + case 0x13: + SET_BSUN_ON_NAN(); + CONDRET("Greater Than or Equal",Z || !(NotANumber || N)); + case 0x1c: + SET_BSUN_ON_NAN(); + CONDRET("Not Greater Than or Equal",!Z && (NotANumber || N)); + case 0x14: + SET_BSUN_ON_NAN(); + CONDRET("Less Than",N && !(NotANumber || Z)); + case 0x1b: + SET_BSUN_ON_NAN(); + CONDRET("Not Less Than",NotANumber || Z || !N); + case 0x15: + SET_BSUN_ON_NAN(); + CONDRET("Less Than or Equal",Z || (N && !NotANumber)); + case 0x1a: + SET_BSUN_ON_NAN(); + CONDRET("Not Less Than or Equal",NotANumber || !(N || Z)); + case 0x16: + SET_BSUN_ON_NAN(); + CONDRET("Greater or Less Than",!(NotANumber || Z)); + case 0x19: + SET_BSUN_ON_NAN(); + CONDRET("Not Greater or Less Than",NotANumber || Z); + case 0x17: + CONDRET("Greater, Less or Equal",!NotANumber); + case 0x18: + SET_BSUN_ON_NAN(); + CONDRET("Not Greater, Less or Equal",NotANumber); + + // IEEE Aware Tests, no BSUN + case 0x02: + CONDRET("Ordered Greater Than",!(NotANumber || Z || N)); + case 0x0d: + CONDRET("Unordered or Less or Equal",NotANumber || Z || N); + case 0x03: + CONDRET("Ordered Greater Than or Equal",Z || !(NotANumber || N)); + case 0x0c: + CONDRET("Unordered or Less Than",NotANumber || (N && !Z)); + case 0x04: + CONDRET("Ordered Less Than",N && !(NotANumber || Z)); + case 0x0b: + CONDRET("Unordered or Greater or Equal",NotANumber || Z || !N); + case 0x05: + CONDRET("Ordered Less Than or Equal",Z || (N && !NotANumber)); + case 0x0a: + CONDRET("Unordered or Greater Than",NotANumber || !(N || Z)); + case 0x06: + CONDRET("Ordered Greater or Less Than",!(NotANumber || Z)); + case 0x09: + CONDRET("Unordered or Equal",NotANumber || Z); + case 0x07: + CONDRET("Ordered",!NotANumber); + case 0x08: + CONDRET("Unordered",NotANumber); + + // Miscellaneous Tests, no BSUN + case 0x00: + CONDRET("False",0); + case 0x0f: + CONDRET("True",1); + + // Miscellaneous Tests, BSUN + case 0x10: + SET_BSUN_ON_NAN(); + CONDRET("Signaling False",0); + case 0x1f: + SET_BSUN_ON_NAN(); + CONDRET("Signaling True",1); + case 0x11: + SET_BSUN_ON_NAN(); + CONDRET("Signaling Equal",Z); + case 0x1e: + SET_BSUN_ON_NAN(); + CONDRET("Signaling Not Equal",!Z); + } + CONDRET("",-1); + +#undef N +#undef Z +#undef I +#undef NotANumber + +} + +PUBLIC void REGPARAM2 FFPU fpuop_dbcc(uae_u32 opcode, uae_u32 extra) +{ + uaecptr pc = (uae_u32) m68k_getpc (); + uae_s32 disp = (uae_s32) (uae_s16) next_iword(); + int cc; + + D(bug("fdbcc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + cc = fpp_cond(opcode, extra & 0x3f); + if (cc < 0) { + m68k_setpc (pc - 4); + op_illg (opcode); + } else if (!cc) { + int reg = opcode & 0x7; + + // TODO_BIGENDIAN + uae_u16 newv = (uae_u16)(m68k_dreg (regs, reg) & 0xffff) - 1; + *((uae_u16 *)&m68k_dreg(regs, reg)) = newv; + + if (newv != 0xffff) + m68k_setpc (pc + disp); + } +} + +PUBLIC void REGPARAM2 FFPU fpuop_scc(uae_u32 opcode, uae_u32 extra) +{ + uae_u32 ad; + int cc; + + D(bug("fscc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + + cc = fpp_cond(opcode, extra & 0x3f); + if (cc < 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } else if ((opcode & 0x38) == 0) { + // TODO_BIGENDIAN + m68k_dreg (regs, opcode & 7) = (m68k_dreg (regs, opcode & 7) & ~0xff) | + (cc ? 0xff : 0x00); + } else { + if (get_fp_ad(opcode, &ad)) { + put_byte(ad, cc ? 0xff : 0x00); + } + } +} + +PUBLIC void REGPARAM2 FFPU fpuop_trapcc(uae_u32 opcode, uaecptr oldpc, uae_u32 extra) +{ + int cc; + + D(bug("ftrapcc_opp %X, %X at %08lx\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc ())); + +#if I3_ON_FTRAPCC +#error "FIXME: _asm int 3" + _asm int 3 +#endif + + // This must be broken. + cc = fpp_cond(opcode, extra & 0x3f); + + if (cc < 0) { + m68k_setpc (oldpc); + op_illg (opcode); + } else if (cc) + Exception(7, oldpc - 2); +} + +// NOTE that we get here also when there is a FNOP (nontrapping false, displ 0) +PUBLIC void REGPARAM2 FFPU fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) +{ + int cc; + + D(bug("fbcc_opp %X, %X at %08lx, jumpto=%X\r\n", (uae_u32)opcode, (uae_u32)extra, m68k_getpc (), extra )); + + cc = fpp_cond(opcode, opcode & 0x3f); + if (cc < 0) { + m68k_setpc (pc); + op_illg (opcode); + } else if (cc) { + if ((opcode & 0x40) == 0) + extra = (uae_s32) (uae_s16) extra; + m68k_setpc (pc + extra); + } +} + +// FSAVE has no post-increment +// 0x1f180000 == IDLE state frame, coprocessor version number 1F +PUBLIC void REGPARAM2 FFPU fpuop_save(uae_u32 opcode) +{ + uae_u32 ad; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + int i; + + D(bug("fsave_opp at %08lx\r\n", m68k_getpc ())); + + if (get_fp_ad(opcode, &ad)) { + if (FPU is_integral) { + // Put 4 byte 68040 IDLE frame. + if (incr < 0) { + ad -= 4; + put_long (ad, 0x41000000); + } else { + put_long (ad, 0x41000000); + ad += 4; + } + } else { + // Put 28 byte 68881 IDLE frame. + if (incr < 0) { + D(bug("fsave_opp pre-decrement\r\n")); + ad -= 4; + // What's this? Some BIU flags, or (incorrectly placed) command/condition? + put_long (ad, 0x70000000); + for (i = 0; i < 5; i++) { + ad -= 4; + put_long (ad, 0x00000000); + } + ad -= 4; + put_long (ad, 0x1f180000); // IDLE, vers 1f + } else { + put_long (ad, 0x1f180000); // IDLE, vers 1f + ad += 4; + for (i = 0; i < 5; i++) { + put_long (ad, 0x00000000); + ad += 4; + } + // What's this? Some BIU flags, or (incorrectly placed) command/condition? + put_long (ad, 0x70000000); + ad += 4; + } + } + if ((opcode & 0x38) == 0x18) { + m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 + D(bug("PROBLEM: fsave_opp post-increment\r\n")); + } + if ((opcode & 0x38) == 0x20) { + m68k_areg (regs, opcode & 7) = ad; + D(bug("fsave_opp pre-decrement %X -> A%d\r\n",ad,opcode & 7)); + } + } +} + +PRIVATE void FFPU do_null_frestore () +{ + // A null-restore operation sets FP7-FP0 positive, nonsignaling NANs. + for( int i=0; i<8; i++ ) { + MAKE_NAN( FPU registers[i], false ); + } + + FPU instruction_address = 0; + set_fpcr(0); + set_fpsr(0); + + x86_status_word = SW_INITIAL; + x86_status_word_accrued = 0; + FPU fpsr.quotient = 0; + + x86_control_word = CW_INITIAL; +/* _asm FLDCW x86_control_word + _asm FNCLEX */ + __asm__ __volatile__("fldcw %0\n\tfnclex" : : "m" (x86_control_word)); +} + +// FSAVE has no pre-decrement +PUBLIC void REGPARAM2 FFPU fpuop_restore(uae_u32 opcode) +{ + uae_u32 ad; + uae_u32 d; + int incr = (opcode & 0x38) == 0x20 ? -1 : 1; + + D(bug("frestore_opp at %08lx\r\n", m68k_getpc ())); + + if (get_fp_ad(opcode, &ad)) { + if (FPU is_integral) { + // 68040 + if (incr < 0) { + D(bug("PROBLEM: frestore_opp incr < 0\r\n")); + // this may be wrong, but it's never called. + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) == 0) { // NULL + D(bug("frestore_opp found NULL frame at %X\r\n",ad-4)); + do_null_frestore(); + } else if ((d & 0x00ff0000) == 0) { // IDLE + D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4)); + } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP + D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4)); + ad -= 44; + } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY + D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4)); + ad -= 92; + } else { + D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d)); + } + } else { + d = get_long (ad); + D(bug("frestore_opp frame at %X = %X\r\n",ad,d)); + ad += 4; + if ((d & 0xff000000) == 0) { // NULL + D(bug("frestore_opp found NULL frame at %X\r\n",ad-4)); + do_null_frestore(); + } else if ((d & 0x00ff0000) == 0) { // IDLE + D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4)); + } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP + D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4)); + ad += 44; + } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY + D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4)); + ad += 92; + } else { + D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d)); + } + } + } else { + // 68881 + if (incr < 0) { + D(bug("PROBLEM: frestore_opp incr < 0\r\n")); + // this may be wrong, but it's never called. + ad -= 4; + d = get_long (ad); + if ((d & 0xff000000) == 0) { // NULL + do_null_frestore(); + } else if ((d & 0x00ff0000) == 0x00180000) { + ad -= 6 * 4; + } else if ((d & 0x00ff0000) == 0x00380000) { + ad -= 14 * 4; + } else if ((d & 0x00ff0000) == 0x00b40000) { + ad -= 45 * 4; + } + } else { + d = get_long (ad); + D(bug("frestore_opp frame at %X = %X\r\n",ad,d)); + ad += 4; + if ((d & 0xff000000) == 0) { // NULL + D(bug("frestore_opp found NULL frame at %X\r\n",ad-4)); + do_null_frestore(); + } else if ((d & 0x00ff0000) == 0x00180000) { // IDLE + D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4)); + ad += 6 * 4; + } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C? + ad += 14 * 4; + D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4)); + } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY + D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4)); + ad += 45 * 4; + } else { + D(bug("PROBLEM: frestore_opp did not find a frame at %X, d=%X\r\n",ad-4,d)); + } + } + } + + if ((opcode & 0x38) == 0x18) { + m68k_areg (regs, opcode & 7) = ad; + D(bug("frestore_opp post-increment %X -> A%d\r\n",ad,opcode & 7)); + } + if ((opcode & 0x38) == 0x20) { + m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881 + D(bug("PROBLEM: frestore_opp pre-decrement\r\n")); + } + } +} + + +/* ---------------------------- Old-style interface ---------------------------- */ + +// #ifndef OPTIMIZED_8BIT_MEMORY_ACCESS +PUBLIC void REGPARAM2 FFPU fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) +{ + uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4); + (*fpufunctbl[mask])(opcode,extra); +} +// #endif + + +/* ---------------------------- Illegal ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_illg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("ILLEGAL F OP 2 %X\r\n",opcode)); + +#if I3_ON_ILLEGAL_FPU_OP +#error "FIXME: asm int 3" + _asm int 3 +#endif + + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); +} + + +/* ---------------------------- FPP -> ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmove_2_ea( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVE -> \r\n")); + + if (put_fp_value (FPU registers[(extra >> 7) & 7], opcode, extra) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + } + + /* + Needed (among other things) by some Pack5/Elems68k transcendental + functions, they require the ACCR_INEX flag after a "MOVE.D, Dreg". + However, now put_fp_value() is responsible of clearing the exceptions + and merging statuses. + */ + + /* + WORD sw_temp; + _asm FNSTSW sw_temp + if(sw_temp & SW_PE) { + _asm FNCLEX + x86_status_word |= SW_PE; + x86_status_word_accrued |= SW_PE; + } + */ + + dump_registers( "END "); +} + + +/* ---------------------------- CONTROL REGS -> Dreg ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM control(none) -> D%d\r\n", opcode & 7)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); + m68k_dreg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpsr(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpcr(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpsr(); + D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); + m68k_dreg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpcr(); + D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); + m68k_dreg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpcr(); + D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpsr(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> D%d\r\n", get_fpcr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpcr(); + D(bug("FMOVEM regs.FPU fpsr (%X) -> D%d\r\n", get_fpsr(), opcode & 7)); + m68k_dreg (regs, opcode & 7) = get_fpsr(); + D(bug("FMOVEM FPU instruction_address (%X) -> D%d\r\n", FPU instruction_address, opcode & 7)); + m68k_dreg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + + +/* ---------------------------- Dreg -> CONTROL REGS ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_none( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM D%d -> control(none)\r\n", opcode & 7)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + FPU instruction_address = m68k_dreg (regs, opcode & 7); + D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr( uae_u32 opcode, uae_u32 extra ) +{ + set_fpsr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + set_fpsr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + FPU instruction_address = m68k_dreg (regs, opcode & 7); + D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + FPU instruction_address = m68k_dreg (regs, opcode & 7); + D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + set_fpsr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + set_fpsr( m68k_dreg (regs, opcode & 7) ); + D(bug("FMOVEM D%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + FPU instruction_address = m68k_dreg (regs, opcode & 7); + D(bug("FMOVEM D%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + + +/* ---------------------------- CONTROL REGS -> Areg ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM control(none) -> A%d\r\n", opcode & 7)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); + m68k_areg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpsr(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpcr(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpsr(); + D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); + m68k_areg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpcr(); + D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); + m68k_areg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpcr(); + D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpsr(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM regs.FPU fpcr (%X) -> A%d\r\n", get_fpcr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpcr(); + D(bug("FMOVEM regs.FPU fpsr (%X) -> A%d\r\n", get_fpsr(), opcode & 7)); + m68k_areg (regs, opcode & 7) = get_fpsr(); + D(bug("FMOVEM FPU instruction_address (%X) -> A%d\r\n", FPU instruction_address, opcode & 7)); + m68k_areg (regs, opcode & 7) = FPU instruction_address; + dump_registers( "END "); +} + + +/* ---------------------------- Areg -> CONTROL REGS ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_none( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM A%d -> control(none)\r\n", opcode & 7)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + FPU instruction_address = m68k_areg (regs, opcode & 7); + D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr( uae_u32 opcode, uae_u32 extra ) +{ + set_fpsr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + set_fpsr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + FPU instruction_address = m68k_areg (regs, opcode & 7); + D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + FPU instruction_address = m68k_areg (regs, opcode & 7); + D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + set_fpsr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ) +{ + set_fpcr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpcr\r\n", opcode & 7, get_fpcr())); + set_fpsr( m68k_areg (regs, opcode & 7) ); + D(bug("FMOVEM A%d (%X) -> regs.FPU fpsr\r\n", opcode & 7, get_fpsr())); + FPU instruction_address = m68k_areg (regs, opcode & 7); + D(bug("FMOVEM A%d (%X) -> FPU instruction_address\r\n", opcode & 7, FPU instruction_address)); + dump_registers( "END "); +} + + +/* ---------------------------- CONTROL REGS -> --MEMORY---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM Control regs (none) -> mem\r\n" )); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 4; + put_long (ad, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 4; + put_long (ad, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 8; + put_long (ad, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); + put_long (ad+4, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 4; + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 8; + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 8; + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 12; + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); + put_long (ad+8, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+8 )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + + +/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM Control regs (none) -> mem\r\n" )); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad )); + m68k_areg (regs, opcode & 7) = ad+4; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); + m68k_areg (regs, opcode & 7) = ad+4; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); + put_long (ad+4, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); + m68k_areg (regs, opcode & 7) = ad+8; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + m68k_areg (regs, opcode & 7) = ad+4; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); + m68k_areg (regs, opcode & 7) = ad+8; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + dump_registers( "END "); + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); + m68k_areg (regs, opcode & 7) = ad+8; + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); + put_long (ad+8, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+8 )); + m68k_areg (regs, opcode & 7) = ad+12; + dump_registers( "END "); + } +} + + +/* ---------------------------- CONTROL REGS -> MEMORY ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM Control regs (none) -> mem\r\n" )); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad )); + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad )); + put_long (ad+4, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+4 )); + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + put_long (ad, get_fpcr()); + D(bug("FMOVEM regs.FPU fpcr (%X) -> mem %X\r\n", get_fpcr(), ad )); + put_long (ad+4, get_fpsr()); + D(bug("FMOVEM regs.FPU fpsr (%X) -> mem %X\r\n", get_fpsr(), ad+4 )); + put_long (ad+8, FPU instruction_address); + D(bug("FMOVEM FPU instruction_address (%X) -> mem %X\r\n", FPU instruction_address, ad+8 )); + dump_registers( "END "); + } +} + + +/* ---------------------------- --MEMORY -> CONTROL REGS ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM --Mem -> control(none)\r\n")); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 4; + FPU instruction_address = get_long (ad); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 4; + set_fpsr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 8; + set_fpsr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); + FPU instruction_address = get_long (ad+4); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 4; + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 8; + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + FPU instruction_address = get_long (ad+4); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 8; + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + set_fpsr( get_long (ad+4) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + ad -= 12; + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + set_fpsr( get_long (ad+4) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); + FPU instruction_address = get_long (ad+8); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+8, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + + +/* ---------------------------- CONTROL REGS -> MEMORY++ ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM Mem++ -> control(none)\r\n")); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + FPU instruction_address = get_long (ad); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad+4; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpsr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); + m68k_areg (regs, opcode & 7) = ad+4; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpsr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); + FPU instruction_address = get_long (ad+4); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad+8; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + m68k_areg (regs, opcode & 7) = ad+4; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + FPU instruction_address = get_long (ad+4); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad+8; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + set_fpsr( get_long (ad+4) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); + m68k_areg (regs, opcode & 7) = ad+8; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + set_fpsr( get_long (ad+4) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); + FPU instruction_address = get_long (ad+8); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+8, FPU instruction_address )); + m68k_areg (regs, opcode & 7) = ad+12; + dump_registers( "END "); + } +} + + +/* ---------------------------- MEMORY -> CONTROL REGS ---------------------------- */ +/* ---------------------------- and ---------------------------- */ +/* ---------------------------- IMMEDIATE -> CONTROL REGS ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVEM Mem -> control(none)\r\n")); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + FPU instruction_address = next_ilong(); + D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + FPU instruction_address = get_long (ad); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad, FPU instruction_address )); + } + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + set_fpsr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpsr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); + } + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + set_fpsr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); + FPU instruction_address = next_ilong(); + D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpsr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad, get_fpsr() )); + FPU instruction_address = get_long (ad+4); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); + } + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + set_fpcr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + } + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + set_fpcr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); + FPU instruction_address = next_ilong(); + D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + FPU instruction_address = get_long (ad+4); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+4, FPU instruction_address )); + } + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + set_fpcr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); + set_fpsr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + set_fpsr( get_long (ad+4) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); + } + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ) +{ + if ((opcode & 0x3f) == 0x3c) { + set_fpcr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpcr\r\n", get_fpcr())); + set_fpsr( next_ilong() ); + D(bug("FMOVEM #<%X> -> regs.FPU fpsr\r\n", get_fpsr())); + FPU instruction_address = next_ilong(); + D(bug("FMOVEM #<%X> -> FPU instruction_address\r\n", FPU instruction_address)); + } else { + uae_u32 ad; + if (get_fp_ad(opcode, &ad)) { + set_fpcr( get_long (ad) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpcr\r\n", ad, get_fpcr() )); + set_fpsr( get_long (ad+4) ); + D(bug("FMOVEM mem %X (%X) -> regs.FPU fpsr\r\n", ad+4, get_fpsr() )); + FPU instruction_address = get_long (ad+8); + D(bug("FMOVEM mem %X (%X) -> FPU instruction_address\r\n", ad+8, FPU instruction_address )); + } + } + dump_registers( "END "); +} + + +/* ---------------------------- FMOVEM MEMORY -> FPP ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + ad -= 4; + wrd3 = get_long (ad); + ad -= 4; + wrd2 = get_long (ad); + ad -= 4; + wrd1 = get_long (ad); + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM memory->FPP\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + wrd1 = get_long (ad); + ad += 4; + wrd2 = get_long (ad); + ad += 4; + wrd3 = get_long (ad); + ad += 4; + to_exten_no_normalize (wrd1, wrd2, wrd3,FPU registers[reg]); + } + list <<= 1; + } + dump_registers( "END "); + } +} + + +/* ---------------------------- FPP -> FMOVEM MEMORY ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=7; reg>=0; reg-- ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + ad -= 4; + put_long (ad, wrd3); + ad -= 4; + put_long (ad, wrd2); + ad -= 4; + put_long (ad, wrd1); + } + list <<= 1; + } + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = extra & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + m68k_areg (regs, opcode & 7) = ad; + dump_registers( "END "); + } +} +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc( uae_u32 opcode, uae_u32 extra ) +{ + uae_u32 ad, list = m68k_dreg (regs, (extra >> 4) & 3) & 0xff; + D(bug("FMOVEM FPP->memory\r\n")); + if (get_fp_ad(opcode, &ad)) { + for( int reg=0; reg<8; reg++ ) { + uae_u32 wrd1, wrd2, wrd3; + if( list & 0x80 ) { + from_exten(FPU registers[reg],&wrd1, &wrd2, &wrd3); + put_long (ad, wrd1); + ad += 4; + put_long (ad, wrd2); + ad += 4; + put_long (ad, wrd3); + ad += 4; + } + list <<= 1; + } + dump_registers( "END "); + } +} + + +/* ---------------------------- FMOVEM CONSTANT ROM -> FPP ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_do_fldpi( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: Pi\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_pi, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fldlg2( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: Log 10 (2)\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_lg2, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_e( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: e\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_e, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fldl2e( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: Log 2 (e)\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_l2e, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_log_10_e( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: Log 10 (e)\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_log_10_e, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fldz( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: zero\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_z, sizeof(fpu_register) ); + x86_status_word = SW_Z; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fldln2( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: ln(2)\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_ln2, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_ln_10( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: ln(10)\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_ln_10, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fld1( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e0\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1, sizeof(fpu_register) ); + x86_status_word = SW_FINITE; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e1\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e1, sizeof(fpu_register) ); + x86_status_word = SW_FINITE; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e2\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e2, sizeof(fpu_register) ); + x86_status_word = SW_FINITE; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e4\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e4, sizeof(fpu_register) ); + x86_status_word = SW_FINITE; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e8( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e8\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e8, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; // Is it really FPSR_EXCEPTION_INEX2? + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e16( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e16\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e16, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e32( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e32\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e32, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e64( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e64\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e64, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e128( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e128\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e128, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e256( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e256\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e256, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e512( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e512\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e512, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1024( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e1024\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e1024, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2048( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e2048\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e2048, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4096( uae_u32 opcode, uae_u32 extra ) +{ + D(bug("FMOVECR memory->FPP FP const: 1.0e4096\r\n")); + memcpy( &FPU registers[(extra>>7) & 7], &const_1e4096, sizeof(fpu_register) ); + x86_status_word = SW_FINITE | FPSR_EXCEPTION_INEX2; + dump_registers( "END "); +} + + +/* -------------------------- 040 ALU -------------------------- */ +PRIVATE void REGPARAM2 FFPU fpuop_do_fsmove( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSMOVE %s\r\n",etos(src))); + do_fsmove( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdmove( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDMOVE %s\r\n",etos(src))); + do_fdmove( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fssqrt( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSSQRT %s\r\n",etos(src))); + do_fssqrt( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdsqrt( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDSQRT %s\r\n",etos(src))); + do_fdsqrt( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsabs( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSABS %s\r\n",etos(src))); + do_fsabs( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdabs( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDABS %s\r\n",etos(src))); + do_fdabs( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsneg( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSNEG %s\r\n",etos(src))); + do_fsneg( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdneg( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDNEG %s\r\n",etos(src))); + do_fdneg( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsdiv( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSDIV %s\r\n",etos(src))); + do_fsdiv( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fddiv( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDDIV %s\r\n",etos(src))); + do_fddiv( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsadd( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSADD %s\r\n",etos(src))); + do_fsadd( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdadd( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDADD %s\r\n",etos(src))); + do_fdadd( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fssub( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSSUB %s\r\n",etos(src))); + do_fssub( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdsub( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDSUB %s\r\n",etos(src))); + do_fdsub( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsmul( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSMUL %s\r\n",etos(src))); + do_fsmul( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdmul( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSMUL %s\r\n",etos(src))); + do_fsmul( FPU registers[reg], src ); + dump_registers( "END "); +} + +/* ---------------------------- ALU ---------------------------- */ + +PRIVATE void REGPARAM2 FFPU fpuop_do_fmove( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FMOVE %s\r\n",etos(src))); + do_fmove( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fint( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FINT %s, opcode=%X, extra=%X, ta %X\r\n",etos(src),opcode,extra,m68k_getpc())); + do_fint( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsinh( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSINH %s\r\n",etos(src))); + do_fsinh( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fintrz( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FINTRZ %s\r\n",etos(src))); + do_fintrz( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsqrt( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSQRT %s\r\n",etos(src))); + do_fsqrt( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_flognp1( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FLOGNP1 %s\r\n",etos(src))); + do_flognp1( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fetoxm1( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FETOXM1 %s\r\n",etos(src))); + do_fetoxm1( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_ftanh( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FTANH %s\r\n",etos(src))); + do_ftanh( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fatan( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FATAN %s\r\n",etos(src))); + do_fatan( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fasin( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FASIN %s\r\n",etos(src))); + do_fasin( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fatanh( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FATANH %s\r\n",etos(src))); + do_fatanh( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsin( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSIN %s\r\n",etos(src))); + do_fsin( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_ftan( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FTAN %s\r\n",etos(src))); + do_ftan( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fetox( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FETOX %s\r\n",etos(src))); + do_fetox( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_ftwotox( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FTWOTOX %s\r\n",etos(src))); + do_ftwotox( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_ftentox( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FTENTOX %s\r\n",etos(src))); + do_ftentox( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_flogn( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FLOGN %s\r\n",etos(src))); + do_flogn( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_flog10( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FLOG10 %s\r\n",etos(src))); + do_flog10( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_flog2( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FLOG2 %s\r\n",etos(src))); + do_flog2( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fabs( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FABS %s\r\n",etos(src))); + do_fabs( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fcosh( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FCOSH %s\r\n",etos(src))); + do_fcosh( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fneg( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FNEG %s\r\n",etos(src))); + do_fneg( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_facos( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FACOS %s\r\n",etos(src))); + do_facos( FPU registers[reg], src ); + build_ex_status(); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fcos( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FCOS %s\r\n",etos(src))); + do_fcos( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fgetexp( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FGETEXP %s\r\n",etos(src))); + + if( IS_INFINITY(src) ) { + MAKE_NAN( FPU registers[reg], IS_NEGATIVE(src) ); + do_ftst( FPU registers[reg] ); + x86_status_word |= SW_IE; + } else { + do_fgetexp( FPU registers[reg], src ); + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fgetman( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FGETMAN %s\r\n",etos(src))); + if( IS_INFINITY(src) ) { + MAKE_NAN( FPU registers[reg], IS_NEGATIVE(src) ); + do_ftst( FPU registers[reg] ); + x86_status_word |= SW_IE; + } else { + do_fgetman( FPU registers[reg], src ); + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fdiv( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FDIV %s\r\n",etos(src))); + do_fdiv( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fmod( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FMOD %s\r\n",etos(src))); + +#if USE_3_BIT_QUOTIENT + do_fmod( FPU registers[reg], src ); +#else + if( (x86_control_word & X86_ROUNDING_MODE) == CW_RC_ZERO ) { + do_fmod_dont_set_cw( FPU registers[reg], src ); + } else { + do_fmod( FPU registers[reg], src ); + } +#endif + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_frem( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FREM %s\r\n",etos(src))); +#if USE_3_BIT_QUOTIENT + do_frem( FPU registers[reg], src ); +#else + if( (x86_control_word & X86_ROUNDING_MODE) == CW_RC_NEAR ) { + do_frem_dont_set_cw( FPU registers[reg], src ); + } else { + do_frem( FPU registers[reg], src ); + } +#endif + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fadd( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FADD %s\r\n",etos(src))); + do_fadd( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fmul( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FMUL %s\r\n",etos(src))); + do_fmul( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsgldiv( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSGLDIV %s\r\n",etos(src))); + do_fsgldiv( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fscale( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSCALE %s, opcode=%X, extra=%X, ta %X\r\n",etos(src),opcode,extra,m68k_getpc())); + if( IS_INFINITY(FPU registers[reg]) ) { + MAKE_NAN( FPU registers[reg], IS_NEGATIVE(FPU registers[reg]) ); + do_ftst( FPU registers[reg] ); + x86_status_word |= SW_IE; + } else { + // When the absolute value of the source operand is >= 2^14, + // an overflow or underflow always results. + do_fscale( FPU registers[reg], src ); + } + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsglmul( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSGLMUL %s\r\n",etos(src))); + do_fsglmul( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsub( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSUB %s\r\n",etos(src))); + do_fsub( FPU registers[reg], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fsincos( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FSINCOS %s\r\n",etos(src))); + do_fsincos( FPU registers[reg], FPU registers[extra & 7], src ); + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_fcmp( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FCMP %s\r\n",etos(src))); + + if( IS_INFINITY(src) ) { + if( IS_NEGATIVE(src) ) { + if( IS_INFINITY(FPU registers[reg]) && IS_NEGATIVE(FPU registers[reg]) ) { + x86_status_word = SW_Z | SW_N; + D(bug("-INF FCMP -INF -> NZ\r\n")); + } else { + x86_status_word = SW_FINITE; + D(bug("X FCMP -INF -> None\r\n")); + } + } else { + if( IS_INFINITY(FPU registers[reg]) && !IS_NEGATIVE(FPU registers[reg]) ) { + x86_status_word = SW_Z; + D(bug("+INF FCMP +INF -> Z\r\n")); + } else { + x86_status_word = SW_N; + D(bug("X FCMP +INF -> N\r\n")); + } + } + } else if( IS_INFINITY(FPU registers[reg]) ) { + if( IS_NEGATIVE(FPU registers[reg]) ) { + x86_status_word = SW_N; + D(bug("-INF FCMP X -> Negative\r\n")); + } else { + x86_status_word = SW_FINITE; + D(bug("+INF FCMP X -> None\r\n")); + } + } else { + do_fcmp( FPU registers[reg], src ); + } + + dump_registers( "END "); +} + +PRIVATE void REGPARAM2 FFPU fpuop_do_ftst( uae_u32 opcode, uae_u32 extra ) +{ + int reg = (extra >> 7) & 7; + fpu_register src; + if (get_fp_value (opcode, extra, src) == 0) { + m68k_setpc (m68k_getpc () - 4); + op_illg (opcode); + dump_registers( "END "); + return; + } + D(bug("FTST %s\r\n",etos(src))); + do_ftst( src ); + build_ex_status(); + dump_registers( "END "); +} + + + +/* ---------------------------- SETUP TABLES ---------------------------- */ + +PRIVATE void FFPU build_fpp_opp_lookup_table () +{ + for( uae_u32 opcode=0; opcode<=0x38; opcode+=8 ) { + for( uae_u32 extra=0; extra<65536; extra++ ) { + uae_u32 mask = (extra & 0xFC7F) | ((opcode & 0x0038) << 4); + fpufunctbl[mask] = & FFPU fpuop_illg; + + switch ((extra >> 13) & 0x7) { + case 3: + fpufunctbl[mask] = & FFPU fpuop_fmove_2_ea; + break; + case 4: + case 5: + if ((opcode & 0x38) == 0) { + if (extra & 0x2000) { // dr bit + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Dreg; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Dreg; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Dreg; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Dreg; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Dreg; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Dreg; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Dreg; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg; + break; + } + } else { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_none; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpiar; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpsr; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpsr_fpiar; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr_fpiar; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar; + break; + } + } + } else if ((opcode & 0x38) == 8) { + if (extra & 0x2000) { // dr bit + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Areg; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Areg; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Areg; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Areg; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Areg; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Areg; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Areg; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg; + break; + } + } else { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_none; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpiar; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpsr; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpsr_fpiar; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr_fpiar; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr_fpsr; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar; + break; + } + } + } else if (extra & 0x2000) { + if ((opcode & 0x38) == 0x20) { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Mem_predecrement; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Mem_predecrement; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Mem_predecrement; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Mem_predecrement; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement; + break; + } + } else if ((opcode & 0x38) == 0x18) { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Mem_postincrement; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Mem_postincrement; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Mem_postincrement; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Mem_postincrement; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement; + break; + } + } else { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_none_2_Mem; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpiar_2_Mem; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_2_Mem; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpsr_fpiar_2_Mem; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_2_Mem; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpiar_2_Mem; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_2_Mem; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem; + break; + } + } + } else { + if ((opcode & 0x38) == 0x20) { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_none_predecrement; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpiar_predecrement; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_predecrement; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_predecrement; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement; + break; + } + } else if ((opcode & 0x38) == 0x18) { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_none_postincrement; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpiar_postincrement; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_postincrement; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_postincrement; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement; + break; + } + } else { + switch( extra & 0x1C00 ) { + case 0x0000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_none_2_Mem; + break; + case 0x0400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpiar_2_Mem; + break; + case 0x0800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_2_Mem; + break; + case 0x0C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem; + break; + case 0x1000: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_2_Mem; + break; + case 0x1400: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem; + break; + case 0x1800: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem; + break; + case 0x1C00: + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem; + break; + } + } + break; + case 6: + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_pred_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_pred_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_pred; + break; + case 1: /* dynamic pred */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred; + break; + case 2: /* static postinc */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_static_postinc; + break; + case 3: /* dynamic postinc */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc; + break; + } + break; + case 7: + switch ((extra >> 11) & 3) { + case 0: /* static pred */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_pred_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_pred_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_pred; + break; + case 1: /* dynamic pred */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred; + break; + case 2: /* static postinc */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_static_postinc; + break; + case 3: /* dynamic postinc */ + if ((opcode & 0x38) == 0x18) // post-increment? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement; + else if ((opcode & 0x38) == 0x20) // pre-decrement? + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement; + else + fpufunctbl[mask] = & FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc; + break; + } + break; + case 0: + case 2: + if ((extra & 0xfc00) == 0x5c00) { + switch (extra & 0x7f) { + case 0x00: + fpufunctbl[mask] = & FFPU fpuop_do_fldpi; + break; + case 0x0b: + fpufunctbl[mask] = & FFPU fpuop_do_fldlg2; + break; + case 0x0c: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_e; + break; + case 0x0d: + fpufunctbl[mask] = & FFPU fpuop_do_fldl2e; + break; + case 0x0e: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_log_10_e; + break; + case 0x0f: + fpufunctbl[mask] = & FFPU fpuop_do_fldz; + break; + case 0x30: + fpufunctbl[mask] = & FFPU fpuop_do_fldln2; + break; + case 0x31: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_ln_10; + break; + case 0x32: + fpufunctbl[mask] = & FFPU fpuop_do_fld1; + break; + case 0x33: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e1; + break; + case 0x34: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e2; + break; + case 0x35: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e4; + break; + case 0x36: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e8; + break; + case 0x37: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e16; + break; + case 0x38: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e32; + break; + case 0x39: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e64; + break; + case 0x3a: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e128; + break; + case 0x3b: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e256; + break; + case 0x3c: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e512; + break; + case 0x3d: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e1024; + break; + case 0x3e: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e2048; + break; + case 0x3f: + fpufunctbl[mask] = & FFPU fpuop_do_load_const_1e4096; + break; + } + break; + } + + if (FPU is_integral) { + switch (extra & 0x7f) { + case 0x40: + fpufunctbl[mask] = & FFPU fpuop_do_fsmove; + break; + case 0x44: + fpufunctbl[mask] = & FFPU fpuop_do_fdmove; + break; + case 0x41: + fpufunctbl[mask] = & FFPU fpuop_do_fssqrt; + break; + case 0x45: + fpufunctbl[mask] = & FFPU fpuop_do_fdsqrt; + break; + case 0x58: + fpufunctbl[mask] = & FFPU fpuop_do_fsabs; + break; + case 0x5c: + fpufunctbl[mask] = & FFPU fpuop_do_fdabs; + break; + case 0x5a: + fpufunctbl[mask] = & FFPU fpuop_do_fsneg; + break; + case 0x5e: + fpufunctbl[mask] = & FFPU fpuop_do_fdneg; + break; + case 0x60: + fpufunctbl[mask] = & FFPU fpuop_do_fsdiv; + break; + case 0x64: + fpufunctbl[mask] = & FFPU fpuop_do_fddiv; + break; + case 0x62: + fpufunctbl[mask] = & FFPU fpuop_do_fsadd; + break; + case 0x66: + fpufunctbl[mask] = & FFPU fpuop_do_fdadd; + break; + case 0x68: + fpufunctbl[mask] = & FFPU fpuop_do_fssub; + break; + case 0x6c: + fpufunctbl[mask] = & FFPU fpuop_do_fdsub; + break; + case 0x63: + fpufunctbl[mask] = & FFPU fpuop_do_fsmul; + break; + case 0x67: + fpufunctbl[mask] = & FFPU fpuop_do_fdmul; + break; + default: + break; + } + } + + switch (extra & 0x7f) { + case 0x00: + fpufunctbl[mask] = & FFPU fpuop_do_fmove; + break; + case 0x01: + fpufunctbl[mask] = & FFPU fpuop_do_fint; + break; + case 0x02: + fpufunctbl[mask] = & FFPU fpuop_do_fsinh; + break; + case 0x03: + fpufunctbl[mask] = & FFPU fpuop_do_fintrz; + break; + case 0x04: + fpufunctbl[mask] = & FFPU fpuop_do_fsqrt; + break; + case 0x06: + fpufunctbl[mask] = & FFPU fpuop_do_flognp1; + break; + case 0x08: + fpufunctbl[mask] = & FFPU fpuop_do_fetoxm1; + break; + case 0x09: + fpufunctbl[mask] = & FFPU fpuop_do_ftanh; + break; + case 0x0a: + fpufunctbl[mask] = & FFPU fpuop_do_fatan; + break; + case 0x0c: + fpufunctbl[mask] = & FFPU fpuop_do_fasin; + break; + case 0x0d: + fpufunctbl[mask] = & FFPU fpuop_do_fatanh; + break; + case 0x0e: + fpufunctbl[mask] = & FFPU fpuop_do_fsin; + break; + case 0x0f: + fpufunctbl[mask] = & FFPU fpuop_do_ftan; + break; + case 0x10: + fpufunctbl[mask] = & FFPU fpuop_do_fetox; + break; + case 0x11: + fpufunctbl[mask] = & FFPU fpuop_do_ftwotox; + break; + case 0x12: + fpufunctbl[mask] = & FFPU fpuop_do_ftentox; + break; + case 0x14: + fpufunctbl[mask] = & FFPU fpuop_do_flogn; + break; + case 0x15: + fpufunctbl[mask] = & FFPU fpuop_do_flog10; + break; + case 0x16: + fpufunctbl[mask] = & FFPU fpuop_do_flog2; + break; + case 0x18: + fpufunctbl[mask] = & FFPU fpuop_do_fabs; + break; + case 0x19: + fpufunctbl[mask] = & FFPU fpuop_do_fcosh; + break; + case 0x1a: + fpufunctbl[mask] = & FFPU fpuop_do_fneg; + break; + case 0x1c: + fpufunctbl[mask] = & FFPU fpuop_do_facos; + break; + case 0x1d: + fpufunctbl[mask] = & FFPU fpuop_do_fcos; + break; + case 0x1e: + fpufunctbl[mask] = & FFPU fpuop_do_fgetexp; + break; + case 0x1f: + fpufunctbl[mask] = & FFPU fpuop_do_fgetman; + break; + case 0x20: + fpufunctbl[mask] = & FFPU fpuop_do_fdiv; + break; + case 0x21: + fpufunctbl[mask] = & FFPU fpuop_do_fmod; + break; + case 0x22: + fpufunctbl[mask] = & FFPU fpuop_do_fadd; + break; + case 0x23: + fpufunctbl[mask] = & FFPU fpuop_do_fmul; + break; + case 0x24: + fpufunctbl[mask] = & FFPU fpuop_do_fsgldiv; + break; + case 0x25: + fpufunctbl[mask] = & FFPU fpuop_do_frem; + break; + case 0x26: + fpufunctbl[mask] = & FFPU fpuop_do_fscale; + break; + case 0x27: + fpufunctbl[mask] = & FFPU fpuop_do_fsglmul; + break; + case 0x28: + fpufunctbl[mask] = & FFPU fpuop_do_fsub; + break; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + fpufunctbl[mask] = & FFPU fpuop_do_fsincos; + break; + case 0x38: + fpufunctbl[mask] = & FFPU fpuop_do_fcmp; + break; + case 0x3a: + fpufunctbl[mask] = & FFPU fpuop_do_ftst; + break; + } + } + } + } + } +} + +/* ---------------------------- CONSTANTS ---------------------------- */ + +PRIVATE void FFPU set_constant ( fpu_register & f, char *name, double value, uae_s32 mult ) +{ + FPU_CONSISTENCY_CHECK_START(); + if(mult == 1) { +/* _asm { + MOV ESI, [f] + FLD QWORD PTR [value] + FSTP TBYTE PTR [ESI] + } */ + __asm__ __volatile__( + "fldl %1\n" + "fstpt %0\n" + : "=m" (f) + : "m" (value) + ); + } else { +/* _asm { + MOV ESI, [f] + FILD DWORD PTR [mult] + FLD QWORD PTR [value] + FMUL + FSTP TBYTE PTR [ESI] + } */ + __asm__ __volatile__( + "fildl %2\n" + "fldl %1\n" + "fmul \n" + "fstpt %0\n" + : "=m" (f) + : "m" (value), "m" (mult) + ); + } + D(bug("set_constant (%s,%.04f) = %s\r\n",name,(float)value,etos(f))); + FPU_CONSISTENCY_CHECK_STOP( mult==1 ? "set_constant(mult==1)" : "set_constant(mult>1)" ); +} + +PRIVATE void FFPU do_fldpi ( fpu_register & dest ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + FLDPI + FXAM + FNSTSW x86_status_word + MOV EDI, [dest] + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldpi \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fldpi"); +} + +PRIVATE void FFPU do_fldlg2 ( fpu_register & dest ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + FLDLG2 + FXAM + FNSTSW x86_status_word + MOV EDI, [dest] + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldlg2 \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fldlg2"); +} + +PRIVATE void FFPU do_fldl2e ( fpu_register & dest ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + FLDL2E + FXAM + FNSTSW x86_status_word + MOV EDI, [dest] + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldl2e \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fldl2e"); +} + +PRIVATE void FFPU do_fldz ( fpu_register & dest ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + FLDZ + FXAM + FNSTSW x86_status_word + MOV EDI, [dest] + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldz \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fldz"); +} + +PRIVATE void FFPU do_fldln2 ( fpu_register & dest ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + FLDLN2 + FXAM + FNSTSW x86_status_word + MOV EDI, [dest] + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fldln2 \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fldln2"); +} + +PRIVATE void FFPU do_fld1 ( fpu_register & dest ) +{ + FPU_CONSISTENCY_CHECK_START(); +/* _asm { + FLD1 + FXAM + FNSTSW x86_status_word + MOV EDI, [dest] + FSTP TBYTE PTR [EDI] + } */ + __asm__ __volatile__( + "fld1 \n" + "fxam \n" + "fnstsw %0\n" + "fstpt %1\n" + : "=m" (x86_status_word), "=m" (dest) + ); + FPU_CONSISTENCY_CHECK_STOP("do_fld1"); +} + + +void fpu_set_fpsr(uae_u32 new_fpsr) +{ + set_fpsr(new_fpsr); +} + +uae_u32 fpu_get_fpsr(void) +{ + return get_fpsr(); +} + +void fpu_set_fpcr(uae_u32 new_fpcr) +{ + set_fpcr(new_fpcr); +} + +uae_u32 fpu_get_fpcr(void) +{ + return get_fpcr(); +} + +/* ---------------------------- MAIN INIT ---------------------------- */ + +#ifdef HAVE_SIGACTION +// Mega hackaround-that-happens-to-work: the following way to handle +// SIGFPE just happens to make the "fsave" below in fpu_init() *NOT* +// to abort with a floating point exception. However, we never +// actually reach sigfpe_handler(). +static void sigfpe_handler(int code, siginfo_t *sip, void *) +{ + if (code == SIGFPE && sip->si_code == FPE_FLTINV) { + fprintf(stderr, "Invalid floating point operation\n"); + abort(); + } +} +#endif + +PUBLIC void FFPU fpu_init( bool integral_68040 ) +{ + static bool done_first_time_initialization = false; + if (!done_first_time_initialization) { + fpu_init_native_fflags(); + fpu_init_native_exceptions(); + fpu_init_native_accrued_exceptions(); +#ifdef HAVE_SIGACTION + struct sigaction fpe_sa; + sigemptyset(&fpe_sa.sa_mask); + fpe_sa.sa_sigaction = sigfpe_handler; + fpe_sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &fpe_sa, 0); +#endif + done_first_time_initialization = true; + } + + __asm__ __volatile__("fsave %0" : "=m" (m_fpu_state_original)); + + FPU is_integral = integral_68040; + FPU instruction_address = 0; + set_fpcr(0); + set_fpsr(0); + + x86_control_word = CW_INITIAL; + x86_status_word = SW_INITIAL; + x86_status_word_accrued = 0; + FPU fpsr.quotient = 0; + + for( int i=0; i<8; i++ ) { + MAKE_NAN( FPU registers[i], false ); + } + + build_fpp_opp_lookup_table(); + +/* _asm { + FNINIT + FLDCW x86_control_word + } */ + __asm__ __volatile__("fninit\nfldcw %0" : : "m" (x86_control_word)); + + do_fldpi( const_pi ); + do_fldlg2( const_lg2 ); + do_fldl2e( const_l2e ); + do_fldz( const_z ); + do_fldln2( const_ln2 ); + do_fld1( const_1 ); + + set_constant( const_e, "e", exp (1.0), 1 ); + set_constant( const_log_10_e, "Log 10 (e)", log (exp (1.0)) / log (10.0), 1 ); + set_constant( const_ln_10, "ln(10)", log (10.0), 1 ); + set_constant( const_1e1, "1.0e1", 1.0e1, 1 ); + set_constant( const_1e2, "1.0e2", 1.0e2, 1 ); + set_constant( const_1e4, "1.0e4", 1.0e4, 1 ); + set_constant( const_1e8, "1.0e8", 1.0e8, 1 ); + set_constant( const_1e16, "1.0e16", 1.0e16, 1 ); + set_constant( const_1e32, "1.0e32", 1.0e32, 1 ); + set_constant( const_1e64, "1.0e64", 1.0e64, 1 ) ; + set_constant( const_1e128, "1.0e128", 1.0e128, 1 ); + set_constant( const_1e256, "1.0e256", 1.0e256, 1 ); + set_constant( const_1e512, "1.0e512", 1.0e256, 10 ); + set_constant( const_1e1024, "1.0e1024", 1.0e256, 100 ); + set_constant( const_1e2048, "1.0e2048", 1.0e256, 1000 ); + set_constant( const_1e4096, "1.0e4096", 1.0e256, 10000 ); + + // Just in case. +/* _asm { + FNINIT + FLDCW x86_control_word + } */ + __asm__ __volatile__("fninit\nfldcw %0" : : "m" (x86_control_word)); +} + +PUBLIC void FFPU fpu_exit( void ) +{ + __asm__ __volatile__("frstor %0" : : "m" (m_fpu_state_original)); +} + +PUBLIC void FFPU fpu_reset( void ) +{ + fpu_exit(); + fpu_init(FPU is_integral); +} diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86.h b/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86.h new file mode 100644 index 000000000..c42bfa91b --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86.h @@ -0,0 +1,384 @@ +/* + * fpu/fpu_x86.h - Extra Definitions for the X86 assembly FPU core + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_X86_H +#define FPU_X86_H + +/* NOTE: this file shall be included from fpu/fpu_x86.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +// Status word +PRIVATE uae_u32 x86_status_word; +PRIVATE uae_u32 x86_status_word_accrued; + +// FPU jump table +typedef void REGPARAM2 ( *fpuop_func )( uae_u32, uae_u32 ); +PRIVATE fpuop_func fpufunctbl[65536]; + +// FPU consistency +PRIVATE uae_u32 checked_sw_atstart; + +// FMOVECR constants supported byt x86 FPU +PRIVATE fpu_register const_pi; +PRIVATE fpu_register const_lg2; +PRIVATE fpu_register const_l2e; +PRIVATE fpu_register const_z; +PRIVATE fpu_register const_ln2; +PRIVATE fpu_register const_1; + +// FMOVECR constants not not suported by x86 FPU +PRIVATE fpu_register const_e; +PRIVATE fpu_register const_log_10_e; +PRIVATE fpu_register const_ln_10; +PRIVATE fpu_register const_1e1; +PRIVATE fpu_register const_1e2; +PRIVATE fpu_register const_1e4; +PRIVATE fpu_register const_1e8; +PRIVATE fpu_register const_1e16; +PRIVATE fpu_register const_1e32; +PRIVATE fpu_register const_1e64; +PRIVATE fpu_register const_1e128; +PRIVATE fpu_register const_1e256; +PRIVATE fpu_register const_1e512; +PRIVATE fpu_register const_1e1024; +PRIVATE fpu_register const_1e2048; +PRIVATE fpu_register const_1e4096; + +// Saved host FPU state +PRIVATE uae_u8 m_fpu_state_original[108]; // 90/94/108 + +/* -------------------------------------------------------------------------- */ +/* --- Methods --- */ +/* -------------------------------------------------------------------------- */ + +// Debug support functions +PRIVATE void FFPU dump_first_bytes_buf(char *b, uae_u8* buf, uae_s32 actual); +PRIVATE char * FFPU etos(fpu_register const & e) REGPARAM; + +// FPU consistency +PRIVATE void FFPU FPU_CONSISTENCY_CHECK_START(void); +PRIVATE void FFPU FPU_CONSISTENCY_CHECK_STOP(const char *name); + +// Get special floating-point value class +PRIVATE inline uae_u32 FFPU IS_INFINITY (fpu_register const & f); +PRIVATE inline uae_u32 FFPU IS_NAN (fpu_register const & f); +PRIVATE inline uae_u32 FFPU IS_ZERO (fpu_register const & f); +PRIVATE inline uae_u32 FFPU IS_NEGATIVE (fpu_register const & f); + +// Make a special floating-point value +PRIVATE inline void FFPU MAKE_NAN (fpu_register & f, bool negative); +PRIVATE inline void FFPU MAKE_INF_POSITIVE (fpu_register & f); +PRIVATE inline void FFPU MAKE_INF_NEGATIVE (fpu_register & f); +PRIVATE inline void FFPU MAKE_ZERO_POSITIVE (fpu_register & f); +PRIVATE inline void FFPU MAKE_ZERO_NEGATIVE (fpu_register & f); + +// Conversion from extended floating-point values +PRIVATE uae_s32 FFPU extended_to_signed_32 ( fpu_register const & f ) REGPARAM; +PRIVATE uae_s16 FFPU extended_to_signed_16 ( fpu_register const & f ) REGPARAM; +PRIVATE uae_s8 FFPU extended_to_signed_8 ( fpu_register const & f ) REGPARAM; +PRIVATE fpu_double FFPU extended_to_double( fpu_register const & f ) REGPARAM; +PRIVATE uae_u32 FFPU from_single ( fpu_register const & f ) REGPARAM; +PRIVATE void FFPU from_exten ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3 ) REGPARAM; +PRIVATE void FFPU from_double ( fpu_register const & f, uae_u32 *wrd1, uae_u32 *wrd2 ) REGPARAM; +PRIVATE void FFPU from_pack (fpu_double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) REGPARAM; + +// Conversion to extended floating-point values +PRIVATE void FFPU signed_to_extended ( uae_s32 x, fpu_register & f ) REGPARAM; +PRIVATE void FFPU double_to_extended ( double x, fpu_register & f ) REGPARAM; +PRIVATE void FFPU to_single ( uae_u32 src, fpu_register & f ) REGPARAM; +PRIVATE void FFPU to_exten_no_normalize ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) REGPARAM; +PRIVATE void FFPU to_exten ( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & f ) REGPARAM; +PRIVATE void FFPU to_double ( uae_u32 wrd1, uae_u32 wrd2, fpu_register & f ) REGPARAM; +PRIVATE fpu_double FFPU to_pack(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) REGPARAM; + +// Atomic floating-point arithmetic operations +PRIVATE void FFPU do_fmove ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fmove_no_status ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fint ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fintrz ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsqrt ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_ftst ( fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsinh ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_flognp1 ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fetoxm1 ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_ftanh ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fatan ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fasin ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fatanh ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fetox ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_ftwotox ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_ftentox ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_flogn ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_flog10 ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_flog2 ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_facos ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fcosh ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsin ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_ftan ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fabs ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fneg ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fcos ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fgetexp ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fgetman ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fdiv ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fmod ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_frem ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fmod_dont_set_cw ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_frem_dont_set_cw ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fadd ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fmul ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsgldiv ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fscale ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsglmul ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsub ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fsincos ( fpu_register & dest_sin, fpu_register & dest_cos, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fcmp ( fpu_register & dest, fpu_register const & src ) REGPARAM; +PRIVATE void FFPU do_fldpi ( fpu_register & dest ) REGPARAM; +PRIVATE void FFPU do_fldlg2 ( fpu_register & dest ) REGPARAM; +PRIVATE void FFPU do_fldl2e ( fpu_register & dest ) REGPARAM; +PRIVATE void FFPU do_fldz ( fpu_register & dest ) REGPARAM; +PRIVATE void FFPU do_fldln2 ( fpu_register & dest ) REGPARAM; +PRIVATE void FFPU do_fld1 ( fpu_register & dest ) REGPARAM; + +// Instructions handlers +PRIVATE void REGPARAM2 FFPU fpuop_illg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmove_2_ea( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Dreg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_none( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Dreg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Areg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_none( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Areg_2_fpcr_fpsr_fpiar( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_none_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_none_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpcr_fpsr_fpiar_2_Mem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_pred( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_pred( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_static_postinc( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_Mem_2_fpp_dynamic_postinc( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_pred( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_pred( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_static_postinc( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_postincrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc_predecrement( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_fmovem_fpp_2_Mem_dynamic_postinc( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fldpi( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fldlg2( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_e( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fldl2e( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_log_10_e( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fldz( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fldln2( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_ln_10( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fld1( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e8( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e16( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e32( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e64( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e128( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e256( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e512( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e1024( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e2048( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_load_const_1e4096( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fmove( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fint( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsinh( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fintrz( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsqrt( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_flognp1( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fetoxm1( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_ftanh( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fatan( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fasin( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fatanh( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsin( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_ftan( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fetox( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_ftwotox( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_ftentox( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_flogn( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_flog10( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_flog2( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fabs( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fcosh( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fneg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_facos( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fcos( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fgetexp( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fgetman( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdiv( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fmod( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_frem( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fadd( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fmul( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsgldiv( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fscale( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsglmul( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsub( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsincos( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fcmp( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_ftst( uae_u32 opcode, uae_u32 extra ); + +// 040 +PRIVATE void REGPARAM2 FFPU fpuop_do_fsmove( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdmove( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fssqrt( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdsqrt( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsabs( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdabs( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsneg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdneg( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsdiv( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fddiv( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsadd( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdadd( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fssub( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdsub( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fsmul( uae_u32 opcode, uae_u32 extra ); +PRIVATE void REGPARAM2 FFPU fpuop_do_fdmul( uae_u32 opcode, uae_u32 extra ); + +// Get & Put floating-point values +PRIVATE int FFPU get_fp_value (uae_u32 opcode, uae_u32 extra, fpu_register & src) REGPARAM; +PRIVATE int FFPU put_fp_value (fpu_register const & value, uae_u32 opcode, uae_u32 extra) REGPARAM; +PRIVATE int FFPU get_fp_ad(uae_u32 opcode, uae_u32 * ad) REGPARAM; + +// Floating-point condition-based instruction handlers +PRIVATE int FFPU fpp_cond(uae_u32 opcode, int condition) REGPARAM; + +// Misc functions +PRIVATE void inline FFPU set_host_fpu_control_word (); +PRIVATE void inline FFPU SET_BSUN_ON_NAN (); +PRIVATE void inline FFPU build_ex_status (); +PRIVATE void FFPU do_null_frestore (); +PRIVATE void FFPU build_fpp_opp_lookup_table (); +PRIVATE void FFPU set_constant ( fpu_register & f, char *name, double value, uae_s32 mult ); + +#endif /* FPU_X86_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86_asm.h b/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86_asm.h new file mode 100644 index 000000000..6e5a37667 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/fpu_x86_asm.h @@ -0,0 +1,104 @@ +/* + * fpu/fpu_x86_asm.h - Extra Definitions for the X86 assembly FPU core + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define DEFINE_X86_MACRO(name, value) \ + asm(".local " #name "\n\t" #name " = " #value) + +DEFINE_X86_MACRO(BSUN, 0x00008000); +DEFINE_X86_MACRO(SNAN, 0x00004000); +DEFINE_X86_MACRO(OPERR, 0x00002000); +DEFINE_X86_MACRO(OVFL, 0x00001000); +DEFINE_X86_MACRO(UNFL, 0x00000800); +DEFINE_X86_MACRO(DZ, 0x00000400); +DEFINE_X86_MACRO(INEX2, 0x00000200); +DEFINE_X86_MACRO(INEX1, 0x00000100); +DEFINE_X86_MACRO(ACCR_IOP, 0x80); +DEFINE_X86_MACRO(ACCR_OVFL, 0x40); +DEFINE_X86_MACRO(ACCR_UNFL, 0x20); +DEFINE_X86_MACRO(ACCR_DZ, 0x10); +DEFINE_X86_MACRO(ACCR_INEX, 0x08); +DEFINE_X86_MACRO(ROUND_CONTROL_MASK, 0x30); +DEFINE_X86_MACRO(ROUND_TO_NEAREST, 0); +DEFINE_X86_MACRO(ROUND_TO_ZERO, 0x10); +DEFINE_X86_MACRO(ROUND_TO_NEGATIVE_INFINITY, 0x20); +DEFINE_X86_MACRO(ROUND_TO_POSITIVE_INFINITY, 0x30); +DEFINE_X86_MACRO(PRECISION_CONTROL_MASK, 0xC0); +DEFINE_X86_MACRO(PRECISION_CONTROL_EXTENDED, 0); +DEFINE_X86_MACRO(PRECISION_CONTROL_DOUBLE, 0x80); +DEFINE_X86_MACRO(PRECISION_CONTROL_SINGLE, 0x40); +DEFINE_X86_MACRO(PRECISION_CONTROL_UNDEFINED, 0xC0); +DEFINE_X86_MACRO(CW_RESET, 0x0040); +DEFINE_X86_MACRO(CW_FINIT, 0x037F); +DEFINE_X86_MACRO(SW_RESET, 0x0000); +DEFINE_X86_MACRO(SW_FINIT, 0x0000); +DEFINE_X86_MACRO(TW_RESET, 0x5555); +DEFINE_X86_MACRO(TW_FINIT, 0x0FFF); +DEFINE_X86_MACRO(CW_X, 0x1000); +DEFINE_X86_MACRO(CW_RC_ZERO, 0x0C00); +DEFINE_X86_MACRO(CW_RC_UP, 0x0800); +DEFINE_X86_MACRO(CW_RC_DOWN, 0x0400); +DEFINE_X86_MACRO(CW_RC_NEAR, 0x0000); +DEFINE_X86_MACRO(CW_PC_EXTENDED, 0x0300); +DEFINE_X86_MACRO(CW_PC_DOUBLE, 0x0200); +DEFINE_X86_MACRO(CW_PC_RESERVED, 0x0100); +DEFINE_X86_MACRO(CW_PC_SINGLE, 0x0000); +DEFINE_X86_MACRO(CW_PM, 0x0020); +DEFINE_X86_MACRO(CW_UM, 0x0010); +DEFINE_X86_MACRO(CW_OM, 0x0008); +DEFINE_X86_MACRO(CW_ZM, 0x0004); +DEFINE_X86_MACRO(CW_DM, 0x0002); +DEFINE_X86_MACRO(CW_IM, 0x0001); +DEFINE_X86_MACRO(SW_B, 0x8000); +DEFINE_X86_MACRO(SW_C3, 0x4000); +DEFINE_X86_MACRO(SW_TOP_7, 0x3800); +DEFINE_X86_MACRO(SW_TOP_6, 0x3000); +DEFINE_X86_MACRO(SW_TOP_5, 0x2800); +DEFINE_X86_MACRO(SW_TOP_4, 0x2000); +DEFINE_X86_MACRO(SW_TOP_3, 0x1800); +DEFINE_X86_MACRO(SW_TOP_2, 0x1000); +DEFINE_X86_MACRO(SW_TOP_1, 0x0800); +DEFINE_X86_MACRO(SW_TOP_0, 0x0000); +DEFINE_X86_MACRO(SW_C2, 0x0400); +DEFINE_X86_MACRO(SW_C1, 0x0200); +DEFINE_X86_MACRO(SW_C0, 0x0100); +DEFINE_X86_MACRO(SW_ES, 0x0080); +DEFINE_X86_MACRO(SW_SF, 0x0040); +DEFINE_X86_MACRO(SW_PE, 0x0020); +DEFINE_X86_MACRO(SW_UE, 0x0010); +DEFINE_X86_MACRO(SW_OE, 0x0008); +DEFINE_X86_MACRO(SW_ZE, 0x0004); +DEFINE_X86_MACRO(SW_DE, 0x0002); +DEFINE_X86_MACRO(SW_IE, 0x0001); +DEFINE_X86_MACRO(X86_ROUNDING_MODE, 0x0C00); +DEFINE_X86_MACRO(X86_ROUNDING_PRECISION, 0x0300); + +#undef DEFINE_X86_MACRO diff --git a/BasiliskII/src/uae_cpu_2021/fpu/impl.h b/BasiliskII/src/uae_cpu_2021/fpu/impl.h new file mode 100644 index 000000000..ec5648a94 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/impl.h @@ -0,0 +1,158 @@ +/* + * fpu/impl.h - extra functions and inline implementations + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * 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. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_IMPL_H +#define FPU_IMPL_H + +/* NOTE: this file shall be included from fpu/core.h */ +#undef PUBLIC +#define PUBLIC /**/ + +#undef PRIVATE +#define PRIVATE /**/ + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* -------------------------------------------------------------------------- */ +/* --- X86 assembly fpu specific methods --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_X86 + +/* Return the floating-point status register in m68k format */ +static inline uae_u32 FFPU get_fpsr(void) +{ + return to_m68k_fpcond[(x86_status_word & 0x4700) >> 8] + | FPU fpsr.quotient + | exception_host2mac[x86_status_word & (SW_FAKE_BSUN|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE)] + | accrued_exception_host2mac[x86_status_word_accrued & (SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE)] + ; +} + +/* Set the floating-point status register from an m68k format */ +static inline void FFPU set_fpsr(uae_u32 new_fpsr) +{ + x86_status_word = to_host_fpcond[(new_fpsr & FPSR_CCB) >> 24 ] + | exception_mac2host[(new_fpsr & FPSR_EXCEPTION_STATUS) >> 8]; + x86_status_word_accrued = accrued_exception_mac2host[(new_fpsr & FPSR_ACCRUED_EXCEPTION) >> 3]; +} + +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Original UAE and IEEE FPU core methods --- */ +/* -------------------------------------------------------------------------- */ + +#ifndef FPU_X86 + +/* Return the floating-point status register in m68k format */ +static inline uae_u32 FFPU get_fpsr(void) +{ + uae_u32 condition_codes = get_fpccr(); + uae_u32 exception_status = get_exception_status(); + uae_u32 accrued_exception = get_accrued_exception(); + uae_u32 quotient = FPU fpsr.quotient; + return (condition_codes | quotient | exception_status | accrued_exception); +} + +/* Set the floating-point status register from an m68k format */ +static inline void FFPU set_fpsr(uae_u32 new_fpsr) +{ + set_fpccr ( new_fpsr & FPSR_CCB ); + set_exception_status ( new_fpsr & FPSR_EXCEPTION_STATUS ); + set_accrued_exception ( new_fpsr & FPSR_ACCRUED_EXCEPTION ); + FPU fpsr.quotient = new_fpsr & FPSR_QUOTIENT; +} + +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Common routines for control word --- */ +/* -------------------------------------------------------------------------- */ + +/* Return the floating-point control register in m68k format */ +static inline uae_u32 FFPU get_fpcr(void) +{ + // according to the manual, the msb bits are always zero. + // According to Toni Wilen, on '040 the least + // significant 4 bits are not masked out + return FPU fpcr & (CPUType == 4 ? 0xffff : 0xfff0); +} + +/* Set the floating-point control register from an m68k format */ +static inline void FFPU set_fpcr(uae_u32 new_fpcr) +{ + FPU fpcr = new_fpcr; + set_rounding_precision ( new_fpcr & FPCR_ROUNDING_PRECISION); + set_rounding_mode ( new_fpcr & FPCR_ROUNDING_MODE ); + set_host_control_word(); +} + +/* -------------------------------------------------------------------------- */ +/* --- Specific part to X86 assembly FPU --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_X86 + +/* Retrieve a floating-point register value and convert it to double precision */ +static inline double FFPU fpu_get_register(int r) +{ + /* only used for debug output; no need for any fancy asm here */ + return FPU registers[r]; +} + +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Specific to original UAE or new IEEE-based FPU core --- */ +/* -------------------------------------------------------------------------- */ + +#if defined(FPU_UAE) || defined(FPU_IEEE) + +/* Retrieve a floating-point register value and convert it to double precision */ +static inline double FFPU fpu_get_register(int r) +{ + return FPU registers[r]; +} + +#endif + +#endif /* FPU_IMPL_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/mathlib.cpp b/BasiliskII/src/uae_cpu_2021/fpu/mathlib.cpp new file mode 100644 index 000000000..c96169271 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/mathlib.cpp @@ -0,0 +1,109 @@ +/* + * fpu/mathlib.cpp - Floating-point math support library + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* NOTE: this file shall be included only from fpu/fpu_*.cpp */ +#undef PRIVATE +#define PRIVATE static + +#undef PUBLIC +#define PUBLIC /**/ + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) + +#if !defined(HAVE_EXP10L) && !defined(HAVE_POW10L) +PRIVATE fpu_extended fp_do_pow(fpu_extended x, fpu_extended y) +{ + fpu_extended value, exponent; + uae_s64 p = (uae_s64)y; + + if (x == 0.0) { + if (y > 0.0) + return (y == (double) p && (p & 1) != 0 ? x : 0.0); + else if (y < 0.0) + return (y == (double) p && (-p & 1) != 0 ? 1.0 / x : 1.0 / fp_fabs (x)); + } + + if (y == (double) p) { + fpu_extended r = 1.0; + if (p == 0) + return 1.0; + if (p < 0) { + p = -p; + x = 1.0 / x; + } + while (1) { + if (p & 1) + r *= x; + p >>= 1; + if (p == 0) + return r; + x *= x; + } + } + + __asm__ __volatile__("fyl2x" : "=t" (value) : "0" (x), "u" (1.0) : "st(1)"); + __asm__ __volatile__("fmul %%st(1) # y * log2(x)\n\t" + "fst %%st(1)\n\t" + "frndint # int(y * log2(x))\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(y * log2(x))\n\t" + "f2xm1 # 2^(fract(y * log2(x))) - 1\n\t" + : "=t" (value), "=u" (exponent) : "0" (y), "1" (value)); + value += 1.0; + __asm__ __volatile__("fscale" : "=t" (value) : "0" (value), "u" (exponent)); + return value; +} +#endif + +#ifndef HAVE_LOG1PL +PRIVATE fpu_extended fp_do_log1p(fpu_extended x) +{ + // TODO: handle NaN and +inf/-inf + fpu_extended value; + // The fyl2xp1 can only be used for values in + // -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2 + // 0.29 is a safe value. + if (fp_fabs(x) <= 0.29) + __asm__ __volatile__("fldln2; fxch; fyl2xp1" : "=t" (value) : "0" (x)); + else + __asm__ __volatile__("fldln2; fxch; fyl2x" : "=t" (value) : "0" (x + 1.0)); + return value; +} +#endif + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/fpu/mathlib.h b/BasiliskII/src/uae_cpu_2021/fpu/mathlib.h new file mode 100644 index 000000000..8b03dd2af --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/mathlib.h @@ -0,0 +1,1220 @@ +/* + * fpu/mathlib.h - Floating-point math support library + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_MATHLIB_H +#define FPU_MATHLIB_H + +/* NOTE: this file shall be included only from fpu/fpu_*.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +// Define the following macro if branches are expensive. If so, +// integer-based isnan() and isinf() functions are implemented. +// TODO: move to Makefile.in +#define BRANCHES_ARE_EXPENSIVE 1 + +// Use ISO C99 extended-precision math functions (glibc 2.1+) +#define FPU_USE_ISO_C99 1 + +#if defined(FPU_USE_ISO_C99) +// NOTE: no prior shall be included at this point +#define __USE_ISOC99 1 // for glibc 2.2.X and newer +#define __USE_ISOC9X 1 // for glibc 2.1.X +#include +#else +#include +using namespace std; +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Floating-point register types --- */ +/* -------------------------------------------------------------------------- */ + +// Single : S 8*E 23*F +#define FP_SINGLE_EXP_MAX 0xff +#define FP_SINGLE_EXP_BIAS 0x7f + +// Double : S 11*E 52*F +#define FP_DOUBLE_EXP_MAX 0x7ff +#define FP_DOUBLE_EXP_BIAS 0x3ff + +// Extended : S 15*E 64*F +#define FP_EXTENDED_EXP_MAX 0x7fff +#define FP_EXTENDED_EXP_BIAS 0x3fff + +// Zeroes : E = 0 & F = 0 +// Infinities : E = MAX & F = 0 +// Not-A-Number : E = MAX & F # 0 + +/* -------------------------------------------------------------------------- */ +/* --- Floating-point type shapes (IEEE-compliant) --- */ +/* -------------------------------------------------------------------------- */ + +// Taken from glibc 2.2.x: ieee754.h + +// IEEE-754 float format +union fpu_single_shape { + + fpu_single value; + + /* This is the IEEE 754 single-precision format. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int mantissa:23; +#else + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int negative:1; +#endif + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int quiet_nan:1; + unsigned int mantissa:22; +#else + unsigned int mantissa:22; + unsigned int quiet_nan:1; + unsigned int exponent:8; + unsigned int negative:1; +#endif + } ieee_nan; +}; + +// IEEE-754 double format +union fpu_double_shape { + fpu_double value; + + /* This is the IEEE 754 double-precision format. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:20; + unsigned int mantissa1:32; +#else +# if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:11; + unsigned int quiet_nan:1; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:19; + unsigned int mantissa1:32; +#else +# if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif + } ieee_nan; + + /* This format is used to extract the sign_exponent and mantissa parts only */ + struct { +#if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + unsigned int msw:32; + unsigned int lsw:32; +#else + unsigned int lsw:32; + unsigned int msw:32; +#endif + } parts; +}; + +#ifdef USE_LONG_DOUBLE +// IEEE-854 long double format +union fpu_extended_shape { + fpu_extended value; + + /* This is the IEEE 854 double-extended-precision format. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +#else +# if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +# else + unsigned int mantissa1:32; + unsigned int mantissa0:32; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +# endif +#endif + } ieee; + + /* This is for NaNs in the IEEE 854 double-extended-precision format. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int one:1; + unsigned int quiet_nan:1; + unsigned int mantissa0:30; + unsigned int mantissa1:32; +#else +# if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + unsigned int mantissa0:30; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int mantissa1:32; +# else + unsigned int mantissa1:32; + unsigned int mantissa0:30; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +# endif +#endif + } ieee_nan; + + /* This format is used to extract the sign_exponent and mantissa parts only */ + struct { +#if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + unsigned int sign_exponent:16; + unsigned int empty:16; + unsigned int msw:32; + unsigned int lsw:32; +#else + unsigned int lsw:32; + unsigned int msw:32; + unsigned int sign_exponent:16; + unsigned int empty:16; +#endif + } parts; +}; +#endif + +#ifdef USE_QUAD_DOUBLE +// IEEE-854 quad double format +union fpu_extended_shape { + fpu_extended value; + + /* This is the IEEE 854 quad-precision format. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int mantissa0:16; + unsigned int mantissa1:32; + unsigned int mantissa2:32; + unsigned int mantissa3:32; +#else + unsigned int mantissa3:32; + unsigned int mantissa2:32; + unsigned int mantissa1:32; + unsigned int mantissa0:16; + unsigned int exponent:15; + unsigned int negative:1; +#endif + } ieee; + + /* This is for NaNs in the IEEE 854 quad-precision format. */ + struct { +#ifdef WORDS_BIGENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int quiet_nan:1; + unsigned int mantissa0:15; + unsigned int mantissa1:32; + unsigned int mantissa2:32; + unsigned int mantissa3:32; +#else + unsigned int mantissa3:32; + unsigned int mantissa2:32; + unsigned int mantissa1:32; + unsigned int mantissa0:15; + unsigned int quiet_nan:1; + unsigned int exponent:15; + unsigned int negative:1; +#endif + } ieee_nan; + + /* This format is used to extract the sign_exponent and mantissa parts only */ +#if defined(HOST_FLOAT_WORDS_BIG_ENDIAN) && HOST_FLOAT_WORDS_BIG_ENDIAN + struct { + uae_u64 msw; + uae_u64 lsw; + } parts64; + struct { + uae_u32 w0; + uae_u32 w1; + uae_u32 w2; + uae_u32 w3; + } parts32; +#else + struct { + uae_u64 lsw; + uae_u64 msw; + } parts64; + struct { + uae_u32 w3; + uae_u32 w2; + uae_u32 w1; + uae_u32 w0; + } parts32; +#endif +}; +#endif + +// Declare a shape of the requested FP type +#define fp_declare_init_shape(psvar, ftype) \ + fpu_ ## ftype ## _shape psvar + +/* -------------------------------------------------------------------------- */ +/* --- Extra Math Functions --- */ +/* --- (most of them had to be defined before including ) --- */ +/* -------------------------------------------------------------------------- */ + +#undef isnan +#if 0 && defined(HAVE_ISNANL) +# define isnan(x) isnanl((x)) +#else +# define isnan(x) fp_do_isnan((x)) +#endif + +PRIVATE inline bool FFPU fp_do_isnan(fpu_register const & r) +{ +#ifdef BRANCHES_ARE_EXPENSIVE +#if !defined(USE_LONG_DOUBLE) + fp_declare_init_shape(sxp, double); + sxp.value = r; + uae_s32 hx = sxp.parts.msw; + uae_s32 lx = sxp.parts.lsw; + hx &= 0x7fffffff; + hx |= (uae_u32)(lx | (-lx)) >> 31; + hx = 0x7ff00000 - hx; + return (int)(((uae_u32)hx) >> 31); +#elif defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = r; + uae_s64 hx = sxp.parts64.msw; + uae_s64 lx = sxp.parts64.lsw; + hx &= 0x7fffffffffffffffLL; + hx |= (uae_u64)(lx | (-lx)) >> 63; + hx = 0x7fff000000000000LL - hx; + return (int)((uae_u64)hx >> 63); +#else + fp_declare_init_shape(sxp, extended); + sxp.value = r; + uae_s32 se = sxp.parts.sign_exponent; + uae_s32 hx = sxp.parts.msw; + uae_s32 lx = sxp.parts.lsw; + se = (se & 0x7fff) << 1; + lx |= hx & 0x7fffffff; + se |= (uae_u32)(lx | (-lx)) >> 31; + se = 0xfffe - se; + return (int)(((uae_u32)(se)) >> 31); +#endif +#else +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = r; + return (sxp.ieee.exponent == FP_EXTENDED_EXP_MAX) +#else + fp_declare_init_shape(sxp, double); + sxp.value = r; + return (sxp.ieee.exponent == FP_DOUBLE_EXP_MAX) +#endif + && (sxp.ieee.mantissa0 & 0x7fffffff) != 0 + && sxp.ieee.mantissa1 != 0 +#ifdef USE_QUAD_DOUBLE + && sxp.ieee.mantissa2 != 0 + && sxp.ieee.mantissa3 != 0 +#endif + ; +#endif +} + +#undef isinf +#if 0 && defined(HAVE_ISINFL) +# define isinf(x) isinfl((x)) +#else +# define isinf(x) fp_do_isinf((x)) +#endif + +PRIVATE inline bool FFPU fp_do_isinf(fpu_register const & r) +{ +#ifdef BRANCHES_ARE_EXPENSIVE +#if !defined(USE_LONG_DOUBLE) + fp_declare_init_shape(sxp, double); + sxp.value = r; + uae_s32 hx = sxp.parts.msw; + uae_s32 lx = sxp.parts.lsw; + lx |= (hx & 0x7fffffff) ^ 0x7ff00000; + lx |= -lx; + return ~(lx >> 31) & (hx >> 30); +#elif defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = r; + uae_s64 hx = sxp.parts64.msw; + uae_s64 lx = sxp.parts64.lsw; + lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL; + lx |= -lx; + return ~(lx >> 63) & (hx >> 62); +#else + fp_declare_init_shape(sxp, extended); + sxp.value = r; + /* NOTE: This function should work for both m68k and native INFs. */ +#if 0 + uae_s32 se = sxp.parts.sign_exponent; + uae_s32 hx = sxp.parts.msw; + uae_s32 lx = sxp.parts.lsw; + /* This additional ^ 0x80000000 is necessary because in Intel's + internal representation of the implicit one is explicit. + NOTE: anyway, this is equivalent to & 0x7fffffff in that case. */ +#ifdef CPU_i386 + lx |= (hx ^ 0x80000000) | ((se & 0x7fff) ^ 0x7fff); +#else + lx |= (hx & 0x7fffffff) | ((se & 0x7fff) ^ 0x7fff); +#endif + lx |= -lx; + se &= 0x8000; + return ~(lx >> 31) & (1 - (se >> 14)); +#else + return sxp.ieee.exponent == FP_EXTENDED_EXP_MAX + && (sxp.ieee.mantissa0 & 0x7fffffff) == 0 + && sxp.ieee.mantissa1 == 0; +#endif +#endif +#else +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = r; + return (sxp.ieee_nan.exponent == FP_EXTENDED_EXP_MAX) +#else + fp_declare_init_shape(sxp, double); + sxp.value = r; + return (sxp.ieee_nan.exponent == FP_DOUBLE_EXP_MAX) +#endif + && (sxp.ieee.mantissa0 & 0x7fffffff) == 0 + && sxp.ieee.mantissa1 == 0 +#ifdef USE_QUAD_DOUBLE + && sxp.ieee.mantissa2 == 0 + && sxp.ieee.mantissa3 == 0 +#endif + ; +#endif +} + +#undef isneg +#define isneg(x) fp_do_isneg((x)) + +PRIVATE inline bool FFPU fp_do_isneg(fpu_register const & r) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); +#else + fp_declare_init_shape(sxp, double); +#endif + sxp.value = r; + return sxp.ieee.negative; +} + +#undef iszero +#define iszero(x) fp_do_iszero((x)) + +PRIVATE inline bool FFPU fp_do_iszero(fpu_register const & r) +{ + // TODO: BRANCHES_ARE_EXPENSIVE +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); +#else + fp_declare_init_shape(sxp, double); +#endif + sxp.value = r; + return (sxp.ieee.exponent == 0) + && (sxp.ieee.mantissa0 == 0) + && (sxp.ieee.mantissa1 == 0) +#ifdef USE_QUAD_DOUBLE + && (sxp.ieee.mantissa2 == 0) + && (sxp.ieee.mantissa3 == 0) +#endif + ; +} + +PRIVATE inline void FFPU get_dest_flags(fpu_register const & r) +{ + fl_dest.negative = isneg(r); + fl_dest.zero = iszero(r); + fl_dest.infinity = isinf(r); + fl_dest.nan = isnan(r); + fl_dest.in_range = !fl_dest.zero && !fl_dest.infinity && !fl_dest.nan; +} + +PRIVATE inline void FFPU get_source_flags(fpu_register const & r) +{ + fl_source.negative = isneg(r); + fl_source.zero = iszero(r); + fl_source.infinity = isinf(r); + fl_source.nan = isnan(r); + fl_source.in_range = !fl_source.zero && !fl_source.infinity && !fl_source.nan; +} + +PRIVATE inline void FFPU make_nan(fpu_register & r, bool negative) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.ieee.exponent = FP_EXTENDED_EXP_MAX; + sxp.ieee.empty = 0; + sxp.ieee.mantissa0 = 0xffffffff; +#else + fp_declare_init_shape(sxp, double); + sxp.ieee.exponent = FP_DOUBLE_EXP_MAX; + sxp.ieee.mantissa0 = 0xfffff; +#endif + sxp.ieee.mantissa1 = 0xffffffff; +#ifdef USE_QUAD_DOUBLE + sxp.ieee.mantissa2 = 0xffffffff; + sxp.ieee.mantissa3 = 0xffffffff; +#endif + sxp.ieee.negative = negative; + r = sxp.value; +} + +PRIVATE inline void FFPU make_zero(fpu_register & r, bool negative) +{ +#if 1 + r = negative ? -0.0 : +0.0; +#else +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.ieee.empty = 0; +#else + fp_declare_init_shape(sxp, double); +#endif + sxp.ieee.negative = negative; + sxp.ieee.exponent = 0; + sxp.ieee.mantissa0 = 0; + sxp.ieee.mantissa1 = 0; +#ifdef USE_QUAD_DOUBLE + sxp.ieee.mantissa2 = 0; + sxp.ieee.mantissa3 = 0; +#endif + r = sxp.value; +#endif +} + +PRIVATE inline void FFPU make_inf(fpu_register & r, bool negative) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.ieee.exponent = FP_EXTENDED_EXP_MAX; + sxp.ieee.mantissa0 = 0x80000000; + sxp.ieee.empty = 0; +#else + fp_declare_init_shape(sxp, double); + sxp.ieee.exponent = FP_DOUBLE_EXP_MAX; + sxp.ieee.mantissa0 = 0; +#endif + sxp.ieee.negative = negative; + sxp.ieee.mantissa1 = 0; +#ifdef USE_QUAD_DOUBLE + sxp.ieee.mantissa2 = 0; + sxp.ieee.mantissa3 = 0; +#endif + r = sxp.value; +} + +PRIVATE inline fpu_register FFPU fast_fgetexp(fpu_register const & r) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = r; + return ((int) sxp.ieee.exponent - FP_EXTENDED_EXP_BIAS); +#else + fp_declare_init_shape(sxp, double); + sxp.value = r; + return ((int) sxp.ieee.exponent - FP_DOUBLE_EXP_BIAS); +#endif +} + +// Normalize to range 1..2 +PRIVATE inline void FFPU fast_remove_exponent(fpu_register & r) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = r; + sxp.ieee.exponent = FP_EXTENDED_EXP_BIAS; +#else + fp_declare_init_shape(sxp, double); + sxp.value = r; + sxp.ieee.exponent = FP_DOUBLE_EXP_BIAS; +#endif + r = sxp.value; +} + +// The sign of the quotient is the exclusive-OR of the sign bits +// of the source and destination operands. +PRIVATE inline uae_u32 FFPU get_quotient_sign(fpu_register const & ra, fpu_register const & rb) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sap, extended); + fp_declare_init_shape(sbp, extended); +#else + fp_declare_init_shape(sap, double); + fp_declare_init_shape(sbp, double); +#endif + sap.value = ra; + sbp.value = rb; + return ((sap.ieee.negative ^ sbp.ieee.negative) ? FPSR_QUOTIENT_SIGN : 0); +} + +/* -------------------------------------------------------------------------- */ +/* --- Math functions --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef __HAIKU__ +#ifdef __cplusplus +extern "C" { +#endif +/* Haiku seems to lack some declarations, even if the functions are there */ +extern long double exp10l(long double); +#ifdef __cplusplus +} +#endif +#endif + +#if defined(FPU_USE_ISO_C99) && (defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE)) +# ifdef HAVE_LOGL +# define fp_log logl +# endif +# ifdef HAVE_LOG1PL +# define fp_log1p log1pl +# endif +# ifdef HAVE_EXPM1L +# define fp_expm1 expm1l +# endif +# ifdef HAVE_LOG10L +# define fp_log10 log10l +# endif +# ifdef HAVE_LOG2L +# define fp_log2 log2l +# endif +# ifdef HAVE_EXPL +# define fp_exp expl +# endif +# ifdef HAVE_POWL +# define fp_pow powl +# endif +# if defined(HAVE_EXP10L) +# define fp_pow10 exp10l +# elif defined(HAVE_POW10L) +# define fp_pow10 pow10l +# else +# define fp_pow10(x) fp_pow(LD(10.0), x) +# endif +# if defined(HAVE_EXP2L) +# define fp_pow2 exp2l +# elif defined(HAVE_POW2L) +# define fp_pow2 pow2l +# else +# define fp_pow2(x) fp_pow(LD(2.0), x) +# endif +# ifdef HAVE_FABSL +# define fp_fabs fabsl +# endif +# ifdef HAVE_SQRTL +# define fp_sqrt sqrtl +# endif +# ifdef HAVE_SINL +# define fp_sin sinl +# endif +# ifdef HAVE_COSL +# define fp_cos cosl +# endif +# ifdef HAVE_TANL +# define fp_tan tanl +# endif +# ifdef HAVE_SINHL +# define fp_sinh sinhl +# endif +# ifdef HAVE_COSHL +# define fp_cosh coshl +# endif +# ifdef HAVE_TANHL +# define fp_tanh tanhl +# endif +# ifdef HAVE_ASINL +# define fp_asin asinl +# endif +# ifdef HAVE_ACOSL +# define fp_acos acosl +# endif +# ifdef HAVE_ATANL +# define fp_atan atanl +# endif +# ifdef HAVE_ASINHL +# define fp_asinh asinhl +# endif +# ifdef HAVE_ACOSHL +# define fp_acosh acoshl +# endif +# ifdef HAVE_ATANHL +# define fp_atanh atanhl +# endif +# ifdef HAVE_FLOORL +# define fp_floor floorl +# endif +# ifdef HAVE_CEILL +# define fp_ceil ceill +# endif +#endif + +#ifndef fp_log +# define fp_log log +#endif +#ifndef fp_log1p +# define fp_log1p log1p +#endif +#ifndef fp_expm1 +# define fp_expm1 expm1 +#endif +#ifndef fp_log10 +# define fp_log10 log10 +#endif +#ifndef fp_log2 +# define fp_log2 log2 +#endif +#ifndef fp_exp +# define fp_exp exp +#endif +#ifndef fp_pow +# define fp_pow pow +#endif +#ifndef fp_pow10 +# ifdef HAVE_POW10 +# define fp_pow10 pow10 +# else +# define fp_pow10 exp10 +# endif +#endif +#ifndef fp_pow2 +# ifdef HAVE_POW2 +# define fp_pow2 pow2 +# else +# define fp_pow2 exp2 +# endif +#endif +#ifndef fp_fabs +# define fp_fabs fabs +#endif +#ifndef fp_sqrt +# define fp_sqrt sqrt +#endif +#ifndef fp_sin +# define fp_sin sin +#endif +#ifndef fp_cos +# define fp_cos cos +#endif +#ifndef fp_tan +# define fp_tan tan +#endif +#ifndef fp_sinh +# define fp_sinh sinh +#endif +#ifndef fp_cosh +# define fp_cosh cosh +#endif +#ifndef fp_tanh +# define fp_tanh tanh +#endif +#ifndef fp_asin +# define fp_asin asin +#endif +#ifndef fp_acos +# define fp_acos acos +#endif +#ifndef fp_atan +# define fp_atan atan +#endif +#ifndef fp_asinh +# define fp_asinh asinh +#endif +#ifndef fp_acosh +# define fp_acosh acosh +#endif +#ifndef fp_atanh +# define fp_atanh atanh +#endif +#ifndef fp_floor +# define fp_floor floor +#endif +#ifndef fp_ceil +# define fp_ceil ceil +#endif + +#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) +// Assembly optimized support functions. Taken from glibc 2.2.2 + +#undef fp_log +#define fp_log fp_do_log + +PRIVATE inline fpu_extended fp_do_log(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fldln2; fxch; fyl2x" : "=t" (value) : "0" (x) : "st(1)"); + return value; +} + +#undef fp_log10 +#define fp_log10 fp_do_log10 + +PRIVATE inline fpu_extended fp_do_log10(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fldlg2; fxch; fyl2x" : "=t" (value) : "0" (x) : "st(1)"); + return value; +} + +#if !defined(HAVE_EXPL) +#undef fp_exp +#define fp_exp fp_do_exp + +PRIVATE inline fpu_extended fp_do_exp(fpu_extended x) +{ + fpu_extended value, exponent; + if (isinf(x)) + { + if(isneg(x)) + return 0.; + else + return x; + } + __asm__ __volatile__("fldl2e # e^x = 2^(x * log2(e))\n\t" + "fmul %%st(1) # x * log2(e)\n\t" + "fst %%st(1)\n\t" + "frndint # int(x * log2(e))\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(x * log2(e))\n\t" + "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" + : "=t" (value), "=u" (exponent) : "0" (x)); + value += 1.0; + __asm__ __volatile__("fscale" : "=t" (value) : "0" (value), "u" (exponent)); + return value; +} +#endif + +#if !defined(HAVE_EXP10L) && !defined(HAVE_POW10L) +#undef fp_pow +#define fp_pow fp_do_pow + +PRIVATE fpu_extended fp_do_pow(fpu_extended x, fpu_extended y); +#endif + +#undef fp_fabs +#define fp_fabs fp_do_fabs + +PRIVATE inline fpu_extended fp_do_fabs(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fabs" : "=t" (value) : "0" (x)); + return value; +} + +#undef fp_sqrt +#define fp_sqrt fp_do_sqrt + +PRIVATE inline fpu_extended fp_do_sqrt(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fsqrt" : "=t" (value) : "0" (x)); + return value; +} + +#ifndef ACCURATE_SIN_COS_TAN +#undef fp_sin +#define fp_sin fp_do_sin + +PRIVATE inline fpu_extended fp_do_sin(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fsin" : "=t" (value) : "0" (x)); + return value; +} + +#undef fp_cos +#define fp_cos fp_do_cos + +PRIVATE inline fpu_extended fp_do_cos(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fcos" : "=t" (value) : "0" (x)); + return value; +} + +#undef fp_tan +#define fp_tan fp_do_tan + +PRIVATE inline fpu_extended fp_do_tan(fpu_extended x) +{ + fpu_extended value, value2; + __asm__ __volatile__("fptan" : "=t" (value2), "=u" (value) : "0" (x)); + return value; +} +#endif /* ACCURATE_SIN_COS_TAN */ + +#ifndef HAVE_EXPM1L +#undef fp_expm1 +#define fp_expm1 fp_do_expm1 + +// Returns: exp(X) - 1.0 +PRIVATE inline fpu_extended fp_do_expm1(fpu_extended x) +{ + fpu_extended value, exponent, temp, temp2; + if (isinf(x)) + { + if(isneg(x)) + return -1.; + else + return x; + } + __asm__ __volatile__("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" + "fmul %%st(1) # x * log2(e)\n\t" + "fst %%st(1)\n\t" + "frndint # int(x * log2(e))\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(x * log2(e))\n\t" + "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" + "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" + : "=t" (value), "=u" (exponent) : "0" (x)); + __asm__ __volatile__("fld1 \n\t" + "fscale \n\t" + : "=t" (temp), "=u" (temp2) : "0" (exponent)); + temp -= 1.0; + return temp + value ? temp + value : x; +} +#endif + +#undef fp_sgn1 +#define fp_sgn1 fp_do_sgn1 + +PRIVATE inline fpu_extended fp_do_sgn1(fpu_extended x) +{ +#if defined(USE_LONG_DOUBLE) || defined(USE_QUAD_DOUBLE) + fp_declare_init_shape(sxp, extended); + sxp.value = x; + sxp.ieee_nan.exponent = FP_EXTENDED_EXP_MAX>>1; + sxp.ieee_nan.one = 1; +#else + fp_declare_init_shape(sxp, double); + sxp.value = x; + sxp.ieee_nan.exponent = FP_DOUBLE_EXP_MAX>>1; +#endif + sxp.ieee_nan.quiet_nan = 0; + sxp.ieee_nan.mantissa0 = 0; + sxp.ieee_nan.mantissa1 = 0; + x = sxp.value; + return x; +} + +#ifndef HAVE_SINHL +#undef fp_sinh +#define fp_sinh fp_do_sinh + +PRIVATE inline fpu_extended fp_do_sinh(fpu_extended x) +{ + if (isinf(x)) return x; + fpu_extended exm1 = fp_expm1(fp_fabs(x)); + return 0.5 * (exm1 / (exm1 + 1.0) + exm1) * fp_sgn1(x); +} +#endif + +#ifndef HAVE_COSHL +#undef fp_cosh +#define fp_cosh fp_do_cosh + +PRIVATE inline fpu_extended fp_do_cosh(fpu_extended x) +{ + fpu_extended ex = fp_exp(x); + return 0.5 * (ex + 1.0 / ex); +} +#endif + +#ifndef HAVE_TANHL +#undef fp_tanh +#define fp_tanh fp_do_tanh + +PRIVATE inline fpu_extended fp_do_tanh(fpu_extended x) +{ + fpu_extended exm1 = fp_expm1(-fp_fabs(x + x)); + return exm1 / (exm1 + 2.0) * fp_sgn1(-x); +} +#endif + +#undef fp_atan2 +#define fp_atan2 fp_do_atan2 + +PRIVATE inline fpu_extended fp_do_atan2(fpu_extended y, fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fpatan" : "=t" (value) : "0" (x), "u" (y) : "st(1)"); + return value; +} + +#ifndef HAVE_ASINL +#undef fp_asin +#define fp_asin fp_do_asin + +PRIVATE inline fpu_extended fp_do_asin(fpu_extended x) +{ + return fp_atan2(x, fp_sqrt(1.0 - x * x)); +} +#endif + +#ifndef HAVE_ACOSL +#undef fp_acos +#define fp_acos fp_do_acos + +PRIVATE inline fpu_extended fp_do_acos(fpu_extended x) +{ + return fp_atan2(fp_sqrt(1.0 - x * x), x); +} +#endif + +#undef fp_atan +#define fp_atan fp_do_atan + +PRIVATE inline fpu_extended fp_do_atan(fpu_extended x) +{ + fpu_extended value; + __asm__ __volatile__("fld1; fpatan" : "=t" (value) : "0" (x) : "st(1)"); + return value; +} + +#ifndef HAVE_LOG1PL +#undef fp_log1p +#define fp_log1p fp_do_log1p + +// Returns: ln(1.0 + X) +PRIVATE fpu_extended fp_do_log1p(fpu_extended x); +#endif + +#ifndef HAVE_ASINHL +#undef fp_asinh +#define fp_asinh fp_do_asinh + +PRIVATE inline fpu_extended fp_do_asinh(fpu_extended x) +{ + fpu_extended y = fp_fabs(x); + return (fp_log1p(y * y / (fp_sqrt(y * y + 1.0) + 1.0) + y) * fp_sgn1(x)); +} +#endif + +#ifndef HAVE_ACOSHL +#undef fp_acosh +#define fp_acosh fp_do_acosh + +PRIVATE inline fpu_extended fp_do_acosh(fpu_extended x) +{ + return fp_log(x + fp_sqrt(x - 1.0) * fp_sqrt(x + 1.0)); +} +#endif + +#ifndef HAVE_ATANHL +#undef fp_atanh +#define fp_atanh fp_do_atanh + +PRIVATE inline fpu_extended fp_do_atanh(fpu_extended x) +{ + fpu_extended y = fp_fabs(x); + return -0.5 * fp_log1p(-(y + y) / (1.0 + y)) * fp_sgn1(x); +} +#endif + + +/* + * LLVM 2.9 crashes on first definition, + * clang with LLVM 3.x crashes on 2nd definition... sigh + */ +#if defined(__clang__) || !defined(__llvm__) +#define DEFINE_ROUND_FUNC(rounding_mode_str, rounding_mode) \ +PRIVATE inline fpu_extended fp_do_round_to_ ## rounding_mode_str(fpu_extended __x) \ +{ \ + register long double __value; \ + register int __ignore; \ + volatile unsigned short __cw; \ + volatile unsigned short __cwtmp; \ + __asm __volatile ("fnstcw %3\n\t" \ + "movzwl %3, %1\n\t" \ + "andl $0xf3ff, %1\n\t" \ + "orl %5, %1\n\t" \ + "movw %w1, %2\n\t" \ + "fldcw %2\n\t" \ + "frndint\n\t" \ + "fldcw %3" \ + : "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp), \ + "=m" (__cw) \ + : "0" (__x), "i"(rounding_mode)); \ + return __value; \ +} +#else +#define DEFINE_ROUND_FUNC(rounding_mode_str, rounding_mode) \ +PRIVATE inline fpu_extended fp_do_round_to_ ## rounding_mode_str(fpu_extended x) \ +{ \ + volatile unsigned short cw; \ + __asm__ __volatile__("fnstcw %0" : "=m" (cw)); \ + volatile unsigned short cw_temp = (cw & 0xf3ff) | (rounding_mode); \ + __asm__ __volatile__("fldcw %0" : : "m" (cw_temp)); \ + fpu_extended value; \ + __asm__ __volatile__("frndint" : "=t" (value) : "0" (x)); \ + __asm__ __volatile__("fldcw %0" : : "m" (cw)); \ + return value; \ +} +#endif + +#undef fp_round_to_minus_infinity +#ifdef HAVE_FLOORL +#define fp_round_to_minus_infinity floorl +#else +#define fp_round_to_minus_infinity fp_do_round_to_minus_infinity +DEFINE_ROUND_FUNC(minus_infinity, CW_RC_DOWN) +#endif + +#undef fp_round_to_plus_infinity +#ifdef HAVE_CEILL +#define fp_round_to_plus_infinity ceill +#else +#define fp_round_to_plus_infinity fp_do_round_to_plus_infinity +DEFINE_ROUND_FUNC(plus_infinity, CW_RC_UP) +#endif + +#undef fp_round_to_zero +#ifdef HAVE_TRUNCL +#define fp_round_to_zero truncl +#else +#define fp_round_to_zero fp_do_round_to_zero +DEFINE_ROUND_FUNC(zero, CW_RC_ZERO) +#endif + +#undef fp_round_to_nearest +#ifdef HAVE_ROUNDL +#define fp_round_to_nearest roundl +#else +#define fp_round_to_nearest fp_do_round_to_nearest +DEFINE_ROUND_FUNC(nearest, CW_RC_NEAR) +#endif + +#undef fp_round_to_even +#ifdef HAVE_RINTL +#define fp_round_to_even rintl +#else +#define fp_round_to_even fp_do_round_to_even +DEFINE_ROUND_FUNC(even, CW_RC_NEAR) +#endif + +#undef fp_ceil +#define fp_ceil fp_do_round_to_plus_infinity + +#undef fp_floor +#define fp_floor fp_do_round_to_minus_infinity + + +#endif /* USE_X87_ASSEMBLY */ + +#ifndef fp_round_to_minus_infinity +#define fp_round_to_minus_infinity(x) fp_floor(x) +#endif + +#ifndef fp_round_to_plus_infinity +#define fp_round_to_plus_infinity(x) fp_ceil(x) +#endif + +#ifndef fp_round_to_zero +#define fp_round_to_zero(x) ((int)(x)) +#endif + +#ifndef fp_round_to_nearest +#define fp_round_to_nearest(x) ((int)((x) + 0.5)) +#endif + +#ifndef fp_round_to_even +#define fp_round_to_even fp_round_to_nearest +#endif + +#endif /* FPU_MATHLIB_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/rounding.cpp b/BasiliskII/src/uae_cpu_2021/fpu/rounding.cpp new file mode 100644 index 000000000..9942d4e89 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/rounding.cpp @@ -0,0 +1,69 @@ +/* + * fpu/rounding.cpp - system-dependant FPU rounding mode and precision + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#undef PRIVATE +#define PRIVATE /**/ + +#undef PUBLIC +#define PUBLIC /**/ + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* -------------------------------------------------------------------------- */ +/* --- Native X86 Rounding Mode --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_X86_ROUNDING_MODE +const uae_u32 FFPU x86_control_word_rm_mac2host[] = { + CW_RC_NEAR, + CW_RC_ZERO, + CW_RC_DOWN, + CW_RC_UP +}; +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Native X86 Rounding Precision --- */ +/* -------------------------------------------------------------------------- */ + +#ifdef FPU_USE_X86_ROUNDING_PRECISION +const uae_u32 FFPU x86_control_word_rp_mac2host[] = { + CW_PC_EXTENDED, + CW_PC_SINGLE, + CW_PC_DOUBLE, + CW_PC_RESERVED +}; +#endif diff --git a/BasiliskII/src/uae_cpu_2021/fpu/rounding.h b/BasiliskII/src/uae_cpu_2021/fpu/rounding.h new file mode 100644 index 000000000..aa2c9ced1 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/rounding.h @@ -0,0 +1,159 @@ +/* + * fpu/rounding.h - system-dependant FPU rounding mode and precision + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_ROUNDING_H +#define FPU_ROUNDING_H + +/* NOTE: this file shall be included from fpu/fpu_*.cpp */ +#undef PUBLIC +#define PUBLIC extern + +#undef PRIVATE +#define PRIVATE static + +#undef FFPU +#define FFPU /**/ + +#undef FPU +#define FPU fpu. + +/* Defaults to generic rounding mode and precision handling */ +#define FPU_USE_GENERIC_ROUNDING_MODE +#define FPU_USE_GENERIC_ROUNDING_PRECISION + +/* -------------------------------------------------------------------------- */ +/* --- Selection of floating-point rounding mode and precision --- */ +/* -------------------------------------------------------------------------- */ + +/* Optimized i386 fpu core must use native rounding mode */ +#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_ROUNDING_MODE +# define FPU_USE_X86_ROUNDING_MODE +#endif + +/* Optimized i386 fpu core must use native rounding precision */ +#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_ROUNDING_PRECISION +# define FPU_USE_X86_ROUNDING_PRECISION +#endif + +#if 0 // gb-- FIXME: that doesn't work +/* IEEE-based fpu core can have native rounding mode on i386 */ +#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_ROUNDING_MODE +# define FPU_USE_X86_ROUNDING_MODE +#endif + +/* IEEE-based fpu core can have native rounding precision on i386 */ +#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) +# undef FPU_USE_GENERIC_ROUNDING_PRECISION +# define FPU_USE_X86_ROUNDING_PRECISION +#endif +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Sanity checks --- */ +/* -------------------------------------------------------------------------- */ + +/* X86 rounding mode and precision work together */ +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) +# define FPU_USE_X86_ROUNDING +# define CW_INITIAL (CW_RESET|CW_X|CW_PC_EXTENDED|CW_RC_NEAR|CW_PM|CW_UM|CW_OM|CW_ZM|CW_DM|CW_IM) + PRIVATE uae_u32 x86_control_word; +#endif + +/* Control word -- rounding mode */ +#ifdef FPU_USE_X86_ROUNDING_MODE +PUBLIC const uae_u32 x86_control_word_rm_mac2host[]; +#endif + +/* Control word -- rounding precision */ +#ifdef FPU_USE_X86_ROUNDING_PRECISION +PUBLIC const uae_u32 x86_control_word_rp_mac2host[]; +#endif + +#if defined(FPU_USE_X86_ROUNDING_MODE) && defined(FPU_USE_X86_ROUNDING_PRECISION) +/* Set host control word for rounding mode and rounding precision */ +PRIVATE inline void set_host_control_word(void) +{ + /* + Exception enable byte is ignored, but the same value is returned + that was previously set. + */ + x86_control_word + = (x86_control_word & ~(X86_ROUNDING_MODE|X86_ROUNDING_PRECISION)) + | x86_control_word_rm_mac2host[(FPU fpcr & FPCR_ROUNDING_MODE) >> 4] + | x86_control_word_rp_mac2host[(FPU fpcr & FPCR_ROUNDING_PRECISION) >> 6] + ; + __asm__ __volatile__("fldcw %0" : : "m" (x86_control_word)); +} +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Generic rounding mode and precision --- */ +/* -------------------------------------------------------------------------- */ + +#if defined(FPU_USE_GENERIC_ROUNDING_MODE) && defined(FPU_USE_GENERIC_ROUNDING_PRECISION) +/* Set host control word for rounding mode and rounding precision */ +PRIVATE inline void set_host_control_word(void) + { } +#endif + +/* -------------------------------------------------------------------------- */ +/* --- Common rounding mode and precision --- */ +/* -------------------------------------------------------------------------- */ + +#if defined(FPU_USE_GENERIC_ROUNDING_MODE) || defined(FPU_USE_X86_ROUNDING_MODE) + +/* Return the current rounding mode in m68k format */ +static inline uae_u32 FFPU get_rounding_mode(void) + { return FPU fpcr & FPCR_ROUNDING_MODE; } + +/* Convert and set to native rounding mode */ +static inline void FFPU set_rounding_mode(uae_u32 /* new_rounding_mode */ ) + { } + +#endif + +#if defined(FPU_USE_GENERIC_ROUNDING_PRECISION) || defined(FPU_USE_X86_ROUNDING_PRECISION) + +/* Return the current rounding precision in m68k format */ +static inline uae_u32 FFPU get_rounding_precision(void) + { return FPU fpcr & FPCR_ROUNDING_PRECISION; } + +/* Convert and set to native rounding precision */ +static inline void FFPU set_rounding_precision(uae_u32 /* new_rounding_precision */) + { } + +#endif + +#endif /* FPU_ROUNDING_H */ diff --git a/BasiliskII/src/uae_cpu_2021/fpu/types.h b/BasiliskII/src/uae_cpu_2021/fpu/types.h new file mode 100644 index 000000000..50e07ec20 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/fpu/types.h @@ -0,0 +1,183 @@ +/* + * fpu/types.h - basic types for fpu registers + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * MC68881/68040 fpu emulation + * + * Original UAE FPU, copyright 1996 Herman ten Brugge + * Rewrite for x86, copyright 1999-2001 Lauri Pesonen + * New framework, copyright 2000-2001 Gwenole Beauchesne + * Adapted for JIT compilation (c) Bernd Meyer, 2000-2001 + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FPU_TYPES_H +#define FPU_TYPES_H + +#include "sysdeps.h" + +/* Default behavior is *not* to use long doubles */ +#undef USE_LONG_DOUBLE +#undef USE_QUAD_DOUBLE + +/* -------------------------------------------------------------------------- */ +/* --- Original UAE fpu core --- */ +/* -------------------------------------------------------------------------- */ + +#if defined(FPU_UAE) + +/* 4-byte floats */ +#if SIZEOF_FLOAT == 4 +typedef float uae_f32; +#elif SIZEOF_DOUBLE == 4 +typedef double uae_f32; +#else +#error "No 4 byte float type, you lose." +#endif + +/* 8-byte floats */ +#if SIZEOF_DOUBLE == 8 +typedef double uae_f64; +#elif SIZEOF_LONG_DOUBLE == 8 +typedef long double uae_f64; +#else +#error "No 8 byte float type, you lose." +#endif + +/* Original UAE FPU registers are only 8 bytes long */ +typedef uae_f64 fpu_register; +typedef fpu_register fpu_extended; +typedef uae_f64 fpu_double; +typedef uae_f32 fpu_single; + +/* -------------------------------------------------------------------------- */ +/* --- Optimized core for x86 --- */ +/* -------------------------------------------------------------------------- */ + +#elif defined(FPU_X86) + +/* 4-byte floats */ +#if SIZEOF_FLOAT == 4 +typedef float uae_f32; +#elif SIZEOF_DOUBLE == 4 +typedef double uae_f32; +#else +#error "No 4 byte float type, you lose." +#endif + +/* 8-byte floats */ +#if SIZEOF_DOUBLE == 8 +typedef float uae_f64; +#elif SIZEOF_LONG_DOUBLE == 8 +typedef double uae_f64; +#else +#error "No 8 byte float type, you lose." +#endif + +/* At least 10-byte floats are required */ +#if SIZEOF_LONG_DOUBLE >= 10 +typedef long double fpu_register; +#else +#error "No float type at least 10 bytes long, you lose." +#endif + +/* X86 FPU has a custom register type that maps to a native X86 register */ +typedef fpu_register fpu_extended; +typedef uae_f64 fpu_double; +typedef uae_f32 fpu_single; + +/* -------------------------------------------------------------------------- */ +/* --- C99 implementation --- */ +/* -------------------------------------------------------------------------- */ + +#elif defined(FPU_IEEE) + +#if 0 +#if HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT +#error "No IEEE float format, you lose." +#endif +#endif + +/* 4-byte floats */ +#if SIZEOF_FLOAT == 4 +typedef float uae_f32; +#elif SIZEOF_DOUBLE == 4 +typedef double uae_f32; +#else +#error "No 4 byte float type, you lose." +#endif + +/* 8-byte floats */ +#if SIZEOF_DOUBLE == 8 +typedef double uae_f64; +#elif SIZEOF_LONG_DOUBLE == 8 +typedef long double uae_f64; +#else +#error "No 8 byte float type, you lose." +#endif + +/* 12-byte or 16-byte floats */ +#if SIZEOF_LONG_DOUBLE == 12 +typedef long double uae_f96; +typedef uae_f96 fpu_register; +#define USE_LONG_DOUBLE 1 +#elif SIZEOF_LONG_DOUBLE == 16 && (defined(CPU_i386) || defined(CPU_x86_64) || defined(CPU_ia64)) +/* Long doubles on x86-64 are really held in old x87 FPU stack. */ +typedef long double uae_f128; +typedef uae_f128 fpu_register; +#define USE_LONG_DOUBLE 1 +#elif 0 +/* Disable for now and probably for good as (i) the emulator + implementation is not correct, (ii) I don't know of any CPU which + handles this kind of format *natively* with conformance to IEEE. */ +typedef long double uae_f128; +typedef uae_f128 fpu_register; +#define USE_QUAD_DOUBLE 1 +#else +typedef uae_f64 fpu_register; +#endif + +/* We need all those floating-point types */ +typedef fpu_register fpu_extended; +typedef uae_f64 fpu_double; +typedef uae_f32 fpu_single; + +#elif defined(FPU_MPFR) + +#include + +struct fpu_register { + mpfr_t f; + uae_u64 nan_bits; + int nan_sign; + operator long double (); + fpu_register &operator=(long double); +}; + +#endif + +union fpu_register_parts { + fpu_register val; + uae_u32 parts[sizeof(fpu_register) / 4]; +}; + +#endif /* FPU_TYPES_H */ diff --git a/BasiliskII/src/uae_cpu_2021/gencpu.c b/BasiliskII/src/uae_cpu_2021/gencpu.c new file mode 100644 index 000000000..295a49e50 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/gencpu.c @@ -0,0 +1,2885 @@ +/* + * gencpu.c - m68k emulation generator + * + * Copyright (c) 2009 ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * UAE - The Un*x Amiga Emulator + * + * MC68000 emulation generator + * + * This is a fairly stupid program that generates a lot of case labels that + * can be #included in a switch statement. + * As an alternative, it can generate functions that handle specific + * MC68000 instructions, plus a prototype header file and a function pointer + * array to look up the function for an opcode. + * Error checking is bad, an illegal table68k file will cause the program to + * call abort(). + * The generated code is sometimes sub-optimal, an optimizing compiler should + * take care of this. + * + * Copyright 1995, 1996 Bernd Schmidt + */ + +#define CC_FOR_BUILD 1 + +#include "sysdeps.h" +#include "readcpu.h" + +#include +#include +#include +#include +#include +#undef abort + +#define BOOL_TYPE "int" +#define VERIFY_MMU_GENAMODE 0 + +static FILE *headerfile; +static FILE *stblfile; +static FILE *functblfile; + +static int using_prefetch; +static int using_exception_3; +static int cpu_level; + +/* For the current opcode, the next lower level that will have different code. + * Initialized to -1 for each opcode. If it remains unchanged, indicates we + * are done with that opcode. */ +static int next_cpu_level; + +static int *opcode_map; +static int *opcode_next_clev; +static int *opcode_last_postfix; +static unsigned long *counts; + +#define GENA_GETV_NO_FETCH 0 +#define GENA_GETV_FETCH 1 +#define GENA_GETV_FETCH_ALIGN 2 +#define GENA_MOVEM_DO_INC 0 +#define GENA_MOVEM_NO_INC 1 +#define GENA_MOVEM_MOVE16 2 + +#define XLATE_LOG 0 +#define XLATE_PHYS 1 +#define XLATE_SFC 2 +#define XLATE_DFC 3 +static char * mem_prefix[4] = { "", "phys_", "sfc_", "dfc_" }; + +/* Define the minimal 680x0 where NV flags are not affected by xBCD instructions. */ +#define xBCD_KEEPS_N_FLAG 4 +#define xBCD_KEEPS_V_FLAG 3 + +static void read_counts (void) +{ + FILE *file; + unsigned long opcode, count, total; + char name[20]; + int nr = 0; + memset (counts, 0, 65536 * sizeof *counts); + + file = fopen ("frequent.68k", "r"); + if (file) { + int c = fscanf (file, "Total: %lu\n", &total); + assert(c == 1); + while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) { + opcode_next_clev[nr] = 4; + opcode_last_postfix[nr] = -1; + opcode_map[nr++] = opcode; + counts[opcode] = count; + } + fclose (file); + } + if (nr == nr_cpuop_funcs) + return; + for (opcode = 0; opcode < 0x10000; opcode++) { + if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG + && counts[opcode] == 0) + { + opcode_next_clev[nr] = 4; + opcode_last_postfix[nr] = -1; + opcode_map[nr++] = opcode; + counts[opcode] = count; + } + } + if (nr != nr_cpuop_funcs) + abort (); +} + +static char endlabelstr[80]; +static int endlabelno = 0; +static int need_endlabel; + +static int n_braces = 0; +static int m68k_pc_offset = 0; + +static void start_brace (void) +{ + n_braces++; + printf ("{"); +} + +static void close_brace (void) +{ + assert (n_braces > 0); + n_braces--; + printf ("}"); +} + +static void finish_braces (void) +{ + while (n_braces > 0) + close_brace (); +} + +static void pop_braces (int to) +{ + while (n_braces > to) + close_brace (); +} + +static int bit_size (int size) +{ + switch (size) { + case sz_byte: return 8; + case sz_word: return 16; + case sz_long: return 32; + default: abort (); + } + return 0; +} + +static const char *bit_mask (int size) +{ + switch (size) { + case sz_byte: return "0xff"; + case sz_word: return "0xffff"; + case sz_long: return "0xffffffff"; + default: abort (); + } + return 0; +} + +static const char *gen_nextilong (void) +{ + static char buffer[80]; + int r = m68k_pc_offset; + + m68k_pc_offset += 4; + + if (using_prefetch) + sprintf (buffer, "get_ilong_prefetch(%d)", r); + else + sprintf (buffer, "get_ilong(%d)", r); + return buffer; +} + +static const char *gen_nextiword (void) +{ + static char buffer[80]; + int r = m68k_pc_offset; + + m68k_pc_offset += 2; + + if (using_prefetch) + sprintf (buffer, "get_iword_prefetch(%d)", r); + else + sprintf (buffer, "get_iword(%d)", r); + return buffer; +} + +static const char *gen_nextibyte (void) +{ + static char buffer[80]; + int r = m68k_pc_offset; + m68k_pc_offset += 2; + + if (using_prefetch) + sprintf (buffer, "get_ibyte_prefetch(%d)", r); + else + sprintf (buffer, "get_ibyte(%d)", r); + return buffer; +} + +static void fill_prefetch_0 (void) +{ + if (using_prefetch) + printf ("fill_prefetch_0 ();\n"); +} + +static void fill_prefetch_2 (void) +{ + if (using_prefetch) + printf ("fill_prefetch_2 ();\n"); +} + +static void swap_opcode (void) +{ + printf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); + printf ("\topcode = do_byteswap_16(opcode);\n"); + printf("#endif\n"); +} + +static void real_opcode (int *have) +{ + if (!*have) + { + printf("#if defined(HAVE_GET_WORD_UNSWAPPED) && !defined(FULLMMU)\n"); + printf ("\tuae_u32 real_opcode = do_byteswap_16(opcode);\n"); + printf("#else\n"); + printf ("\tuae_u32 real_opcode = opcode;\n"); + printf("#endif\n"); + *have = 1; + } +} + +static void sync_m68k_pc (void) +{ + if (m68k_pc_offset == 0) + return; + printf ("m68k_incpc(%d);\n", m68k_pc_offset); + switch (m68k_pc_offset) { + case 0: + /*fprintf (stderr, "refilling prefetch at 0\n"); */ + break; + case 2: + fill_prefetch_2 (); + break; + default: + fill_prefetch_0 (); + break; + } + m68k_pc_offset = 0; +} + +static void gen_set_fault_pc (void) +{ + sync_m68k_pc(); + printf ("regs.fault_pc = m68k_getpc ();\n"); + m68k_pc_offset = 0; +} + +/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, + * the calling routine handles Apdi and Aipi modes. + * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ + +/* fixup indicates if we want to fix up adress registers in pre decrement + * or post increment mode now (0) or later (1). A value of 2 will then be + * used to do the actual fix up. This allows to do all memory readings + * before any register is modified, and so to rerun operation without + * side effect in case a bus fault is generated by any memory access. + * XJ - 2006/11/13 */ +static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int xlateflag, int fixup) +{ + if (fixup != 2) + { + start_brace (); + switch (mode) { + case Dreg: + if (movem) + abort (); + if (getv == GENA_GETV_FETCH) + switch (size) { + case sz_byte: + printf("\n#if defined(AMIGA) && !defined(WARPUP)\n"); + /* sam: I don't know why gcc.2.7.2.1 produces a code worse */ + /* if it is not done like that: */ + printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg(regs, %s))[3];\n", name, reg); + printf("#else\n"); + printf ("\tuae_s8 %s = m68k_dreg(regs, %s);\n", name, reg); + printf("#endif\n"); + break; + case sz_word: + printf("\n#if defined(AMIGA) && !defined(WARPUP)\n"); + printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg(regs, %s))[1];\n", name, reg); + printf("#else\n"); + printf ("\tuae_s16 %s = m68k_dreg(regs, %s);\n", name, reg); + printf("#endif\n"); + break; + case sz_long: + printf ("\tuae_s32 %s = m68k_dreg(regs, %s);\n", name, reg); + break; + default: + abort (); + } + return; + case Areg: + if (movem) + abort (); + if (getv == GENA_GETV_FETCH) + switch (size) { + case sz_word: + printf ("\tuae_s16 %s = m68k_areg(regs, %s);\n", name, reg); + break; + case sz_long: + printf ("\tuae_s32 %s = m68k_areg(regs, %s);\n", name, reg); + break; + default: + abort (); + } + return; + case Aind: + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + break; + case Aipi: + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + break; + case Apdi: + switch (size) { + case sz_byte: + if (movem) + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + else + printf ("\tuaecptr %sa = m68k_areg(regs, %s) - areg_byteinc[%s];\n", name, reg, reg); + break; + case sz_word: + if (movem) + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + else + printf ("\tuaecptr %sa = m68k_areg(regs, %s) - 2;\n", name, reg); + break; + case sz_long: + if (movem) + printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); + else + printf ("\tuaecptr %sa = m68k_areg(regs, %s) - 4;\n", name, reg); + break; + default: + abort (); + } + break; + case Ad16: + printf ("\tuaecptr %sa = m68k_areg(regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword ()); + break; + case Ad8r: + if (cpu_level > 1) { + if (next_cpu_level < 1) + next_cpu_level = 1; + sync_m68k_pc (); + start_brace (); + printf ("\tuaecptr %sa = get_disp_ea_020(m68k_areg(regs, %s), next_iword());\n", name, reg); + } else + printf ("\tuaecptr %sa = get_disp_ea_000(m68k_areg(regs, %s), %s);\n", name, reg, gen_nextiword ()); + + break; + case PC16: + printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset); + printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword ()); + break; + case PC8r: + if (cpu_level > 1) { + if (next_cpu_level < 1) + next_cpu_level = 1; + sync_m68k_pc (); + start_brace (); + printf ("\tuaecptr tmppc = m68k_getpc();\n"); + printf ("\tuaecptr %sa = get_disp_ea_020(tmppc, next_iword());\n", name); + } else { + printf ("\tuaecptr tmppc = m68k_getpc() + %d;\n", m68k_pc_offset); + printf ("\tuaecptr %sa = get_disp_ea_000(tmppc, %s);\n", name, gen_nextiword ()); + } + + break; + case absw: + printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword ()); + break; + case absl: + printf ("\tuaecptr %sa = %s;\n", name, gen_nextilong ()); + break; + case imm: + if (getv != GENA_GETV_FETCH) + abort (); + switch (size) { + case sz_byte: + printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ()); + break; + case sz_word: + printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ()); + break; + case sz_long: + printf ("\tuae_s32 %s = %s;\n", name, gen_nextilong ()); + break; + default: + abort (); + } + return; + case imm0: + if (getv != GENA_GETV_FETCH) + abort (); + printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ()); + return; + case imm1: + if (getv != GENA_GETV_FETCH) + abort (); + printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ()); + return; + case imm2: + if (getv != GENA_GETV_FETCH) + abort (); + printf ("\tuae_s32 %s = %s;\n", name, gen_nextilong ()); + return; + case immi: + if (getv != GENA_GETV_FETCH) + abort (); + printf ("\tuae_u32 %s = %s;\n", name, reg); + return; + default: + abort (); + } + + /* We get here for all non-reg non-immediate addressing modes to + * actually fetch the value. */ + + if (using_exception_3 && getv != GENA_GETV_NO_FETCH && size != sz_byte) { + printf ("\tif ((%sa & 1) != 0) {\n", name); + printf ("\t\tlast_fault_for_exception_3 = %sa;\n", name); + printf ("\t\tlast_op_for_exception_3 = opcode;\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n", m68k_pc_offset); + printf ("\t\tException(3, 0);\n"); + printf ("\t\tgoto %s;\n", endlabelstr); + printf ("\t}\n"); + need_endlabel = 1; + start_brace (); + } + + if (getv == GENA_GETV_FETCH) { + switch (size) { + case sz_byte: break; + case sz_word: break; + case sz_long: break; + default: abort (); + } + start_brace (); + printf("\n#ifdef FULLMMU\n"); + switch (size) { + case sz_byte: printf ("\tuae_s8 %s = %sget_byte(%sa);\n", name, mem_prefix[xlateflag], name); break; + case sz_word: printf ("\tuae_s16 %s = %sget_word(%sa);\n", name, mem_prefix[xlateflag], name); break; + case sz_long: printf ("\tuae_s32 %s = %sget_long(%sa);\n", name, mem_prefix[xlateflag], name); break; + default: abort (); + } + printf("#else\n"); + switch (size) { + case sz_byte: printf ("\tuae_s8 %s = phys_get_byte(%sa);\n", name, name); break; + case sz_word: printf ("\tuae_s16 %s = phys_get_word(%sa);\n", name, name); break; + case sz_long: printf ("\tuae_s32 %s = phys_get_long(%sa);\n", name, name); break; + default: abort (); + } + printf("#endif\n"); + } + + /* We now might have to fix up the register for pre-dec or post-inc + * addressing modes. */ + if (!movem) + switch (mode) { + case Aipi: + if (fixup == 1) + { + printf ("\tfixup.flag = 1;\n"); + printf ("\tfixup.reg = %s;\n", reg); + printf ("\tfixup.value = m68k_areg(regs, %s);\n", reg); + } + switch (size) { + case sz_byte: + printf ("\tm68k_areg(regs, %s) += areg_byteinc[%s];\n", reg, reg); + break; + case sz_word: + printf ("\tm68k_areg(regs, %s) += 2;\n", reg); + break; + case sz_long: + printf ("\tm68k_areg(regs, %s) += 4;\n", reg); + break; + default: + abort (); + } + break; + case Apdi: + if (fixup == 1) + { + printf ("\tfixup.flag = 1;\n"); + printf ("\tfixup.reg = %s;\n", reg); + printf ("\tfixup.value = m68k_areg(regs, %s);\n", reg); + } + printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name); + break; + default: + break; + } + + } + else /* (fixup != 2) */ + { + if (!movem) + switch (mode) { + case Aipi: + case Apdi: + printf ("\tfixup.flag = 0;\n"); + break; + default: + break; + } + } +} + +static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int xlateflag) +{ + genamode2 (mode, reg, size, name, getv, movem, xlateflag, 0); +} + +static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to, int xlateflag) +{ + switch (mode) { + case Dreg: + switch (size) { + case sz_byte: + printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from); + break; + case sz_word: + printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from); + break; + case sz_long: + printf ("\tm68k_dreg(regs, %s) = (%s);\n", reg, from); + break; + default: + abort (); + } + break; + case Areg: + switch (size) { + case sz_word: + fprintf (stderr, "Foo\n"); + printf ("\tm68k_areg(regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from); + break; + case sz_long: + printf ("\tm68k_areg(regs, %s) = (%s);\n", reg, from); + break; + default: + abort (); + } + break; + case Aind: + case Aipi: + case Apdi: + case Ad16: + case Ad8r: + case absw: + case absl: + case PC16: + case PC8r: + gen_set_fault_pc (); + printf("#ifdef FULLMMU\n"); + switch (size) { + case sz_byte: + printf ("\t%sput_byte(%sa,%s);\n", mem_prefix[xlateflag], to, from); + printf("#else\n"); + printf ("\tput_byte(%sa,%s);\n", to, from); + break; + case sz_word: + if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) + abort (); + printf ("\t%sput_word(%sa,%s);\n", mem_prefix[xlateflag], to, from); + printf("#else\n"); + printf ("\tput_word(%sa,%s);\n", to, from); + break; + case sz_long: + if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) + abort (); + printf ("\t%sput_long(%sa,%s);\n", mem_prefix[xlateflag], to, from); + printf("#else\n"); + printf ("\tput_long(%sa,%s);\n", to, from); + break; + default: + abort (); + } + printf("#endif\n"); + break; + case imm: + case imm0: + case imm1: + case imm2: + case immi: + abort (); + break; + default: + abort (); + } +} + +static void genmovemel (uae_u16 opcode) +{ + char getcode1[100]; + char getcode2[100]; + int size = table68k[opcode].size == sz_long ? 4 : 2; + + if (table68k[opcode].size == sz_long) { + strcpy (getcode1, ""); + strcpy (getcode2, "get_long(srca)"); + } else { + strcpy (getcode1, "(uae_s32)(uae_s16)"); + strcpy (getcode2, "get_word(srca)"); + } + + printf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); + printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC, XLATE_LOG); + start_brace (); + printf("\n#ifdef FULLMMU\n"); + printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %s%s; srca += %d; dmask = movem_next[dmask]; }\n", + getcode1, getcode2, size); + printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %s%s; srca += %d; amask = movem_next[amask]; }\n", + getcode1, getcode2, size); + printf("#else\n"); + printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %sphys_%s; srca += %d; dmask = movem_next[dmask]; }\n", + getcode1, getcode2, size); + printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %sphys_%s; srca += %d; amask = movem_next[amask]; }\n", + getcode1, getcode2, size); + printf("#endif\n"); + + if (table68k[opcode].dmode == Aipi) + printf ("\tm68k_areg(regs, dstreg) = srca;\n"); +} + +static void genmovemle (uae_u16 opcode) +{ + char putcode[100]; + int size = table68k[opcode].size == sz_long ? 4 : 2; + + if (table68k[opcode].size == sz_long) { + strcpy (putcode, "put_long(srca,"); + } else { + strcpy (putcode, "put_word(srca,"); + } + + printf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); + genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", + GENA_GETV_FETCH_ALIGN, GENA_MOVEM_NO_INC, XLATE_LOG); + sync_m68k_pc (); + + start_brace (); + if (table68k[opcode].dmode == Apdi) { + printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); + printf("#ifdef FULLMMU\n"); + printf ("\twhile (amask) { srca -= %d; %s m68k_areg(regs, movem_index2[amask])); amask = movem_next[amask]; }\n", + size, putcode); + printf ("\twhile (dmask) { srca -= %d; %s m68k_dreg(regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", + size, putcode); + printf("#else\n"); + printf ("\twhile (amask) { srca -= %d; phys_%s m68k_areg(regs, movem_index2[amask])); amask = movem_next[amask]; }\n", + size, putcode); + printf ("\twhile (dmask) { srca -= %d; phys_%s m68k_dreg(regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", + size, putcode); + printf("#endif\n"); + printf ("\tm68k_areg(regs, dstreg) = srca;\n"); + } else { + printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); + printf("#ifdef FULLMMU\n"); + printf ("\twhile (dmask) { %s m68k_dreg(regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", + putcode, size); + printf ("\twhile (amask) { %s m68k_areg(regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", + putcode, size); + printf("#else\n"); + printf ("\twhile (dmask) { phys_%s m68k_dreg(regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", + putcode, size); + printf ("\twhile (amask) { phys_%s m68k_areg(regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", + putcode, size); + printf("#endif\n"); + } +} + +static void duplicate_carry (void) +{ + printf ("\tCOPY_CARRY();\n"); +} + +typedef enum { + flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn, + flag_av, flag_sv +} flagtypes; + +static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst) +{ + char vstr[100], sstr[100], dstr[100]; + char usstr[100], udstr[100]; + char unsstr[100], undstr[100]; + + switch (size) { + case sz_byte: + strcpy (vstr, "((uae_s8)("); + strcpy (usstr, "((uae_u8)("); + break; + case sz_word: + strcpy (vstr, "((uae_s16)("); + strcpy (usstr, "((uae_u16)("); + break; + case sz_long: + strcpy (vstr, "((uae_s32)("); + strcpy (usstr, "((uae_u32)("); + break; + default: + abort (); + } + strcpy (unsstr, usstr); + + strcpy (sstr, vstr); + strcpy (dstr, vstr); + strcat (vstr, value); + strcat (vstr, "))"); + strcat (dstr, dst); + strcat (dstr, "))"); + strcat (sstr, src); + strcat (sstr, "))"); + + strcpy (udstr, usstr); + strcat (udstr, dst); + strcat (udstr, "))"); + strcat (usstr, src); + strcat (usstr, "))"); + + strcpy (undstr, unsstr); + strcat (unsstr, "-"); + strcat (undstr, "~"); + strcat (undstr, dst); + strcat (undstr, "))"); + strcat (unsstr, src); + strcat (unsstr, "))"); + + switch (type) { + case flag_logical_noclobber: + case flag_logical: + case flag_z: + case flag_zn: + case flag_av: + case flag_sv: + case flag_addx: + case flag_subx: + break; + + case flag_add: + printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr); + break; + case flag_sub: + case flag_cmp: + printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr); + break; + } + + switch (type) { + case flag_logical_noclobber: + case flag_logical: + case flag_z: + case flag_zn: + break; + + case flag_add: + case flag_sub: + case flag_addx: + case flag_subx: + case flag_cmp: + case flag_av: + case flag_sv: + printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr); + printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr); + printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr); + break; + } + + switch (type) { + case flag_logical: + printf ("\tCLEAR_CZNV();\n"); + printf ("\tSET_ZFLG (%s == 0);\n", vstr); + printf ("\tSET_NFLG (%s < 0);\n", vstr); + break; + case flag_logical_noclobber: + printf ("\tSET_ZFLG (%s == 0);\n", vstr); + printf ("\tSET_NFLG (%s < 0);\n", vstr); + break; + case flag_av: + printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); + break; + case flag_sv: + printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); + break; + case flag_z: + printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr); + break; + case flag_zn: + printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr); + printf ("\tSET_NFLG (%s < 0);\n", vstr); + break; + case flag_add: + printf ("\tSET_ZFLG (%s == 0);\n", vstr); + printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); + printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr); + duplicate_carry (); + printf ("\tSET_NFLG (flgn != 0);\n"); + break; + case flag_sub: + printf ("\tSET_ZFLG (%s == 0);\n", vstr); + printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); + printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); + duplicate_carry (); + printf ("\tSET_NFLG (flgn != 0);\n"); + break; + case flag_addx: + printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */ + printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */ + duplicate_carry (); + break; + case flag_subx: + printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */ + printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */ + duplicate_carry (); + break; + case flag_cmp: + printf ("\tSET_ZFLG (%s == 0);\n", vstr); + printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n"); + printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); + printf ("\tSET_NFLG (flgn != 0);\n"); + break; + } +} + +static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) +{ + /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have + them in the appropriate m68k.h files and use just one copy of this + code here. The API can be changed if necessary. */ + int done = 0; + + start_brace (); + printf("\n#ifdef OPTIMIZED_FLAGS\n"); + switch (type) { + case flag_add: + case flag_sub: + printf ("\tuae_u32 %s;\n", value); + break; + default: + break; + } + + /* At least some of those casts are fairly important! */ + switch (type) { + case flag_logical_noclobber: + printf ("\t{uae_u32 oldcznv = GET_CZNV() & ~(FLAGVAL_Z | FLAGVAL_N);\n"); + if (strcmp (value, "0") == 0) { + printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n"); + } else { + switch (size) { + case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break; + case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break; + case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break; + } + printf ("\tIOR_CZNV (oldcznv);\n"); + } + printf ("\t}\n"); + done = 1; + break; + + case flag_logical: + if (strcmp (value, "0") == 0) { + printf ("\tSET_CZNV (FLAGVAL_Z);\n"); + } else { + switch (size) { + case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break; + case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break; + case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break; + } + } + done = 1; + break; + + case flag_add: + switch (size) { + case sz_byte: printf ("\toptflag_addb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; + case sz_word: printf ("\toptflag_addw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; + case sz_long: printf ("\toptflag_addl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; + } + done = 1; + break; + + case flag_sub: + switch (size) { + case sz_byte: printf ("\toptflag_subb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; + case sz_word: printf ("\toptflag_subw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; + case sz_long: printf ("\toptflag_subl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; + } + done = 1; + break; + + case flag_cmp: + switch (size) { + case sz_byte: printf ("\toptflag_cmpb ((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; + case sz_word: printf ("\toptflag_cmpw ((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; + case sz_long: printf ("\toptflag_cmpl ((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; + } + done = 1; + break; + + default: + break; + } + if (done) + printf("#else\n"); + else + printf("#endif\n"); + genflags_normal (type, size, value, src, dst); + if (done) + printf("#endif\n"); +} + +static void force_range_for_rox (const char *var, wordsizes size) +{ + /* Could do a modulo operation here... which one is faster? */ + switch (size) { + case sz_long: + printf ("\tif (%s >= 33) %s -= 33;\n", var, var); + break; + case sz_word: + printf ("\tif (%s >= 34) %s -= 34;\n", var, var); + printf ("\tif (%s >= 17) %s -= 17;\n", var, var); + break; + case sz_byte: + printf ("\tif (%s >= 36) %s -= 36;\n", var, var); + printf ("\tif (%s >= 18) %s -= 18;\n", var, var); + printf ("\tif (%s >= 9) %s -= 9;\n", var, var); + break; + } +} + +static const char *cmask (wordsizes size) +{ + switch (size) { + case sz_byte: return "0x80"; + case sz_word: return "0x8000"; + case sz_long: return "0x80000000"; + default: abort (); return NULL; + } +} + +static int source_is_imm1_8 (struct instr *i) +{ + return i->stype == 3; +} + +static void gen_opcode (unsigned long int opcode) +{ + struct instr *curi = table68k + opcode; + + start_brace (); +#if 0 + printf ("uae_u8 *m68k_pc = m68k_getpc();\n"); +#endif + m68k_pc_offset = 2; + switch (curi->plev) { + case 0: /* not privileged */ + break; + case 1: /* unprivileged only on 68000 */ + if (cpu_level == 0) + break; + if (next_cpu_level < 0) + next_cpu_level = 0; + + /* fall through */ + case 2: /* priviledged */ + printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr); + need_endlabel = 1; + start_brace (); + break; + case 3: /* privileged if size == word */ + if (curi->size == sz_byte) + break; + printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr); + need_endlabel = 1; + start_brace (); + break; + } + switch (curi->mnemo) { + case i_OR: + case i_AND: + case i_EOR: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); + genflags (flag_logical, curi->size, "src", "", ""); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_ORSR: + case i_EORSR: + printf ("\tMakeSR();\n"); + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) { + printf ("\tsrc &= 0xFF;\n"); + } + printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|'); + printf ("\tMakeFromSR();\n"); + break; + case i_ANDSR: + printf ("\tMakeSR();\n"); + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) { + printf ("\tsrc |= 0xFF00;\n"); + } + printf ("\tregs.sr &= src;\n"); + printf ("\tMakeFromSR();\n"); + break; + case i_SUB: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + genflags (flag_sub, curi->size, "newv", "src", "dst"); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_SUBA: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 newv = dst - src;\n"); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + break; + case i_SUBX: + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 1); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 2); + start_brace (); + printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n"); + genflags (flag_subx, curi->size, "newv", "src", "dst"); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_SBCD: + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 1); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 2); + start_brace (); + printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); + printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n"); + printf ("\tuae_u16 newv, tmp_newv;\n"); + printf ("\tint bcd = 0;\n"); + printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); + printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n"); + printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG () ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); + printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG () ? 1 : 0)) & 0x300) > 0xFF);\n"); + duplicate_carry (); + /* Manual says bits NV are undefined though a real 68030 doesn't change V and 68040/060 don't change both */ + if (cpu_level >= xBCD_KEEPS_N_FLAG) { + if (next_cpu_level < xBCD_KEEPS_N_FLAG) + next_cpu_level = xBCD_KEEPS_N_FLAG - 1; + genflags (flag_z, curi->size, "newv", "", ""); + } else { + genflags (flag_zn, curi->size, "newv", "", ""); + } + if (cpu_level >= xBCD_KEEPS_V_FLAG) { + if (next_cpu_level < xBCD_KEEPS_V_FLAG) + next_cpu_level = xBCD_KEEPS_V_FLAG - 1; + } else { + printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); + } + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_ADD: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + genflags (flag_add, curi->size, "newv", "src", "dst"); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_ADDA: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 newv = dst + src;\n"); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + break; + case i_ADDX: + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 1); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 2); + start_brace (); + printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n"); + genflags (flag_addx, curi->size, "newv", "src", "dst"); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_ABCD: + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 1); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 2); + start_brace (); + printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n"); + printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n"); + printf ("\tuae_u16 newv, tmp_newv;\n"); + printf ("\tint cflg;\n"); + printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); + printf ("\tif (newv_lo > 9) { newv += 6; }\n"); + printf ("\tcflg = (newv & 0x3F0) > 0x90;\n"); + printf ("\tif (cflg) newv += 0x60;\n"); + printf ("\tSET_CFLG (cflg);\n"); + duplicate_carry (); + /* Manual says bits NV are undefined though a real 68030 doesn't change V and 68040/060 don't change both */ + if (cpu_level >= xBCD_KEEPS_N_FLAG) { + if (next_cpu_level < xBCD_KEEPS_N_FLAG) + next_cpu_level = xBCD_KEEPS_N_FLAG - 1; + genflags (flag_z, curi->size, "newv", "", ""); + } else { + genflags (flag_zn, curi->size, "newv", "", ""); + } + if (cpu_level >= xBCD_KEEPS_V_FLAG) { + if (next_cpu_level < xBCD_KEEPS_V_FLAG) + next_cpu_level = xBCD_KEEPS_V_FLAG - 1; + } else { + printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); + } + genastore ("newv", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_NEG: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + genflags (flag_sub, curi->size, "dst", "src", "0"); + genastore ("dst", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_NEGX: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n"); + genflags (flag_subx, curi->size, "newv", "src", "0"); + genflags (flag_zn, curi->size, "newv", "", ""); + genastore ("newv", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_NBCD: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); + printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n"); + printf ("\tuae_u16 newv;\n"); + printf ("\tint cflg, tmp_newv;\n"); + printf ("\ttmp_newv = newv_hi + newv_lo;\n"); + printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n"); + printf ("\tnewv = newv_hi + newv_lo;\n"); + printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); + printf ("\tif (cflg) newv -= 0x60;\n"); + printf ("\tSET_CFLG (cflg);\n"); + duplicate_carry(); + /* Manual says bits NV are undefined though a real 68030 doesn't change V and 68040/060 don't change both */ + if (cpu_level >= xBCD_KEEPS_N_FLAG) { + if (next_cpu_level < xBCD_KEEPS_N_FLAG) + next_cpu_level = xBCD_KEEPS_N_FLAG - 1; + genflags (flag_z, curi->size, "newv", "", ""); + } else { + genflags (flag_zn, curi->size, "newv", "", ""); + } + if (cpu_level >= xBCD_KEEPS_V_FLAG) { + if (next_cpu_level < xBCD_KEEPS_V_FLAG) + next_cpu_level = xBCD_KEEPS_V_FLAG - 1; + } else { + printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); + } + genastore ("newv", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_CLR: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + genflags (flag_logical, curi->size, "0", "", ""); + genastore ("0", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_NOT: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 dst = ~src;\n"); + genflags (flag_logical, curi->size, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_TST: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genflags (flag_logical, curi->size, "src", "", ""); + break; + case i_BTST: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); + break; + case i_BCHG: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tdst ^= (1 << src);\n"); + printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_BCLR: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); + printf ("\tdst &= ~(1 << src);\n"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_BSET: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) + printf ("\tsrc &= 7;\n"); + else + printf ("\tsrc &= 31;\n"); + printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); + printf ("\tdst |= (1 << src);\n"); + genastore ("dst", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_CMPM: + case i_CMP: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + genflags (flag_cmp, curi->size, "newv", "src", "dst"); + break; + case i_CMPA: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + genflags (flag_cmp, sz_long, "newv", "src", "dst"); + break; + /* The next two are coded a little unconventional, but they are doing + * weird things... */ + case i_MVPRM: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + + printf ("\tuaecptr memp = m68k_areg(regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); + if (curi->size == sz_word) { + printf ("\tput_byte(memp, src >> 8); put_byte(memp + 2, src);\n"); + } else { + printf ("\tput_byte(memp, src >> 24); put_byte(memp + 2, src >> 16);\n"); + printf ("\tput_byte(memp + 4, src >> 8); put_byte(memp + 6, src);\n"); + } + break; + case i_MVPMR: + printf ("\tuaecptr memp = m68k_areg(regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_word) { + printf ("\tuae_u16 val = get_byte(memp) << 8;\n"); + printf ("\t val |= get_byte(memp + 2);\n"); + } else { + printf ("\tuae_u32 val = get_byte(memp) << 24;\n"); + printf ("\t val |= get_byte(memp + 2) << 16;\n"); + printf ("\t val |= get_byte(memp + 4) << 8;\n"); + printf ("\t val |= get_byte(memp + 6);\n"); + } + genastore ("val", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_MOVE: + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 1); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode2 (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 2); + genflags (flag_logical, curi->size, "src", "", ""); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_MOVEA: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_word) { + printf ("\tuae_u32 val = (uae_s32)(uae_s16)src;\n"); + } else { + printf ("\tuae_u32 val = src;\n"); + } + genastore ("val", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + break; + case i_MVSR2: + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tMakeSR();\n"); + if (curi->size == sz_byte) + genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src", XLATE_LOG); + else + genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src", XLATE_LOG); + break; + case i_MV2SR: + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + if (curi->size == sz_byte) + printf ("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); + else { + printf ("\tregs.sr = src;\n"); + } + printf ("\tMakeFromSR();\n"); + break; + case i_SWAP: + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n"); + genflags (flag_logical, sz_long, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", sz_long, "src", XLATE_LOG); + break; + case i_EXG: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genastore ("dst", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_EXT: + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break; + case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break; + case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break; + default: abort (); + } + genflags (flag_logical, + curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); + genastore ("dst", curi->smode, "srcreg", + curi->size == sz_word ? sz_word : sz_long, "src", XLATE_LOG); + break; + case i_MVMEL: + genmovemel (opcode); + break; + case i_MVMLE: + genmovemle (opcode); + break; + case i_TRAP: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + gen_set_fault_pc (); + printf ("\tException(src+32,0);\n"); + break; + case i_MVR2USP: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tregs.usp = src;\n"); + break; + case i_MVUSP2R: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_RESET: + printf ("\tAtariReset();\n"); + break; + case i_NOP: + break; + case i_STOP: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + /* + * STOP undocumented features: + * if SR is not set: + * 68000 (68010?): Update SR, increase PC and then cause privilege violation exception (handled in newcpu) + * 68000 (68010?): Traced STOP also runs 4 cycles faster. + * 68020 68030: STOP works normally + * 68040 68060: Immediate privilege violation exception + */ + printf ("\tuae_u16 sr = src;\n"); + if (cpu_level >= 4) { + printf("\tif (!(sr & 0x2000)) {\n"); + printf ("m68k_incpc(%d);\n", m68k_pc_offset); + printf("\t\tException(8,0); goto %s;\n", endlabelstr); + printf("\t}\n"); + } + printf("\tregs.sr = sr;\n"); + printf ("\tMakeFromSR();\n"); + printf ("\tm68k_setstopped(1);\n"); + sync_m68k_pc (); + /* STOP does not prefetch anything */ + /* did_prefetch = -1; */ + break; + case i_RTE: + if (cpu_level == 0) { + genamode (Aipi, "7", sz_word, "sr", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tregs.sr = sr; m68k_setpc_rte(pc);\n"); + fill_prefetch_0 (); + printf ("\tMakeFromSR();\n"); + } else { + if (next_cpu_level < 0) + next_cpu_level = 0; + printf ("\tex_rte();\n"); + } + /* PC is set and prefetch filled. */ + m68k_pc_offset = 0; + break; + case i_RTD: + genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tm68k_areg(regs, 7) += offs;\n"); + printf ("\tm68k_setpc_rte(pc);\n"); + fill_prefetch_0 (); + /* PC is set and prefetch filled. */ + m68k_pc_offset = 0; + break; + case i_LINK: + genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src", XLATE_LOG); + printf ("\tm68k_areg(regs, 7) += offs;\n"); + genastore ("src", Apdi, "7", sz_long, "old", XLATE_LOG); + break; + case i_UNLK: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tm68k_areg(regs, 7) = src;\n"); + genamode (Aipi, "7", sz_long, "old", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genastore ("old", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_RTS: + printf ("\tm68k_do_rts();\n"); + fill_prefetch_0 (); + m68k_pc_offset = 0; + break; + case i_TRAPV: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + sync_m68k_pc (); + printf ("\tif (GET_VFLG ()) { Exception(7,oldpc); goto %s; }\n", endlabelstr); + need_endlabel = 1; + break; + case i_RTR: + printf ("\tMakeSR();\n"); + genamode2 (Aipi, "7", sz_word, "sr", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 1); + genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode2 (Aipi, "7", sz_word, "sr", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG, 2); + printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); + printf ("\tregs.sr |= sr; m68k_setpc(pc);\n"); + fill_prefetch_0 (); + printf ("\tMakeFromSR();\n"); + m68k_pc_offset = 0; + break; + case i_JSR: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC, XLATE_PHYS); + printf ("\tm68k_do_jsr(m68k_getpc() + %d, srca);\n", m68k_pc_offset); + fill_prefetch_0 (); + m68k_pc_offset = 0; + break; + case i_JMP: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC, XLATE_PHYS); + printf ("\tm68k_setpc(srca);\n"); + fill_prefetch_0 (); + m68k_pc_offset = 0; + break; + case i_BSR: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_PHYS); + printf ("\tuae_s32 s = (uae_s32)src + 2;\n"); + if (using_exception_3) { + printf ("\tif (src & 1) {\n"); + printf ("\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); + printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + s;\n"); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t}\n"); + need_endlabel = 1; + } + printf ("\tm68k_do_bsr(m68k_getpc() + %d, s);\n", m68k_pc_offset); + fill_prefetch_0 (); + m68k_pc_offset = 0; + break; + case i_Bcc: + if (curi->size == sz_long) { + if (cpu_level < 2) { + printf ("\tm68k_incpc(2);\n"); + printf ("\tif (!cctrue(%d)) goto %s;\n", curi->cc, endlabelstr); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); + printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 1;\n"); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + need_endlabel = 1; + } else { + if (next_cpu_level < 1) + next_cpu_level = 1; + } + } + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_PHYS); + printf ("\tif (!cctrue(%d)) goto didnt_jump_%lx;\n", curi->cc, opcode); + if (using_exception_3) { + printf ("\tif (src & 1) {\n"); + printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); + printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)src;\n"); + printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t}\n"); + need_endlabel = 1; + } + printf ("\tm68k_incpc ((uae_s32)src + 2);\n"); + fill_prefetch_0 (); + printf ("return;\n"); + printf ("didnt_jump_%lx:;\n", opcode); + need_endlabel = 1; + break; + case i_LEA: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + genastore ("srca", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + break; + case i_PEA: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_NO_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (Apdi, "7", sz_long, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + genastore ("srca", Apdi, "7", sz_long, "dst", XLATE_LOG); + break; + case i_DBcc: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + + printf ("\tif (!cctrue(%d)) {\n", curi->cc); + genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + + printf ("\t\tif (src) {\n"); + if (using_exception_3) { + printf ("\t\t\tif (offs & 1) {\n"); + printf ("\t\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); + printf ("\t\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)offs + 2;\n"); + printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr); + printf ("\t\t}\n"); + need_endlabel = 1; + } + printf ("\t\t\tm68k_incpc((uae_s32)offs + 2);\n"); + fill_prefetch_0 (); + printf ("return;\n"); + printf ("\t\t}\n"); + printf ("\t}\n"); + need_endlabel = 1; + break; + case i_Scc: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", curi->cc); + genastore ("val", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_DIVU: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + /* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends + * on this (actually, it's doing a DIVS). */ + printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc); goto %s; } else {\n", endlabelstr); + printf ("\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); + printf ("\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); + /* The N flag appears to be set each time there is an overflow. + * Weird. */ + printf ("\tif (newv > 0xffff) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n"); + genflags (flag_logical, sz_word, "newv", "", ""); + printf ("\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + printf ("\t}\n"); + printf ("\t}\n"); + need_endlabel = 1; + break; + case i_DIVS: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc); goto %s; } else {\n", endlabelstr); + printf ("\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); + printf ("\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); + printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n"); + printf ("\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n"); + genflags (flag_logical, sz_word, "newv", "", ""); + printf ("\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + printf ("\t}\n"); + printf ("\t}\n"); + need_endlabel = 1; + break; + case i_MULU: + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); + genflags (flag_logical, sz_long, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + break; + case i_MULS: + genamode (curi->smode, "srcreg", sz_word, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_word, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); + genflags (flag_logical, sz_long, "newv", "", ""); + genastore ("newv", curi->dmode, "dstreg", sz_long, "dst", XLATE_LOG); + break; + case i_CHK: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tif ((uae_s32)dst < 0) { SET_NFLG (1); Exception(6,oldpc); goto %s; }\n", endlabelstr); + printf ("\telse if (dst > src) { SET_NFLG (0); Exception(6,oldpc); goto %s; }\n", endlabelstr); + need_endlabel = 1; + break; + + case i_CHK2: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); + switch (curi->size) { + case sz_byte: + printf ("\tlower=(uae_s32)(uae_s8)get_byte(dsta); upper = (uae_s32)(uae_s8)get_byte(dsta+1);\n"); + printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n"); + break; + case sz_word: + printf ("\tlower=(uae_s32)(uae_s16)get_word(dsta); upper = (uae_s32)(uae_s16)get_word(dsta+2);\n"); + printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n"); + break; + case sz_long: + printf ("\tlower=get_long(dsta); upper = get_long(dsta+4);\n"); + break; + default: + abort (); + } + printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); + printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); + printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception(6,oldpc); goto %s; }\n}\n", endlabelstr); + need_endlabel = 1; + break; + + case i_ASR: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1); + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size)); + printf ("\t\tSET_CFLG (sign);\n"); + duplicate_carry (); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tval >>= cnt - 1;\n"); + printf ("\t\tSET_CFLG (val & 1);\n"); + duplicate_carry (); + printf ("\t\tval >>= 1;\n"); + printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n", + bit_mask (curi->size), + bit_size (curi->size)); + printf ("\t\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_ASL: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tSET_VFLG (val != 0);\n"); + printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", + bit_size (curi->size)); + duplicate_carry (); + printf ("\t\tval = 0;\n"); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n", + bit_mask (curi->size), + bit_size (curi->size) - 1, + bit_mask (curi->size)); + printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n"); + printf ("\t\tval <<= cnt - 1;\n"); + printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + duplicate_carry (); + printf ("\t\tval <<= 1;\n"); + printf ("\t\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_LSR: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n", + bit_size (curi->size), bit_size (curi->size) - 1); + duplicate_carry (); + printf ("\t\tval = 0;\n"); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tval >>= cnt - 1;\n"); + printf ("\t\tSET_CFLG (val & 1);\n"); + duplicate_carry (); + printf ("\t\tval >>= 1;\n"); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_LSL: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); + printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", + bit_size (curi->size)); + duplicate_carry (); + printf ("\t\tval = 0;\n"); + if (source_is_imm1_8 (curi)) + printf ("\t} else {\n"); + else + printf ("\t} else if (cnt > 0) {\n"); + printf ("\t\tval <<= (cnt - 1);\n"); + printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + duplicate_carry (); + printf ("\t\tval <<= 1;\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_ROL: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else + printf ("\tif (cnt > 0) {\n"); + printf ("\tuae_u32 loval;\n"); + printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); + printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size)); + printf ("\tval <<= cnt;\n"); + printf ("\tval |= loval;\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\tSET_CFLG (val & 1);\n"); + printf ("}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_ROR: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else + printf ("\tif (cnt > 0) {"); + printf ("\tuae_u32 hival;\n"); + printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); + printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size)); + printf ("\tval >>= cnt;\n"); + printf ("\tval |= hival;\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); + printf ("\t}\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_ROXL: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else { + force_range_for_rox ("cnt", curi->size); + printf ("\tif (cnt > 0) {\n"); + } + printf ("\tcnt--;\n"); + printf ("\t{\n\tuae_u32 carry;\n"); + printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1); + printf ("\tcarry = loval & 1;\n"); + printf ("\tval = (((val << 1) | GET_XFLG ()) << cnt) | (loval >> 1);\n"); + printf ("\tSET_XFLG (carry);\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t} }\n"); + printf ("\tSET_CFLG (GET_XFLG ());\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_ROXR: + genamode (curi->smode, "srcreg", curi->size, "cnt", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tcnt &= 63;\n"); + printf ("\tCLEAR_CZNV();\n"); + if (source_is_imm1_8 (curi)) + printf ("{"); + else { + force_range_for_rox ("cnt", curi->size); + printf ("\tif (cnt > 0) {\n"); + } + printf ("\tcnt--;\n"); + printf ("\t{\n\tuae_u32 carry;\n"); + printf ("\tuae_u32 hival = (val << 1) | GET_XFLG ();\n"); + printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1); + printf ("\tval >>= cnt;\n"); + printf ("\tcarry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + printf ("\tval |= hival;\n"); + printf ("\tSET_XFLG (carry);\n"); + printf ("\tval &= %s;\n", bit_mask (curi->size)); + printf ("\t} }\n"); + printf ("\tSET_CFLG (GET_XFLG ());\n"); + genflags (flag_logical_noclobber, curi->size, "val", "", ""); + genastore ("val", curi->dmode, "dstreg", curi->size, "data", XLATE_LOG); + break; + case i_ASRW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); + printf ("\tuae_u32 cflg = val & 1;\n"); + printf ("\tval = (val >> 1) | sign;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("\tSET_CFLG (cflg);\n"); + duplicate_carry (); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_ASLW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); + printf ("\tuae_u32 sign2;\n"); + printf ("\tval <<= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("\tsign2 = %s & val;\n", cmask (curi->size)); + printf ("\tSET_CFLG (sign != 0);\n"); + duplicate_carry (); + + printf ("\tSET_VFLG (GET_VFLG () | (sign2 != sign));\n"); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_LSRW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; + case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (carry);\n"); + duplicate_carry (); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_LSLW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); + printf ("\tval <<= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); + duplicate_carry (); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_ROLW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); + printf ("\tval <<= 1;\n"); + printf ("\tif (carry) val |= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_RORW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + printf ("\tif (carry) val |= %s;\n", cmask (curi->size)); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (carry);\n"); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_ROXLW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); + printf ("\tval <<= 1;\n"); + printf ("\tif (GET_XFLG ()) val |= 1;\n"); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); + duplicate_carry (); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_ROXRW: + genamode (curi->smode, "srcreg", curi->size, "data", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + switch (curi->size) { + case sz_byte: printf ("\tuae_u8 val = data;\n"); break; + case sz_word: printf ("\tuae_u16 val = data;\n"); break; + case sz_long: printf ("\tuae_u32 val = data;\n"); break; + default: abort (); + } + printf ("\tuae_u32 carry = val & 1;\n"); + printf ("\tval >>= 1;\n"); + printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size)); + genflags (flag_logical, curi->size, "val", "", ""); + printf ("SET_CFLG (carry);\n"); + duplicate_carry (); + genastore ("val", curi->smode, "srcreg", curi->size, "data", XLATE_LOG); + break; + case i_MOVEC2: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tint regno = (src >> 12) & 15;\n"); + printf ("\tuae_u32 *regp = regs.regs + regno;\n"); + printf ("\tif (!m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr); + break; + case i_MOVE2C: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tint regno = (src >> 12) & 15;\n"); + printf ("\tuae_u32 *regp = regs.regs + regno;\n"); + printf ("\tif (!m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr); + break; + case i_CAS: + { + int old_brace_level; + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tint ru = (src >> 6) & 7;\n"); + printf ("\tint rc = src & 7;\n"); + genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc)", "dst"); + sync_m68k_pc (); + printf ("\tif (GET_ZFLG ())"); + old_brace_level = n_braces; + start_brace (); + genastore ("(m68k_dreg(regs, ru))", curi->dmode, "dstreg", curi->size, "dst", XLATE_LOG); + pop_braces (old_brace_level); + printf ("else"); + start_brace (); + switch (curi->size) { + case sz_byte: + printf ("\tm68k_dreg(regs, rc) = (m68k_dreg(regs, rc) & ~0xff) | (dst & 0xff);\n"); + break; + case sz_word: + printf ("\tm68k_dreg(regs, rc) = (m68k_dreg(regs, rc) & ~0xffff) | (dst & 0xffff);\n"); + break; + default: + printf ("\tm68k_dreg(regs, rc) = dst;\n"); + break; + } + pop_braces (old_brace_level); + } + break; + case i_CAS2: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n"); + printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n"); + if (curi->size == sz_word) { + int old_brace_level = n_braces; + printf ("\tuae_u32 rc1 = (extra >> 16) & 7;\n"); + printf ("\tuae_u32 rc2 = extra & 7;\n"); + printf ("\tuae_u16 dst1 = get_word(rn1), dst2 = get_word(rn2);\n"); + genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc1)", "dst1"); + printf ("\tif (GET_ZFLG ()) {\n"); + genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc2)", "dst2"); + printf ("\tif (GET_ZFLG ()) {\n"); + printf ("\tput_word(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n"); + printf ("\tput_word(rn2, m68k_dreg(regs, (extra >> 6) & 7));\n"); + printf ("\t}}\n"); + pop_braces (old_brace_level); + printf ("\tif (! GET_ZFLG ()) {\n"); + printf ("\tm68k_dreg(regs, rc2) = (m68k_dreg(regs, rc2) & ~0xffff) | (dst2 & 0xffff);\n"); + printf ("\tm68k_dreg(regs, rc1) = (m68k_dreg(regs, rc1) & ~0xffff) | (dst1 & 0xffff);\n"); + printf ("\t}\n"); + } else { + int old_brace_level = n_braces; + printf ("\tuae_u32 rc1 = (extra >> 16) & 7;\n"); + printf ("\tuae_u32 rc2 = extra & 7;\n"); + printf ("\tuae_u32 dst1 = get_long(rn1), dst2 = get_long(rn2);\n"); + genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc1)", "dst1"); + printf ("\tif (GET_ZFLG ()) {\n"); + genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc2)", "dst2"); + printf ("\tif (GET_ZFLG ()) {\n"); + printf ("\tput_long(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n"); + printf ("\tput_long(rn2, m68k_dreg(regs, (extra >> 6) & 7));\n"); + printf ("\t}}\n"); + pop_braces (old_brace_level); + printf ("\tif (! GET_ZFLG ()) {\n"); + printf ("\tm68k_dreg(regs, rc2) = dst2;\n"); + printf ("\tm68k_dreg(regs, rc1) = dst1;\n"); + printf ("\t}\n"); + } + break; + case i_MOVES: + { + int old_brace_level; + + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace(); + printf ("\tif (extra & 0x0800)\n"); /* from reg to ea */ + { + int old_m68k_pc_offset = m68k_pc_offset; + /* use DFC */ + old_brace_level = n_braces; + start_brace (); + printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n"); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_DFC); + genastore ("src", curi->dmode, "dstreg", curi->size, "dst", XLATE_DFC); + pop_braces (old_brace_level); + m68k_pc_offset = old_m68k_pc_offset; + } + printf ("else"); /* from ea to reg */ + { + /* use SFC */ + start_brace (); + genamode (curi->dmode, "dstreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_SFC); + printf ("\tif (extra & 0x8000) {\n"); /* address/data */ + switch (curi->size) { + case sz_byte: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break; + case sz_word: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break; + case sz_long: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = src;\n"); break; + default: abort (); + } + printf ("\t} else {\n"); + genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "", XLATE_LOG); + printf ("\t}\n"); + sync_m68k_pc(); + pop_braces (old_brace_level); + } + } + break; + case i_BKPT: /* only needed for hardware emulators */ + sync_m68k_pc (); + printf ("\top_illg(opcode);\n"); + break; + case i_CALLM: /* not present in 68030 */ + sync_m68k_pc (); + printf ("\top_illg(opcode);\n"); + break; + case i_RTM: /* not present in 68030 */ + sync_m68k_pc (); + printf ("\top_illg(opcode);\n"); + break; + case i_TRAPcc: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + if (curi->smode != am_unknown && curi->smode != am_illg) + genamode (curi->smode, "srcreg", curi->size, "dummy", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + printf ("\tif (cctrue(%d)) { Exception(7,oldpc); goto %s; }\n", curi->cc, endlabelstr); + need_endlabel = 1; + break; + case i_DIVL: + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n"); + break; + case i_MULL: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "dst", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + printf ("\tm68k_mull(opcode, dst, extra);\n"); + break; + case i_BFTST: + case i_BFEXTU: + case i_BFCHG: + case i_BFEXTS: + case i_BFCLR: + case i_BFFFO: + case i_BFSET: + case i_BFINS: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genamode (curi->dmode, "dstreg", sz_long, "dst", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, XLATE_LOG); + start_brace (); + printf ("\tuae_u32 bdata[2];"); + printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n"); + printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n"); + if (curi->dmode == Dreg) { + printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg);\n"); + printf ("\toffset &= 0x1f;\n"); + printf ("\ttmp = (tmp << offset) | (tmp >> (32 - offset));\n"); + printf ("\tbdata[0] = tmp & ((1 << (32 - width)) - 1);\n"); + } else { + printf ("\tuae_u32 tmp;\n"); + printf ("\tdsta += offset >> 3;\n"); + printf ("\ttmp = get_bitfield(dsta, bdata, offset, width);\n"); + } + printf ("\tSET_NFLG_ALWAYS (((uae_s32)tmp) < 0 ? 1 : 0);\n"); + if (curi->mnemo == i_BFEXTS) + printf ("\ttmp = (uae_s32)tmp >> (32 - width);\n"); + else + printf ("\ttmp >>= (32 - width);\n"); + printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n"); + switch (curi->mnemo) { + case i_BFTST: + break; + case i_BFEXTU: + case i_BFEXTS: + printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n"); + break; + case i_BFCHG: + printf ("\ttmp = tmp ^ (0xffffffffu >> (32 - width));\n"); + break; + case i_BFCLR: + printf ("\ttmp = 0;\n"); + break; + case i_BFFFO: + printf ("\t{ uae_u32 mask = 1 << (width-1);\n"); + printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n"); + printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = offset;\n"); + break; + case i_BFSET: + printf ("\ttmp = 0xffffffffu >> (32 - width);\n"); + break; + case i_BFINS: + printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n"); + printf ("\ttmp = tmp & (0xffffffffu >> (32 - width));\n"); + printf ("\tSET_NFLG_ALWAYS (tmp & (1 << (width - 1)) ? 1 : 0);\n"); + printf ("\tSET_ZFLG (tmp == 0);\n"); + break; + default: + break; + } + if (curi->mnemo == i_BFCHG + || curi->mnemo == i_BFCLR + || curi->mnemo == i_BFSET + || curi->mnemo == i_BFINS) { + if (curi->dmode == Dreg) { + printf ("\ttmp = bdata[0] | (tmp << (32 - width));\n"); + printf ("\tm68k_dreg(regs, dstreg) = (tmp >> offset) | (tmp << (32 - offset));\n"); + } else { + printf ("\tput_bitfield(dsta, bdata, tmp, offset, width);\n"); + } + } + break; + case i_PACK: + if (curi->smode == Dreg) { + printf ("\tuae_u16 val = m68k_dreg(regs, srcreg) + %s;\n", gen_nextiword ()); + printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); + } else { + printf ("\tuae_u16 val;\n"); + printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg) - areg_byteinc[srcreg]);\n"); + printf ("\tval = (val | ((uae_u16)get_byte(m68k_areg(regs, srcreg) - 2 * areg_byteinc[srcreg]) << 8)) + %s;\n", gen_nextiword ()); + printf ("\tm68k_areg(regs, srcreg) -= 2;\n"); + printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); + gen_set_fault_pc (); + printf ("\tput_byte(m68k_areg(regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n"); + } + break; + case i_UNPK: + if (curi->smode == Dreg) { + printf ("\tuae_u16 val = m68k_dreg(regs, srcreg);\n"); + printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ()); + printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffff0000) | (val & 0xffff);\n"); + } else { + printf ("\tuae_u16 val;\n"); + printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg) - areg_byteinc[srcreg]);\n"); + printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ()); + printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); + printf ("\tm68k_areg(regs, dstreg) -= 2;\n"); + gen_set_fault_pc (); + printf ("\tput_word(m68k_areg(regs, dstreg), val);\n"); + } + break; + case i_TAS: + genamode (curi->smode, "srcreg", curi->size, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + genflags (flag_logical, curi->size, "src", "", ""); + printf ("\tsrc |= 0x80;\n"); + genastore ("src", curi->smode, "srcreg", curi->size, "src", XLATE_LOG); + break; + case i_FPP: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_arithmetic(opcode, extra);\n"); + break; + case i_FDBcc: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_dbcc(opcode, extra);\n"); + break; + case i_FScc: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_scc(opcode, extra);\n"); + break; + case i_FTRAPcc: + sync_m68k_pc (); + start_brace (); + printf ("\tuaecptr oldpc = m68k_getpc();\n"); + printf ("\tuae_u16 extra = %s;\n", gen_nextiword()); + if (curi->smode != am_unknown && curi->smode != am_illg) + genamode (curi->smode, "srcreg", curi->size, "dummy", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_trapcc(opcode, oldpc, extra);\n"); + break; + case i_FBcc: + sync_m68k_pc (); + start_brace (); + printf ("\tuaecptr pc = m68k_getpc();\n"); + genamode (curi->dmode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_bcc(opcode, pc, extra);\n"); + break; + case i_FSAVE: + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_save(opcode);\n"); + break; + case i_FRESTORE: + sync_m68k_pc (); + swap_opcode (); + printf ("\tfpuop_restore(opcode);\n"); + break; + case i_CINVL: + printf ("\tflush_internals();\n"); + printf("#ifdef USE_JIT\n"); + printf ("\tif (opcode&0x80)\n" + "\t\tflush_icache();\n"); + printf("#endif\n"); + break; + case i_CINVP: + printf ("\tflush_internals();\n"); + printf("#ifdef USE_JIT\n"); + printf ("\tif (opcode&0x80)\n" + "\t\tflush_icache();\n"); + printf("#endif\n"); + break; + case i_CINVA: + printf ("\tflush_internals();\n"); + printf("#ifdef USE_JIT\n"); + printf ("\tif (opcode&0x80)\n" + "\t\tflush_icache();\n"); + printf("#endif\n"); + break; + case i_CPUSHL: + printf ("\tflush_internals();\n"); + printf("#ifdef USE_JIT\n"); + printf ("\tif (opcode&0x80)\n" + "\t\tflush_icache();\n"); + printf("#endif\n"); + break; + case i_CPUSHP: + printf ("\tflush_internals();\n"); + printf("#ifdef USE_JIT\n"); + printf ("\tif (opcode&0x80)\n" + "\t\tflush_icache();\n"); + printf("#endif\n"); + break; + case i_CPUSHA: + printf ("\tflush_internals();\n"); + printf("#ifdef USE_JIT\n"); + printf ("\tif (opcode&0x80)\n" + "\t\tflush_icache();\n"); + printf("#endif\n"); + break; + case i_MOVE16: + if ((opcode & 0xfff8) == 0xf620) { + /* MOVE16 (Ax)+,(Ay)+ */ + printf ("\tuaecptr mems = m68k_areg(regs, srcreg) & ~15, memd;\n"); + printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword()); + printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n"); + printf ("\tput_long(memd, get_long(mems));\n"); + printf ("\tput_long(memd+4, get_long(mems+4));\n"); + printf ("\tput_long(memd+8, get_long(mems+8));\n"); + printf ("\tput_long(memd+12, get_long(mems+12));\n"); + printf ("\tif (srcreg != dstreg)\n"); + printf ("\tm68k_areg(regs, srcreg) += 16;\n"); + printf ("\tm68k_areg(regs, dstreg) += 16;\n"); + } else { + /* Other variants */ + genamode (curi->smode, "srcreg", curi->size, "mems", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16, XLATE_LOG); + genamode (curi->dmode, "dstreg", curi->size, "memd", GENA_GETV_NO_FETCH, GENA_MOVEM_MOVE16, XLATE_LOG); + printf ("\tmemsa &= ~15;\n"); + printf ("\tmemda &= ~15;\n"); + printf ("\tput_long(memda, get_long(memsa));\n"); + printf ("\tput_long(memda+4, get_long(memsa+4));\n"); + printf ("\tput_long(memda+8, get_long(memsa+8));\n"); + printf ("\tput_long(memda+12, get_long(memsa+12));\n"); + if ((opcode & 0xfff8) == 0xf600) + printf ("\tm68k_areg(regs, srcreg) += 16;\n"); + else if ((opcode & 0xfff8) == 0xf608) + printf ("\tm68k_areg(regs, dstreg) += 16;\n"); + } + break; + case i_MMUOP: + genamode (curi->smode, "srcreg", curi->size, "extra", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG); + sync_m68k_pc (); + swap_opcode (); + printf ("\tmmu_op(opcode,extra);\n"); + break; + + case i_EMULOP_RETURN: + printf ("\tm68k_emulop_return();\n"); + m68k_pc_offset = 0; + break; + + case i_EMULOP: + printf ("\n"); + swap_opcode (); + printf ("\tm68k_emulop(opcode);\n"); + break; + + case i_NATFEAT_ID: + printf ("\n"); + printf ("\tm68k_natfeat_id();\n"); + break; + + case i_NATFEAT_CALL: + printf ("\n"); + printf ("\tm68k_natfeat_call();\n"); + break; + + default: + abort (); + break; + } + finish_braces (); + sync_m68k_pc (); +} + +static void generate_includes (FILE * f) +{ + fprintf (f, "#include \"sysdeps.h\"\n"); + fprintf (f, "#include \"m68k.h\"\n"); + fprintf (f, "#include \"memory.h\"\n"); + fprintf (f, "#include \"readcpu.h\"\n"); + fprintf (f, "#include \"newcpu.h\"\n"); + fprintf (f, "#ifdef USE_JIT\n"); + fprintf (f, "#include \"compiler/compemu.h\"\n"); + fprintf (f, "#endif\n"); + fprintf (f, "#include \"fpu/fpu.h\"\n"); + fprintf (f, "#include \"cputbl.h\"\n"); + fprintf (f, "#include \"cpu_emulation.h\"\n"); + fprintf (f, "#include \"debug.h\"\n"); + + fprintf (f, "#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n"); + fprintf (f, "#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n"); + fprintf (f, "#define CPUFUNC_FF(x) x##_ff\n"); + fprintf (f, "#define CPUFUNC_NF(x) x##_nf\n"); + fprintf (f, "#define CPUFUNC(x) CPUFUNC_FF(x)\n"); + + fprintf (f, "#ifdef NOFLAGS\n"); + fprintf (f, "# include \"noflags.h\"\n"); + fprintf (f, "#endif\n"); +} + +static int postfix; + +struct gencputbl { + char handler[80]; + uae_u16 specific; + uae_u16 opcode; + int namei; +}; +struct gencputbl cpustbl[65536]; +static int n_cpustbl; + +static char *decodeEA (amodes mode, wordsizes size) +{ + static char buffer[80]; + + buffer[0] = 0; + switch (mode){ + case Dreg: + strcpy (buffer,"Dn"); + break; + case Areg: + strcpy (buffer,"An"); + break; + case Aind: + strcpy (buffer,"(An)"); + break; + case Aipi: + strcpy (buffer,"(An)+"); + break; + case Apdi: + strcpy (buffer,"-(An)"); + break; + case Ad16: + strcpy (buffer,"(d16,An)"); + break; + case Ad8r: + strcpy (buffer,"(d8,An,Xn)"); + break; + case PC16: + strcpy (buffer,"(d16,PC)"); + break; + case PC8r: + strcpy (buffer,"(d8,PC,Xn)"); + break; + case absw: + strcpy (buffer,"(xxx).W"); + break; + case absl: + strcpy (buffer,"(xxx).L"); + break; + case imm: + switch (size){ + case sz_byte: + strcpy (buffer,"#.B"); + break; + case sz_word: + strcpy (buffer,"#.W"); + break; + case sz_long: + strcpy (buffer,"#.L"); + break; + default: + break; + } + break; + case imm0: + strcpy (buffer,"#.B"); + break; + case imm1: + strcpy (buffer,"#.W"); + break; + case imm2: + strcpy (buffer,"#.L"); + break; + case immi: + strcpy (buffer,"#"); + break; + + default: + break; + } + return buffer; +} + +static char *outopcode (const char *name, int opcode) +{ + static char out[100]; + struct instr *ins; + + ins = &table68k[opcode]; + strcpy (out, name); + if (ins->smode == immi) + strcat (out, "Q"); + if (ins->size == sz_byte) + strcat (out,".B"); + if (ins->size == sz_word) + strcat (out,".W"); + if (ins->size == sz_long) + strcat (out,".L"); + strcat (out," "); + if (ins->suse) + strcat (out, decodeEA (ins->smode, ins->size)); + if (ins->duse) { + if (ins->suse) strcat (out,","); + strcat (out, decodeEA (ins->dmode, ins->size)); + } + return out; +} + + +static void generate_one_opcode (int rp) +{ + int i; + uae_u16 smsk, dmsk; + int opcode = opcode_map[rp]; + int have_realopcode = 0; + const char *name; + + if (table68k[opcode].mnemo == i_ILLG + || table68k[opcode].clev > cpu_level) + return; + + for (i = 0; lookuptab[i].name[0]; i++) { + if (table68k[opcode].mnemo == lookuptab[i].mnemo) + break; + } + + if (table68k[opcode].handler != -1) + return; + + name = lookuptab[i].name; + if (opcode_next_clev[rp] != cpu_level) { + sprintf(cpustbl[n_cpustbl].handler, "CPUFUNC(op_%x_%d)", opcode, opcode_last_postfix[rp]); + cpustbl[n_cpustbl].specific = 0; + cpustbl[n_cpustbl].opcode = opcode; + cpustbl[n_cpustbl].namei = i; + fprintf (stblfile, "{ %s, %d, %d }, /* %s */\n", cpustbl[n_cpustbl].handler, cpustbl[n_cpustbl].specific, opcode, name); + n_cpustbl++; + return; + } + + if (table68k[opcode].flagdead == 0) + /* force to the "ff" variant since the instruction doesn't set at all the condition codes */ + sprintf (cpustbl[n_cpustbl].handler, "CPUFUNC_FF(op_%x_%d)", opcode, postfix); + else + sprintf (cpustbl[n_cpustbl].handler, "CPUFUNC(op_%x_%d)", opcode, postfix); + cpustbl[n_cpustbl].specific = 0; + cpustbl[n_cpustbl].opcode = opcode; + cpustbl[n_cpustbl].namei = i; + fprintf (stblfile, "{ %s, %d, %d }, /* %s */\n", cpustbl[n_cpustbl].handler, cpustbl[n_cpustbl].specific, opcode, name); + n_cpustbl++; + + fprintf (headerfile, "extern cpuop_func op_%x_%d_nf;\n", opcode, postfix); + fprintf (headerfile, "extern cpuop_func op_%x_%d_ff;\n", opcode, postfix); + + printf ("/* %s */\n", outopcode (name, opcode)); + printf ("void REGPARAM2 CPUFUNC(op_%x_%d)(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, name); + printf ("\tcpuop_begin();\n"); + /* gb-- The "nf" variant for an instruction that doesn't set the condition + codes at all is the same as the "ff" variant, so we don't need the "nf" + variant to be compiled since it is mapped to the "ff" variant in the + smalltbl. */ + if (table68k[opcode].flagdead == 0) + printf ("#ifndef NOFLAGS\n"); + + switch (table68k[opcode].stype) { + case 0: smsk = 7; break; + case 1: smsk = 255; break; + case 2: smsk = 15; break; + case 3: smsk = 7; break; + case 4: smsk = 7; break; + case 5: smsk = 63; break; + case 6: smsk = 255; break; + case 7: smsk = 3; break; + default: abort (); + } + dmsk = 7; + + next_cpu_level = -1; + if (table68k[opcode].suse + && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 + && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 + && table68k[opcode].smode != absw && table68k[opcode].smode != absl + && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16 + /* gb-- We don't want to fetch the EmulOp code since the EmulOp() + routine uses the whole opcode value. Maybe all the EmulOps + could be expanded out but I don't think it is an improvement */ + && table68k[opcode].stype != 6 + ) + { + if (table68k[opcode].spos == -1) { + if (((int) table68k[opcode].sreg) >= 128) + printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); + else + printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg); + } else { + char source[100]; + int pos = table68k[opcode].spos; + +#if 0 + /* Check that we can do the little endian optimization safely. */ + if (pos < 8 && (smsk >> (8 - pos)) != 0) + abort (); +#endif + real_opcode(&have_realopcode); + if (pos) + sprintf (source, "((real_opcode >> %d) & %d)", pos, smsk); + else + sprintf (source, "(real_opcode & %d)", smsk); + if (table68k[opcode].stype == 3) + printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); + else if (table68k[opcode].stype == 1) + printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); + else + printf ("\tuae_u32 srcreg = %s;\n", source); + } + } + if (table68k[opcode].duse + /* Yes, the dmode can be imm, in case of LINK or DBcc */ + && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 + && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 + && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) + { + if (table68k[opcode].dpos == -1) { + if (((int) table68k[opcode].dreg) >= 128) + printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); + else + printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg); + } else { + int pos = table68k[opcode].dpos; +#if 0 + /* Check that we can do the little endian optimization safely. */ + if (pos < 8 && (dmsk >> (8 - pos)) != 0) + abort (); +#endif + real_opcode(&have_realopcode); + if (pos) + printf ("\tuae_u32 dstreg = (real_opcode >> %d) & %d;\n", + pos, dmsk); + else + printf ("\tuae_u32 dstreg = real_opcode & %d;\n", dmsk); + } + } + need_endlabel = 0; + endlabelno++; + sprintf (endlabelstr, "endlabel%d", endlabelno); + gen_opcode (opcode); + if (need_endlabel) + printf ("%s: ;\n", endlabelstr); + if (table68k[opcode].flagdead == 0) + printf ("\n#endif\n"); + printf ("\tcpuop_end();\n"); + printf ("}\n"); + opcode_next_clev[rp] = next_cpu_level; + opcode_last_postfix[rp] = postfix; +} + +static void generate_func (void) +{ + int i, j, rp; + + using_prefetch = 0; + using_exception_3 = 0; + + for (i = 0; i < 1; i++) { + cpu_level = 4 - i; + postfix = i; + fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix); + + /* sam: this is for people with low memory (eg. me :)) */ + printf ("\n" + "#if !defined(PART_1) && !defined(PART_2) && " + "!defined(PART_3) && !defined(PART_4) && " + "!defined(PART_5) && !defined(PART_6) && " + "!defined(PART_7) && !defined(PART_8)" + "\n" + "#define PART_1 1\n" + "#define PART_2 1\n" + "#define PART_3 1\n" + "#define PART_4 1\n" + "#define PART_5 1\n" + "#define PART_6 1\n" + "#define PART_7 1\n" + "#define PART_8 1\n" + "#endif\n\n"); + rp = 0; + n_cpustbl = 0; + for(j=1;j<=8;++j) { + int k = (j*nr_cpuop_funcs)/8; + printf ("#ifdef PART_%d\n",j); + for (; rp < k; rp++) + generate_one_opcode (rp); + printf ("#endif\n\n"); + } + fprintf (stblfile, "{ 0, 0, 0 }};\n"); + } +} + +static struct { + const char *handler; + const char *name; +} cpufunctbl[65536]; +static char const op_illg_1[] = "op_illg_1"; +static char const illegal[] = "ILLEGAL"; + +static void generate_functbl (void) +{ + int i; + unsigned int opcode; + int cpu_level = 4; + struct gencputbl *tbl = cpustbl; + + for (opcode = 0; opcode < 65536; opcode++) + { + cpufunctbl[opcode].handler = op_illg_1; + cpufunctbl[opcode].name = illegal; + } + for (i = 0; i < n_cpustbl; i++) + { + if (! tbl[i].specific) + { + cpufunctbl[tbl[i].opcode].handler = tbl[i].handler; + cpufunctbl[tbl[i].opcode].name = lookuptab[tbl[i].namei].name; + } + } + for (opcode = 0; opcode < 65536; opcode++) + { + const char *f; + + if (table68k[opcode].mnemo == i_ILLG || (unsigned)table68k[opcode].clev > (unsigned)cpu_level) + continue; + + if (table68k[opcode].handler != -1) + { + f = cpufunctbl[table68k[opcode].handler].handler; + if (f == op_illg_1) + abort(); + cpufunctbl[opcode].handler = f; + cpufunctbl[opcode].name = cpufunctbl[table68k[opcode].handler].name; + } + } + for (i = 0; i < n_cpustbl; i++) + { + if (tbl[i].specific) + { + cpufunctbl[tbl[i].opcode].handler = tbl[i].handler; + cpufunctbl[tbl[i].opcode].name = lookuptab[tbl[i].namei].name; + } + } + + fprintf(functblfile, "\n"); + fprintf(functblfile, "cpuop_func *cpufunctbl[65536] = {\n"); + fprintf(functblfile, "#if !defined(HAVE_GET_WORD_UNSWAPPED) || defined(FULLMMU)\n"); + for (opcode = 0; opcode < 65536; opcode++) + { + fprintf(functblfile, "\t%s%s /* %s */\n", cpufunctbl[opcode].handler, opcode < 65535 ? "," : "", cpufunctbl[opcode].name); + } + fprintf(functblfile, "#else\n"); + for (opcode = 0; opcode < 65536; opcode++) + { + unsigned int map = do_byteswap_16(opcode); + fprintf(functblfile, "\t%s%s /* %s */\n", cpufunctbl[map].handler, opcode < 65535 ? "," : "", cpufunctbl[map].name); + } + fprintf(functblfile, "#endif\n"); + fprintf(functblfile, "};\n"); +} + +#if (defined(OS_cygwin) || defined(OS_mingw)) && defined(EXTENDED_SIGSEGV) +void cygwin_mingw_abort() +{ +#undef abort + abort(); +} +#endif + +int main(void) +{ + init_table68k (); + + opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); + counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); + read_counts (); + + /* It would be a lot nicer to put all in one file (we'd also get rid of + * cputbl.h that way), but cpuopti can't cope. That could be fixed, but + * I don't dare to touch the 68k version. */ + + if ((headerfile = fopen ("cputbl.h", "wb")) == NULL) + abort(); + if ((stblfile = fopen ("cpustbl.cpp", "wb")) == NULL) + abort(); + if ((functblfile = fopen ("cpufunctbl.cpp", "wb")) == NULL) + abort(); + if (freopen ("cpuemu.cpp", "wb", stdout) == NULL) + abort(); + + generate_includes (stdout); + fprintf(stdout, "#ifdef HAVE_CFLAG_NO_REDZONE\n"); + fprintf(stdout, "#ifndef NOFLAGS\n"); + fprintf(stdout, "#pragma GCC option \"-mno-red-zone\"\n"); + fprintf(stdout, "#endif\n"); + fprintf(stdout, "#endif\n"); + generate_includes (stblfile); + generate_includes (functblfile); + generate_func (); + generate_functbl (); + free (table68k); + fclose(headerfile); + fclose(stblfile); + fclose(functblfile); + return 0; +} diff --git a/BasiliskII/src/uae_cpu_2021/m68k.h b/BasiliskII/src/uae_cpu_2021/m68k.h new file mode 100644 index 000000000..c307bdfd7 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/m68k.h @@ -0,0 +1,1479 @@ +/* + * m68k.h - machine dependent bits + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + /* + * UAE - The Un*x Amiga Emulator + * + * MC68000 emulation - machine dependent bits + * + * Copyright 1996 Bernd Schmidt + * + */ + +#ifndef M68K_FLAGS_H +#define M68K_FLAGS_H + +#ifdef OPTIMIZED_FLAGS + +#if (defined(CPU_i386) && defined(X86_ASSEMBLY)) || (defined(CPU_x86_64) && defined(X86_64_ASSEMBLY)) + +#ifdef __cplusplus +# include +#else +# include +#endif + +#ifndef SAHF_SETO_PROFITABLE + +/* + * Machine dependent structure for holding the 68k CCR flags + */ +/* PUSH/POP instructions are naturally 64-bit sized on x86-64, thus + unsigned long hereunder is either 64-bit or 32-bit wide depending + on the target. */ +struct flag_struct { +#if defined(CPU_x86_64) + uint64 cznv; + uint64 x; +#else + uint32 cznv; + uint32 x; +#endif +}; + +/* + * The bits in the cznv field in the above structure are assigned to + * allow the easy mirroring of the x86 rFLAGS register. + * + * The 68k CZNV flags are thus assigned in cznv as: + * + * 76543210 FEDCBA98 --------- --------- + * SZxxxxxC xxxxVxxx xxxxxxxxx xxxxxxxxx + */ + +#define FLAGBIT_N 7 +#define FLAGBIT_Z 6 +#define FLAGBIT_C 0 +#define FLAGBIT_V 11 +#define FLAGBIT_X 0 /* must be in position 0 for duplicate_carry() to work */ + +#define FLAGVAL_N (1 << FLAGBIT_N) +#define FLAGVAL_Z (1 << FLAGBIT_Z) +#define FLAGVAL_C (1 << FLAGBIT_C) +#define FLAGVAL_V (1 << FLAGBIT_V) +#define FLAGVAL_X (1 << FLAGBIT_X) + +#define SET_ZFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z)) +#define SET_CFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C)) +#define SET_VFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V)) +#define SET_NFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N)) +#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X) + +#define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1) +#define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1) +#define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1) +#define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1) +#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1) + +#define CLEAR_CZNV() (regflags.cznv = 0) +#define GET_CZNV() (regflags.cznv) +#define IOR_CZNV(X) (regflags.cznv |= (X)) +#define SET_CZNV(X) (regflags.cznv = (X)) + +#define COPY_CARRY() (regflags.x = regflags.cznv >> (FLAGBIT_C - FLAGBIT_X)) + +extern struct flag_struct regflags __asm__ ("regflags"); + +/* + * Test CCR condition + */ +static inline int cctrue(int cc) +{ + uae_u32 cznv = regflags.cznv; + + switch (cc) { + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */ + case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */ + case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */ + case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */ + case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */ + case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */ + case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */ + case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */ + case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */ + case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */ +#if FLAGBIT_N > FLAGBIT_V + case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0; +#else + case 12: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) != 0; +#endif + } + abort (); + return 0; +} + +#define optflag_testl(v) \ + __asm__ __volatile__ ("andl %1,%1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv) : "r" (v) : "memory", "cc") + +#define optflag_testw(v) \ + __asm__ __volatile__ ("andw %w1,%w1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv) : "r" (v) : "memory", "cc") + +#define optflag_testb(v) \ + __asm__ __volatile__ ("andb %b1,%b1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv) : "q" (v) : "memory", "cc") + +#define optflag_addl(v, s, d) do { \ + __asm__ __volatile__ ("addl %k2,%k1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "memory", "cc"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_addw(v, s, d) do { \ + __asm__ __volatile__ ("addw %w2,%w1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "memory", "cc"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_addb(v, s, d) do { \ + __asm__ __volatile__ ("addb %b2,%b1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_subl(v, s, d) do { \ + __asm__ __volatile__ ("subl %k2,%k1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "memory", "cc"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_subw(v, s, d) do { \ + __asm__ __volatile__ ("subw %w2,%w1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "memory", "cc"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_subb(v, s, d) do { \ + __asm__ __volatile__ ("subb %b2,%b1\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "memory", "cc"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_cmpl(s, d) \ + __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv) : "rmi" (s), "r" (d) : "memory", "cc") + +#define optflag_cmpw(s, d) \ + __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv) : "rmi" (s), "r" (d) : "memory", "cc") + +#define optflag_cmpb(s, d) \ + __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \ + "pushf\n\t" \ + "pop %0\n\t" \ + : "=rm" (regflags.cznv) : "qmi" (s), "q" (d) : "memory", "cc") + +#else /* !SAHF_SETO_PROFITABLE */ + +/* + * Machine dependent structure for holding the 68k CCR flags + */ +struct flag_struct { + uae_u32 cznv; + uae_u32 x; +}; + +extern struct flag_struct regflags __asm__ ("regflags"); + +/* + * The bits in the cznv field in the above structure are assigned to + * allow the easy mirroring of the x86 condition flags. (For example, + * from the AX register - the x86 overflow flag can be copied to AL + * with a setto %AL instr and the other flags copied to AH with an + * lahf instr). + * + * The 68k CZNV flags are thus assigned in cznv as: + * + * <--AL--> <--AH--> + * 76543210 FEDCBA98 --------- --------- + * xxxxxxxV NZxxxxxC xxxxxxxxx xxxxxxxxx + */ + +#define FLAGBIT_N 15 +#define FLAGBIT_Z 14 +#define FLAGBIT_C 8 +#define FLAGBIT_V 0 +#define FLAGBIT_X 0 /* must be in position 0 for duplicate_carry() to work */ + +#define FLAGVAL_N (1 << FLAGBIT_N) +#define FLAGVAL_Z (1 << FLAGBIT_Z) +#define FLAGVAL_C (1 << FLAGBIT_C) +#define FLAGVAL_V (1 << FLAGBIT_V) +#define FLAGVAL_X (1 << FLAGBIT_X) + +#define SET_ZFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z)) +#define SET_CFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C)) +#define SET_VFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V)) +#define SET_NFLG(y) (regflags.cznv = (((uae_u32)regflags.cznv) & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N)) +#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X) + +#define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1) +#define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1) +#define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1) +#define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1) +#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1) + +#define CLEAR_CZNV() (regflags.cznv = 0) +#define GET_CZNV() (regflags.cznv) +#define IOR_CZNV(X) (regflags.cznv |= (X)) +#define SET_CZNV(X) (regflags.cznv = (X)) + +#define COPY_CARRY() (regflags.x = regflags.cznv >> (FLAGBIT_C - FLAGBIT_X)) + + +/* + * Test CCR condition + */ +static inline int cctrue(int cc) +{ + uae_u32 cznv = regflags.cznv; + + switch (cc) { + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */ + case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */ + case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */ + case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */ + case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */ + case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */ + case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */ + case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */ + case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */ + case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */ +#if FLAGBIT_N > FLAGBIT_V + case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0; +#else + case 12: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & FLAGVAL_V) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* !ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG || (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_V - FLAGBIT_N)) ^ cznv) & (FLAGVAL_V | FLAGVAL_Z)) != 0; +#endif + } + abort (); + return 0; +} + +/* Manually emit LAHF instruction so that 64-bit assemblers can grok it */ +#if defined CPU_x86_64 && defined __GNUC__ +#define ASM_LAHF ".byte 0x9f" +#else +#define ASM_LAHF "lahf" +#endif + +/* Is there any way to do this without declaring *all* memory clobbered? + I.e. any way to tell gcc that some byte-sized value is in %al? */ +#define optflag_testl(v) \ + __asm__ __volatile__ ("andl %0,%0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : : "r" (v) : "%eax","cc","memory") + +#define optflag_testw(v) \ + __asm__ __volatile__ ("andw %w0,%w0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : : "r" (v) : "%eax","cc","memory") + +#define optflag_testb(v) \ + __asm__ __volatile__ ("andb %b0,%b0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : : "q" (v) : "%eax","cc","memory") + +#define optflag_addl(v, s, d) do { \ + __asm__ __volatile__ ("addl %k1,%k0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_addw(v, s, d) do { \ + __asm__ __volatile__ ("addw %w1,%w0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_addb(v, s, d) do { \ + __asm__ __volatile__ ("addb %b1,%b0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_subl(v, s, d) do { \ + __asm__ __volatile__ ("subl %k1,%k0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_subw(v, s, d) do { \ + __asm__ __volatile__ ("subw %w1,%w0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_subb(v, s, d) do { \ + __asm__ __volatile__ ("subb %b1,%b0\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \ + COPY_CARRY(); \ + } while (0) + +#define optflag_cmpl(s, d) \ + __asm__ __volatile__ ("cmpl %k0,%k1\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : : "rmi" (s), "r" (d) : "%eax","cc","memory") + +#define optflag_cmpw(s, d) \ + __asm__ __volatile__ ("cmpw %w0,%w1\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : : "rmi" (s), "r" (d) : "%eax","cc","memory") + +#define optflag_cmpb(s, d) \ + __asm__ __volatile__ ("cmpb %b0,%b1\n\t" \ + ASM_LAHF "\n\t" \ + "seto %%al\n\t" \ + "movb %%al,regflags\n\t" \ + "movb %%ah,regflags+1\n\t" \ + : : "qmi" (s), "q" (d) : "%eax","cc","memory") + +#endif /* SAHF_SETO_PROFITABLE */ + +#elif defined(CPU_arm) && defined(ARM_ASSEMBLY) + +/* + * Machine dependent structure for holding the 68k CCR flags + */ +struct flag_struct { + uae_u32 nzcv; + uae_u32 x; +}; + +#define FLAGBIT_N 31 +#define FLAGBIT_Z 30 +#define FLAGBIT_C 29 +#define FLAGBIT_V 28 +#define FLAGBIT_X FLAGBIT_C /* must be in the same position in as x flag */ + +#define FLAGVAL_N (1 << FLAGBIT_N) +#define FLAGVAL_Z (1 << FLAGBIT_Z) +#define FLAGVAL_C (1 << FLAGBIT_C) +#define FLAGVAL_V (1 << FLAGBIT_V) +#define FLAGVAL_X (1 << FLAGBIT_X) + +#define SET_NFLG(y) (regflags.nzcv = (regflags.nzcv & ~FLAGVAL_N) | (((y) & 1) << FLAGBIT_N)) +#define SET_ZFLG(y) (regflags.nzcv = (regflags.nzcv & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z)) +#define SET_CFLG(y) (regflags.nzcv = (regflags.nzcv & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C)) +#define SET_VFLG(y) (regflags.nzcv = (regflags.nzcv & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V)) +#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X) + +#define GET_NFLG() ((regflags.nzcv >> FLAGBIT_N) & 1) +#define GET_ZFLG() ((regflags.nzcv >> FLAGBIT_Z) & 1) +#define GET_CFLG() ((regflags.nzcv >> FLAGBIT_C) & 1) +#define GET_VFLG() ((regflags.nzcv >> FLAGBIT_V) & 1) +#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1) + +#define CLEAR_CZNV() (regflags.nzcv = 0) +#define GET_CZNV() (regflags.nzcv) +#define IOR_CZNV(X) (regflags.nzcv |= (X)) +#define SET_CZNV(X) (regflags.nzcv = (X)) + +#define COPY_CARRY() (regflags.x = regflags.nzcv >> (FLAGBIT_C - FLAGBIT_X)) + +extern struct flag_struct regflags __asm__ ("regflags"); + +/* + * Test CCR condition + */ +static inline int cctrue(int cc) +{ + unsigned int nzcv = regflags.nzcv; + switch(cc){ + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (nzcv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !GET_CFLG && !GET_ZFLG; HI */ + case 3: return (nzcv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* GET_CFLG || GET_ZFLG; LS */ + case 4: return (nzcv & FLAGVAL_C) == 0; /* !GET_CFLG; CC */ + case 5: return (nzcv & FLAGVAL_C) != 0; /* GET_CFLG; CS */ + case 6: return (nzcv & FLAGVAL_Z) == 0; /* !GET_ZFLG; NE */ + case 7: return (nzcv & FLAGVAL_Z) != 0; /* GET_ZFLG; EQ */ + case 8: return (nzcv & FLAGVAL_V) == 0; /* !GET_VFLG; VC */ + case 9: return (nzcv & FLAGVAL_V) != 0; /* GET_VFLG; VS */ + case 10:return (nzcv & FLAGVAL_N) == 0; /* !GET_NFLG; PL */ + case 11:return (nzcv & FLAGVAL_N) != 0; /* GET_NFLG; MI */ + case 12:return (((nzcv << (FLAGBIT_N - FLAGBIT_V)) ^ nzcv) & FLAGVAL_N) == 0; /* GET_NFLG == GET_VFLG; GE */ + case 13:return (((nzcv << (FLAGBIT_N - FLAGBIT_V)) ^ nzcv) & FLAGVAL_N) != 0; /* GET_NFLG != GET_VFLG; LT */ + case 14: nzcv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); + return (((nzcv << (FLAGBIT_N - FLAGBIT_V)) ^ nzcv) & (FLAGVAL_N | FLAGVAL_Z)) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */ + case 15: nzcv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); + return (((nzcv << (FLAGBIT_N - FLAGBIT_V)) ^ nzcv) & (FLAGVAL_N | FLAGVAL_Z)) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */ + } + return 0; +} + +#define optflag_testl(v) do {\ + __asm__ __volatile__ ("tst %[rv],%[rv]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "bic %[nzcv],#0x30000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rv] "r" (v) \ + : "cc"); \ + } while(0) + +#define optflag_addl(v, s, d) do { \ + __asm__ __volatile__ ("adds %[rv],%[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_subl(v, s, d) do { \ + __asm__ __volatile__ ("subs %[rv],%[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_cmpl(s, d) do { \ + __asm__ __volatile__ ("cmp %[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rs] "ri" (s), [rd] "0" (d) \ + : "cc"); \ + } while(0) + +#if defined(ARMV6_ASSEMBLY) + +// #pragma message "ARM/v6 Assembly optimized flags" + +#define optflag_testw(v) do { \ + __asm__ __volatile__ ("sxth %[rv],%[rv]\n\t" \ + "tst %[rv],%[rv]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "bic %[nzcv],#0x30000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rv] "0" (v) \ + : "cc"); \ + }while(0) + +#define optflag_testb(v) do {\ + __asm__ __volatile__ ("sxtb %[rv],%[rv]\n\t" \ + "tst %[rv],%[rv]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "bic %[nzcv],#0x30000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rv] "0" (v) \ + : "cc"); \ + }while(0) + +#define optflag_addw(v, s, d) do { \ + __asm__ __volatile__ ("sxth %[rd],%[rd]\n\t" \ + "sxth %[rs],%[rs]\n\t" \ + "adds %[rd],%[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_addb(v, s, d) do { \ + __asm__ __volatile__ ("sxtb %[rd],%[rd]\n\t" \ + "sxtb %[rs],%[rs]\n\t" \ + "adds %[rd],%[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_subw(v, s, d) do { \ + __asm__ __volatile__ ("sxth %[rd],%[rd]\n\t" \ + "sxth %[rs],%[rs]\n\t" \ + "subs %[rd],%[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_subb(v, s, d) do { \ + __asm__ __volatile__ ("sxtb %[rd],%[rd]\n\t" \ + "sxtb %[rs],%[rs]\n\t" \ + "subs %[rd],%[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_cmpw(s, d) do { \ + __asm__ __volatile__ ("sxth %[rd],%[rd]\n\t" \ + "sxth %[rs],%[rs]\n\t" \ + "cmp %[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rs] "ri" (s), [rd] "0" (d) \ + : "cc"); \ + } while(0) + +#define optflag_cmpb(s, d) do { \ + __asm__ __volatile__ ("sxtb %[rd],%[rd]\n\t" \ + "sxtb %[rs],%[rs]\n\t" \ + "cmp %[rd],%[rs]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rs] "ri" (s), [rd] "0" (d) \ + : "cc"); \ + } while(0) + +#else + +// #pragma message "ARM/generic Assembly optimized flags" + +#define optflag_testw(v) do { \ + __asm__ __volatile__ ("lsl %[rv],%[rv],#16\n\t" \ + "tst %[rv],%[rv]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "bic %[nzcv],#0x30000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rv] "0" (v) \ + : "cc"); \ + }while(0) + +#define optflag_testb(v) do {\ + __asm__ __volatile__ ("lsl %[rv],%[rv],#24\n\t" \ + "tst %[rv],%[rv]\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "bic %[nzcv],#0x30000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rv] "0" (v) \ + : "cc"); \ + }while(0) + +#define optflag_addw(v, s, d) do { \ + __asm__ __volatile__ ("lsl %[rd],%[rd],#16\n\t" \ + "adds %[rd],%[rd],%[rs],lsl #16\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "lsr %[rv],%[rd],#16\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_addb(v, s, d) do { \ + __asm__ __volatile__ ("lsl %[rd],%[rd],#24\n\t" \ + "adds %[rd],%[rd],%[rs],lsl #24\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "lsr %[rv],%[rd],#24\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_subw(v, s, d) do { \ + __asm__ __volatile__ ("lsl %[rd],%[rd],#16\n\t" \ + "subs %[rd],%[rd],%[rs],lsl #16\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + "lsr %[rv],%[rd],#16\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_subb(v, s, d) do { \ + __asm__ __volatile__ ("lsl %[rd],%[rd],#24\n\t" \ + "subs %[rd],%[rd],%[rs],lsl #24\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + "lsr %[rv],%[rd],#24\n\t" \ + : [nzcv] "=r" (regflags.nzcv), [rv] "=r" (v) \ + : [rs] "ri" (s), [rd] "1" (d) \ + : "cc"); \ + COPY_CARRY(); \ + } while(0) + +#define optflag_cmpw(s, d) do { \ + __asm__ __volatile__ ("lsl %[rd],%[rd],#16\n\t" \ + "cmp %[rd],%[rs],lsl #16\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rs] "ri" (s), [rd] "0" (d) \ + : "cc"); \ + } while(0) + +#define optflag_cmpb(s, d) do { \ + __asm__ __volatile__ ("lsl %[rd],%[rd],#24\n\t" \ + "cmp %[rd],%[rs],lsl #24\n\t" \ + "mrs %[nzcv],cpsr\n\t" \ + "eor %[nzcv],#0x20000000\n\t" \ + : [nzcv] "=r" (regflags.nzcv) \ + : [rs] "ri" (s), [rd] "0" (d) \ + : "cc"); \ + } while(0) + +#endif + +#elif defined(CPU_sparc) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY)) + +/* + * Machine dependent structure for holding the 68k CCR flags + */ +struct flag_struct { + unsigned char nzvc; + unsigned char x; +}; + +extern struct flag_struct regflags; + +#define FLAGBIT_N 3 +#define FLAGBIT_Z 2 +#define FLAGBIT_V 1 +#define FLAGBIT_C 0 +#define FLAGBIT_X FLAGBIT_C /* should be in the same position as the x flag */ + +#define FLAGVAL_N (1 << FLAGBIT_N) +#define FLAGVAL_Z (1 << FLAGBIT_Z) +#define FLAGVAL_C (1 << FLAGBIT_C) +#define FLAGVAL_V (1 << FLAGBIT_V) +#define FLAGVAL_X (1 << FLAGBIT_X) + +#define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~FLAGVAL_Z) | (((y) & 1) << FLAGBIT_Z)) +#define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~FLAGVAL_C) | (((y) & 1) << FLAGBIT_C)) +#define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_V)) +#define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~FLAGVAL_V) | (((y) & 1) << FLAGBIT_N)) +#define SET_XFLG(y) (regflags.x = ((y) & 1) << FLAGBIT_X) + +#define GET_ZFLG() ((regflags.nzvc >> FLAGBIT_Z) & 1) +#define GET_CFLG() ((regflags.nzvc >> FLAGBIT_C) & 1) +#define GET_VFLG() ((regflags.nzvc >> FLAGBIT_V) & 1) +#define GET_NFLG() ((regflags.nzvc >> FLAGBIT_N) & 1) +#define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1) + +#define CLEAR_CZNV() (regflags.nzvc = 0) +#define GET_CZNV() (regflags.nzvc) +#define IOR_CZNV(X) (regflags.nzvc |= (X)) +#define SET_CZNV(X) (regflags.nzvc = (X)) + +#define COPY_CARRY() (regflags.x = regflags.nzvc >> (FLAGBIT_C - FLAGBIT_X)) + +/* + * Test CCR condition + */ +static inline int cctrue(int cc) +{ + uae_u32 nzvc = regflags.nzvc; + switch (cc) { + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */ + case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */ + case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */ + case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */ + case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */ + case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */ + case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */ + case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */ + case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */ + case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */ + case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0; /* NFLG == VFLG GE */ + case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0; /* NFLG != VFLG LT */ + case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG && (NFLG == VFLG) GT */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0; + case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG && (NFLG != VFLG) LE */ + return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0; + } + return 0; +} + +#ifdef SPARC_V8_ASSEMBLY + +static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " addcc %2, %3, %0\n" + " addx %%g0, %%g0, %%o0 ! X,C flags\n" + " stb %%o0, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " subcc %2, %3, %0\n" + " addx %%g0, %%g0, %%o0 ! X,C flags\n" + " stb %%o0, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " sll %2, 24, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " addx %%g0, %%g0, %%o0 ! C flag\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " sll %2, 16, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " addx %%g0, %%g0, %%o0 ! C flag\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " subcc %1, %2, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o1 ! Get the X Flag\n" + " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +#if 0 +VERY SLOW... +static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " ldub [%1 + 1], %%o2\n" + " subcc %%g0, %%o2, %%g0\n" + " addx %%g0, %%g0, %%o2\n" + " sll %%o2, 24, %%o2\n" + " addcc %%o0, %%o2, %%o0\n" + " srl %%o0, 24, %0\n" + " addx %%g0, %%g0, %%o2\n" + " or %%o1, %%o2, %%o1 ! update X,C flags\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! update V flag\n" + " and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n" + " and %%o1, 1, %%o2 ! keep C flag in %%o2\n" + " bnz,a .+8\n" + " or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n" + " stb %%o2, [%1 + 1] ! store the X flag\n" + " or %%o1, %%o0, %%o1\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1", "o2" + ); + return value; +} +#endif + +static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o0 ! Get the X Flag\n" + " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + " ldub [%1], %%o0 ! retreive the old NZVC flags\n" + " and %%o0, 0x04, %%o0 ! but keep only Z flag\n" + " addx %%o0, %%g0, %%o0 ! X,C flags\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " bnz,a .+8\n" + " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1 + 1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +#endif /* SPARC_V8_ASSEMBLY */ + +#ifdef SPARC_V9_ASSEMBLY + +static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " addcc %2, %3, %0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " subcc %2, %3, %0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " sll %2, 24, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " sll %2, 16, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " subcc %1, %2, %%g0\n" +#if 0 + " subcc %1, %2, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" +#endif +#if 0 + " subcc %1, %2, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,pt,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" +#endif + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +#if 1 +static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " subcc %%o0, %%g0, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0" + ); +} + +static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " subcc %%o0, %%g0, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0" + ); +} + +static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " subcc %1, %%g0, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0" + ); +} +#else +static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " subcc %%o0, %%g0, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " subcc %%o0, %%g0, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " subcc %1, %%g0, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0", "o1" + ); +} +#endif + +static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o1 ! Get the X Flag\n" + " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o0 ! Get the X Flag\n" + " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + " ldub [%1], %%o0 ! retreive the old NZVC flags\n" + " and %%o0, 0x04, %%o0 ! but keep only Z flag\n" + " addx %%o0, %%g0, %%o0 ! X,C flags\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " bnz,a .+8\n" + " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1 + 1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +#endif /* SPARC_V9_ASSEMBLY */ + +#endif + +#else + +/* + * Machine independent structure for holding the 68k CCR flags + */ +struct flag_struct { + unsigned int c; + unsigned int z; + unsigned int n; + unsigned int v; + unsigned int x; +}; + +extern struct flag_struct regflags; + +#define ZFLG (regflags.z) +#define NFLG (regflags.n) +#define CFLG (regflags.c) +#define VFLG (regflags.v) +#define XFLG (regflags.x) + +#define SET_CFLG(x) (CFLG = (x)) +#define SET_NFLG(x) (NFLG = (x)) +#define SET_VFLG(x) (VFLG = (x)) +#define SET_ZFLG(x) (ZFLG = (x)) +#define SET_XFLG(x) (XFLG = (x)) + +#define GET_CFLG() CFLG +#define GET_NFLG() NFLG +#define GET_VFLG() VFLG +#define GET_ZFLG() ZFLG +#define GET_XFLG() XFLG + +#define CLEAR_CZNV() do { \ + SET_CFLG (0); \ + SET_ZFLG (0); \ + SET_NFLG (0); \ + SET_VFLG (0); \ +} while (0) + +#define COPY_CARRY() (SET_XFLG (GET_CFLG ())) + +/* + * Test CCR condition + */ +static inline int cctrue(const int cc) +{ + switch(cc){ + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return !CFLG && !ZFLG; /* HI */ + case 3: return CFLG || ZFLG; /* LS */ + case 4: return !CFLG; /* CC */ + case 5: return CFLG; /* CS */ + case 6: return !ZFLG; /* NE */ + case 7: return ZFLG; /* EQ */ + case 8: return !VFLG; /* VC */ + case 9: return VFLG; /* VS */ + case 10:return !NFLG; /* PL */ + case 11:return NFLG; /* MI */ + case 12:return NFLG == VFLG; /* GE */ + case 13:return NFLG != VFLG; /* LT */ + case 14:return !ZFLG && (NFLG == VFLG); /* GT */ + case 15:return ZFLG || (NFLG != VFLG); /* LE */ + } + return 0; +} + +#endif /* OPTIMIZED_FLAGS */ + +#endif /* M68K_FLAGS_H */ diff --git a/BasiliskII/src/uae_cpu_2021/memory.h b/BasiliskII/src/uae_cpu_2021/memory.h new file mode 100644 index 000000000..f7bab41de --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/memory.h @@ -0,0 +1,125 @@ +/* + * UAE - The Un*x Amiga Emulator + * + * memory management + * + * Copyright 1995 Bernd Schmidt + * + * 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 UAE_MEMORY_H +#define UAE_MEMORY_H + +#if DIRECT_ADDRESSING +extern uintptr MEMBaseDiff; +#endif + +extern void Exception (int, uaecptr); +#ifdef EXCEPTIONS_VIA_LONGJMP + extern JMP_BUF excep_env; + #define SAVE_EXCEPTION \ + JMP_BUF excep_env_old; \ + memcpy(excep_env_old, excep_env, sizeof(JMP_BUF)) + #define RESTORE_EXCEPTION \ + memcpy(excep_env, excep_env_old, sizeof(JMP_BUF)) + #define TRY(var) int var = SETJMP(excep_env); if (!var) + #define CATCH(var) else + #define THROW(n) LONGJMP(excep_env, n) + #define THROW_AGAIN(var) LONGJMP(excep_env, var) + #define VOLATILE volatile +#else + struct m68k_exception { + int prb; + m68k_exception (int exc) : prb (exc) {} + operator int() { return prb; } + }; + #define SAVE_EXCEPTION + #define RESTORE_EXCEPTION + #define TRY(var) try + #define CATCH(var) catch(m68k_exception var) + #define THROW(n) throw m68k_exception(n) + #define THROW_AGAIN(var) throw + #define VOLATILE +#endif /* EXCEPTIONS_VIA_LONGJMP */ + +#if DIRECT_ADDRESSING +static __inline__ uae_u8 *do_get_real_address(uaecptr addr) +{ + return (uae_u8 *)MEMBaseDiff + addr; +} +static __inline__ uae_u32 do_get_virtual_address(uae_u8 *addr) +{ + return (uintptr)addr - MEMBaseDiff; +} +static __inline__ uae_u32 get_long(uaecptr addr) +{ + uae_u32 * const m = (uae_u32 *)do_get_real_address(addr); + return do_get_mem_long(m); +} +#define phys_get_long get_long +static __inline__ uae_u32 get_word(uaecptr addr) +{ + uae_u16 * const m = (uae_u16 *)do_get_real_address(addr); + return do_get_mem_word(m); +} +#define phys_get_word get_word +static __inline__ uae_u32 get_byte(uaecptr addr) +{ + uae_u8 * const m = (uae_u8 *)do_get_real_address(addr); + return do_get_mem_byte(m); +} +#define phys_get_byte get_byte +static __inline__ void put_long(uaecptr addr, uae_u32 l) +{ + uae_u32 * const m = (uae_u32 *)do_get_real_address(addr); + do_put_mem_long(m, l); +} +#define phys_put_long put_long +static __inline__ void put_word(uaecptr addr, uae_u32 w) +{ + uae_u16 * const m = (uae_u16 *)do_get_real_address(addr); + do_put_mem_word(m, w); +} +#define phys_put_word put_word +static __inline__ void put_byte(uaecptr addr, uae_u32 b) +{ + uae_u8 * const m = (uae_u8 *)do_get_real_address(addr); + do_put_mem_byte(m, b); +} +#define phys_put_byte put_byte +static __inline__ uae_u8 *get_real_address(uaecptr addr) +{ + return do_get_real_address(addr); +} +static inline uae_u8 *get_real_address(uaecptr addr, int write, int sz) +{ + return do_get_real_address(addr); +} +static inline uae_u8 *phys_get_real_address(uaecptr addr) +{ + return do_get_real_address(addr); +} +static __inline__ uae_u32 get_virtual_address(uae_u8 *addr) +{ + return do_get_virtual_address(addr); +} +#endif /* DIRECT_ADDRESSING */ + +static __inline__ void check_ram_boundary(uaecptr addr, int size, bool write) {} +static inline void flush_internals() {} + +#endif /* MEMORY_H */ + diff --git a/BasiliskII/src/uae_cpu_2021/newcpu.cpp b/BasiliskII/src/uae_cpu_2021/newcpu.cpp new file mode 100644 index 000000000..0832df820 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/newcpu.cpp @@ -0,0 +1,1692 @@ +/* + * newcpu.cpp - CPU emulation + * + * Copyright (c) 2010 ARAnyM dev team (see AUTHORS) + * + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + /* + * UAE - The Un*x Amiga Emulator + * + * MC68000 emulation + * + * (c) 1995 Bernd Schmidt + */ + +#include "sysdeps.h" +#include + +#include "cpu_emulation.h" +#include "main.h" +#include "emul_op.h" +#include "m68k.h" +#include "memory.h" +#include "readcpu.h" +#include "newcpu.h" +#ifdef USE_JIT +# include "compiler/compemu.h" +#endif +#include "fpu/fpu.h" +#include "cpummu.h" +#if 0 +#include "natfeats.h" +#include "disasm-glue.h" +#endif +#if USE_JIT +extern bool UseJIT; +#endif + +#include + +#define DEBUG 0 +#include "debug.h" + +#define SANITY_CHECK_ATC 1 + +struct fixup fixup = {0, 0, 0}; + +int quit_program = 0; +int exit_val = 0; + +// For instruction $7139 +bool cpu_debugging = false; + +struct flag_struct regflags; + +/* LongJump buffers */ +#ifdef EXCEPTIONS_VIA_LONGJMP +JMP_BUF excep_env; +#endif +/* Opcode of faulting instruction */ +uae_u16 last_op_for_exception_3; +/* PC at fault time */ +uaecptr last_addr_for_exception_3; +/* Address that generated the exception */ +uaecptr last_fault_for_exception_3; + +int areg_byteinc[] = { 1,1,1,1,1,1,1,2 }; +int imm8_table[] = { 8,1,2,3,4,5,6,7 }; + +int movem_index1[256]; +int movem_index2[256]; +int movem_next[256]; + +#ifdef FLIGHT_RECORDER + +// feel free to edit the following defines to customize the dump +#define FRLOG_HOTKEY 1 /* 1 = dump only when hotkey is held down */ +#define FRLOG_ALL 1 /* 1 = dump continuously to ever growing log */ +#define FRLOG_IRQ 0 /* 1 = dump also CPU in interrupts */ +#define FRLOG_REGS 0 /* 1 = dump also all data/address registers */ +#define FRLOG_SIZE 8192 /* this many instructions in single dump */ + +struct rec_step { + uae_u32 d[8]; + uae_u32 a[8]; + uae_u32 pc; + uae_u16 sr; + uae_u32 usp; + uae_u32 msp; + uae_u32 isp; + uae_u16 instr; +}; + +bool cpu_flight_recorder_active = false; + +#if FRLOG_ALL +const int LOG_SIZE = 10; +#else +const int LOG_SIZE = FRLOG_SIZE; +#endif +static rec_step frlog[LOG_SIZE]; +static int log_ptr = -1; // First time initialization + +static const char *log_filename(void) +{ + const char *name = getenv("M68K_LOG_FILE"); + return name ? name : "log.68k"; +} + +void dump_flight_recorder(void) +{ +#if FRLOG_ALL + FILE *f = fopen(log_filename(), "a"); +#else + FILE *f = fopen(log_filename(), "w"); +#endif + if (f == NULL) + return; + for (int i = 0; i < LOG_SIZE; i++) { + int j = (i + log_ptr) % LOG_SIZE; + fprintf(f, "pc %08x instr %04x sr %04x usp %08x msp %08x isp %08x\n", frlog[j].pc, frlog[j].instr, frlog[j].sr, frlog[j].usp, frlog[j].msp, frlog[j].isp); + // adding a simple opcode -> assembler conversion table would help +#if FRLOG_REGS + fprintf(f, "d0 %08x d1 %08x d2 %08x d3 %08x\n", frlog[j].d[0], frlog[j].d[1], frlog[j].d[2], frlog[j].d[3]); + fprintf(f, "d4 %08x d5 %08x d6 %08x d7 %08x\n", frlog[j].d[4], frlog[j].d[5], frlog[j].d[6], frlog[j].d[7]); + fprintf(f, "a0 %08x a1 %08x a2 %08x a3 %08x\n", frlog[j].a[0], frlog[j].a[1], frlog[j].a[2], frlog[j].a[3]); + fprintf(f, "a4 %08x a5 %08x a6 %08x a7 %08x\n", frlog[j].a[4], frlog[j].a[5], frlog[j].a[6], frlog[j].a[7]); +#endif + m68k_disasm(f, frlog[j].pc, NULL, 1); + } + fclose(f); +} + +void m68k_record_step(uaecptr pc, int opcode) +{ + static bool last_state = false; + +#if FRLOG_HOTKEY + if (! cpu_flight_recorder_active) { + if (last_state) { + // dump log out + dump_flight_recorder(); + + // remember last state + last_state = false; + } + return; + } +#endif + + if (! last_state) { + // reset old log + log_ptr = 0; + memset(frlog, 0, sizeof(frlog)); + // remember last state + last_state = true; + } + +#if FRLOG_REGS + for (int i = 0; i < 8; i++) { + frlog[log_ptr].d[i] = m68k_dreg(regs, i); + frlog[log_ptr].a[i] = m68k_areg(regs, i); + } +#endif + frlog[log_ptr].pc = pc; + + MakeSR(); +#if ! FRLOG_IRQ + // is CPU in interrupt handler? Quit if should not be logged. + if (regs.s && !regs.m) return; +#endif + frlog[log_ptr].sr = regs.sr; + frlog[log_ptr].usp = regs.usp; + frlog[log_ptr].msp = regs.msp; + frlog[log_ptr].isp = regs.isp; + frlog[log_ptr].instr = opcode; + + log_ptr = (log_ptr + 1) % LOG_SIZE; +#if FRLOG_ALL + if (log_ptr == 0) dump_flight_recorder(); +#endif +} +#endif /* FLIGHT_RECORDER */ + +int broken_in; + +static inline unsigned int cft_map (unsigned int f) +{ +#if !defined(HAVE_GET_WORD_UNSWAPPED) || defined(FULLMMU) + return f; +#else + return do_byteswap_16(f); +#endif +} + +void REGPARAM2 op_illg_1 (uae_u32 opcode) +{ + op_illg (cft_map (opcode)); +} + + +void init_m68k (void) +{ + int i; + + for (i = 0 ; i < 256 ; i++) { + int j; + for (j = 0 ; j < 8 ; j++) { + if (i & (1 << j)) break; + } + movem_index1[i] = j; + movem_index2[i] = 7-j; + movem_next[i] = i & (~(1 << j)); + } + fpu_init (CPUType == 4); +} + +void exit_m68k (void) +{ + fpu_exit (); +} + +struct regstruct regs; +// MJ static struct regstruct regs_backup[16]; +// MJ static int backup_pointer = 0; + + +#ifdef FULLMMU +static inline uae_u8 get_ibyte_1(uae_u32 o) +{ + return get_ibyte(o); +} +static inline uae_u16 get_iword_1(uae_u32 o) +{ + return get_iword(o); +} +static inline uae_u32 get_ilong_1(uae_u32 o) +{ + return get_ilong(o); +} +#else +# define get_ibyte_1(o) get_byte(m68k_getpc() + (o) + 1) +# define get_iword_1(o) get_word(m68k_getpc() + (o)) +# define get_ilong_1(o) get_long(m68k_getpc() + (o)) +#endif + +/* + * extract bitfield data from memory and return it in the MSBs + * bdata caches the unmodified data for put_bitfield() + */ +uae_u32 get_bitfield(uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) +{ + uae_u32 tmp, res, mask; + + offset &= 7; + mask = 0xffffffffu << (32 - width); + switch ((offset + width + 7) >> 3) { + case 1: + tmp = get_byte(src); + res = tmp << (24 + offset); + bdata[0] = tmp & ~(mask >> (24 + offset)); + break; + case 2: + tmp = get_word(src); + res = tmp << (16 + offset); + bdata[0] = tmp & ~(mask >> (16 + offset)); + break; + case 3: + tmp = get_word(src); + res = tmp << (16 + offset); + bdata[0] = tmp & ~(mask >> (16 + offset)); + tmp = get_byte(src + 2); + res |= tmp << (8 + offset); + bdata[1] = tmp & ~(mask >> (8 + offset)); + break; + case 4: + tmp = get_long(src); + res = tmp << offset; + bdata[0] = tmp & ~(mask >> offset); + break; + case 5: + tmp = get_long(src); + res = tmp << offset; + bdata[0] = tmp & ~(mask >> offset); + tmp = get_byte(src + 4); + res |= tmp >> (8 - offset); + bdata[1] = tmp & ~(mask << (8 - offset)); + break; + default: + /* Panic? */ + res = 0; + break; + } + return res; +} + +/* + * write bitfield data (in the LSBs) back to memory, upper bits + * must be cleared already. + */ +void put_bitfield(uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) +{ + offset = (offset & 7) + width; + switch ((offset + 7) >> 3) { + case 1: + put_byte(dst, bdata[0] | (val << (8 - offset))); + break; + case 2: + put_word(dst, bdata[0] | (val << (16 - offset))); + break; + case 3: + put_word(dst, bdata[0] | (val >> (offset - 16))); + put_byte(dst + 2, bdata[1] | (val << (24 - offset))); + break; + case 4: + put_long(dst, bdata[0] | (val << (32 - offset))); + break; + case 5: + put_long(dst, bdata[0] | (val >> (offset - 32))); + put_byte(dst + 4, bdata[1] | (val << (40 - offset))); + break; + } +} + +uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp) +{ + int reg = (dp >> 12) & 15; + uae_s32 regd = regs.regs[reg]; + if ((dp & 0x800) == 0) + regd = (uae_s32)(uae_s16)regd; + regd <<= (dp >> 9) & 3; + if (dp & 0x100) { + uae_s32 outer = 0; + if (dp & 0x80) base = 0; + if (dp & 0x40) regd = 0; + + if ((dp & 0x30) == 0x20) base += (uae_s32)(uae_s16)next_iword(); + if ((dp & 0x30) == 0x30) base += next_ilong(); + + if ((dp & 0x3) == 0x2) outer = (uae_s32)(uae_s16)next_iword(); + if ((dp & 0x3) == 0x3) outer = next_ilong(); + + if ((dp & 0x4) == 0) base += regd; + if (dp & 0x3) base = get_long (base); + if (dp & 0x4) base += regd; + + return base + outer; + } else { + return base + (uae_s32)((uae_s8)dp) + regd; + } +} + +uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp) +{ + int reg = (dp >> 12) & 15; + uae_s32 regd = regs.regs[reg]; +#if 1 + if ((dp & 0x800) == 0) + regd = (uae_s32)(uae_s16)regd; + return base + (uae_s8)dp + regd; +#else + /* Branch-free code... benchmark this again now that + * things are no longer inline. */ + uae_s32 regd16; + uae_u32 mask; + mask = ((dp & 0x800) >> 11) - 1; + regd16 = (uae_s32)(uae_s16)regd; + regd16 &= mask; + mask = ~mask; + base += (uae_s8)dp; + regd &= mask; + regd |= regd16; + return base + regd; +#endif +} + +void MakeSR (void) +{ +#if 0 + assert((regs.t1 & 1) == regs.t1); + assert((regs.t0 & 1) == regs.t0); + assert((regs.s & 1) == regs.s); + assert((regs.m & 1) == regs.m); + assert((XFLG & 1) == XFLG); + assert((NFLG & 1) == NFLG); + assert((ZFLG & 1) == ZFLG); + assert((VFLG & 1) == VFLG); + assert((CFLG & 1) == CFLG); +#endif + regs.sr = ((regs.t1 << 15) | (regs.t0 << 14) + | (regs.s << 13) | (regs.m << 12) | (regs.intmask << 8) + | (GET_XFLG() << 4) | (GET_NFLG() << 3) | (GET_ZFLG() << 2) | (GET_VFLG() << 1) + | GET_CFLG()); +} + +void MakeFromSR (void) +{ + int oldm = regs.m; + int olds = regs.s; + + regs.t1 = (regs.sr >> 15) & 1; + regs.t0 = (regs.sr >> 14) & 1; + regs.s = (regs.sr >> 13) & 1; + mmu_set_super(regs.s); + regs.m = (regs.sr >> 12) & 1; + regs.intmask = (regs.sr >> 8) & 7; + SET_XFLG ((regs.sr >> 4) & 1); + SET_NFLG ((regs.sr >> 3) & 1); + SET_ZFLG ((regs.sr >> 2) & 1); + SET_VFLG ((regs.sr >> 1) & 1); + SET_CFLG (regs.sr & 1); + if (olds != regs.s) { + if (olds) { + if (oldm) + regs.msp = m68k_areg(regs, 7); + else + regs.isp = m68k_areg(regs, 7); + m68k_areg(regs, 7) = regs.usp; + } else { + regs.usp = m68k_areg(regs, 7); + m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp; + } + } else if (olds && oldm != regs.m) { + if (oldm) { + regs.msp = m68k_areg(regs, 7); + m68k_areg(regs, 7) = regs.isp; + } else { + regs.isp = m68k_areg(regs, 7); + m68k_areg(regs, 7) = regs.msp; + } + } + + // SPCFLAGS_SET( SPCFLAG_INT ); + SPCFLAGS_SET( SPCFLAG_INT ); + if (regs.t1 || regs.t0) + SPCFLAGS_SET( SPCFLAG_TRACE ); + else + SPCFLAGS_CLEAR( SPCFLAG_TRACE ); +} + +/* for building exception frames */ +static inline void exc_push_word(uae_u16 w) +{ + m68k_areg(regs, 7) -= 2; + put_word(m68k_areg(regs, 7), w); +} +static inline void exc_push_long(uae_u32 l) +{ + m68k_areg(regs, 7) -= 4; + put_long (m68k_areg(regs, 7), l); +} + +static inline void exc_make_frame( + int format, + uae_u16 sr, + uae_u32 currpc, + int nr, + uae_u32 x0, + uae_u32 x1 +) +{ + switch(format) { + case 4: + exc_push_long(x1); + exc_push_long(x0); + break; + case 3: + case 2: + exc_push_long(x0); + break; + } + + exc_push_word((format << 12) + (nr * 4)); /* format | vector */ + exc_push_long(currpc); + exc_push_word(sr); +#if 0 /* debugging helpers; activate as needed */ + if (/* nr != 0x45 && */ /* Timer-C */ + nr != 0x1c && /* VBL */ + nr != 0x46) /* ACIA */ + { + memptr sp = m68k_areg(regs, 7); + uae_u16 sr = get_word(sp); + fprintf(stderr, "Exc:%02x SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x", nr, sp, regs.usp, sr, get_long(sp + 2), get_word(sp + 6)); + if (nr >= 32 && nr < 48) + { + fprintf(stderr, " Opcode: $%04x", sr & 0x2000 ? get_word(sp + 8) : get_word(regs.usp)); + } + fprintf(stderr, "\n"); + } +#endif +} + + +void ex_rte(void) +{ + uae_u16 newsr; + uae_u32 newpc; + uae_s16 format; + + for (;;) + { + newsr = get_word(m68k_areg(regs, 7)); + m68k_areg(regs, 7) += 2; + newpc = get_long(m68k_areg(regs, 7)); + m68k_areg(regs, 7) += 4; + format = get_word(m68k_areg(regs, 7)); + m68k_areg(regs, 7) += 2; + if ((format & 0xF000) == 0x0000) break; + else if ((format & 0xF000) == 0x1000) { ; } + else if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; } +// else if ((format & 0xF000) == 0x3000) { m68k_areg(regs, 7) += 4; break; } + else if ((format & 0xF000) == 0x7000) { m68k_areg(regs, 7) += 52; break; } + else if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; } + else if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; } + else if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; } + else if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; } + else { Exception(14,0); return; } + regs.sr = newsr; + MakeFromSR(); + } +#if 0 /* debugging helpers; activate as needed */ + { + memptr sp = m68k_areg(regs, 7) - 8; + int nr = (format & 0xfff) >> 2; + if (/* nr != 0x45 && */ /* Timer-C */ + nr != 0x1c && /* VBL */ + nr != 0x46) /* ACIA */ + fprintf(stderr, "RTE SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x olds=%d nr=%02x -> %08x\n", sp, regs.usp, newsr, m68k_getpc(), format, regs.s, nr, newpc); + } +#endif + regs.sr = newsr; + MakeFromSR(); + m68k_setpc_rte(newpc); + fill_prefetch_0(); +} + +#ifdef EXCEPTIONS_VIA_LONGJMP +static int building_bus_fault_stack_frame=0; +#endif + +void Exception(int nr, uaecptr oldpc) +{ + uae_u32 currpc = m68k_getpc (); + MakeSR(); + + if (fixup.flag) + { + m68k_areg(regs, fixup.reg) = fixup.value; + fixup.flag = 0; + } + + if (!regs.s) { + regs.usp = m68k_areg(regs, 7); + m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp; + regs.s = 1; + mmu_set_super(1); + } + + if (nr == 2) { + /* BUS ERROR handler begins */ +#ifdef ENABLE_EPSLIMITER + check_eps_limit(currpc); +#endif + // panicbug("Exception Nr. %d CPC: %08x NPC: %08x SP=%08x Addr: %08x", nr, currpc, get_long (regs.vbr + 4*nr), m68k_areg(regs, 7), regs.mmu_fault_addr); +#ifdef EXCEPTIONS_VIA_LONGJMP + if (!building_bus_fault_stack_frame) +#else + try +#endif + { +#ifdef EXCEPTIONS_VIA_LONGJMP + building_bus_fault_stack_frame= 1; +#endif + /* 68040 */ + exc_push_long(0); /* PD3 */ + exc_push_long(0); /* PD2 */ + exc_push_long(0); /* PD1 */ + exc_push_long(0); /* PD0/WB1D */ + exc_push_long(0); /* WB1A */ + exc_push_long(0); /* WB2D */ + exc_push_long(0); /* WB2A */ + exc_push_long(regs.wb3_data); /* WB3D */ + exc_push_long(regs.mmu_fault_addr); /* WB3A */ + exc_push_long(regs.mmu_fault_addr); + exc_push_word(0); /* WB1S */ + exc_push_word(0); /* WB2S */ + exc_push_word(regs.wb3_status); /* WB3S */ + regs.wb3_status = 0; + exc_push_word(regs.mmu_ssw); + exc_push_long(regs.mmu_fault_addr); /* EA */ + exc_make_frame(7, regs.sr, regs.fault_pc, 2, 0, 0); + + } +#ifdef EXCEPTIONS_VIA_LONGJMP + else +#else + catch (m68k_exception) +#endif + { + report_double_bus_error(); +#ifdef EXCEPTIONS_VIA_LONGJMP + building_bus_fault_stack_frame= 0; +#endif + return; + } + +#ifdef EXCEPTIONS_VIA_LONGJMP + building_bus_fault_stack_frame= 0; +#endif + /* end of BUS ERROR handler */ + } else if (nr == 3) { + exc_make_frame(2, regs.sr, last_addr_for_exception_3, nr, + last_fault_for_exception_3 & 0xfffffffe, 0); + } else if (nr == 5 || nr == 6 || nr == 7 || nr == 9) { + /* div by zero, CHK, TRAP or TRACE */ + exc_make_frame(2, regs.sr, currpc, nr, oldpc, 0); + } else if (regs.m && nr >= 24 && nr < 32) { + /* interrupts! */ + exc_make_frame(0, regs.sr, currpc, nr, 0, 0); + regs.sr |= (1 << 13); + regs.msp = m68k_areg(regs, 7); + m68k_areg(regs, 7) = regs.isp; + + exc_make_frame(1, /* throwaway */ + regs.sr, currpc, nr, 0, 0); + } else { + exc_make_frame(0, regs.sr, currpc, nr, 0, 0); + } + m68k_setpc (get_long (regs.vbr + 4*nr)); + SPCFLAGS_SET( SPCFLAG_JIT_END_COMPILE ); + fill_prefetch_0 (); + regs.t1 = regs.t0 = regs.m = 0; + SPCFLAGS_CLEAR(SPCFLAG_TRACE | SPCFLAG_DOTRACE); +} + +static void Interrupt(int nr) +{ + assert(nr < 8 && nr >= 0); + Exception(nr+24, 0); + + regs.intmask = nr; + // why the hell the SPCFLAG_INT is to be set??? (joy) + // regs.spcflags |= SPCFLAG_INT; (disabled by joy) + SPCFLAGS_SET( SPCFLAG_INT ); +} + +static void SCCInterrupt(int nr) +{ + // fprintf(stderr, "CPU: in SCCInterrupt\n"); + Exception(nr, 0); + + regs.intmask = 5;// ex 5 +} + +static void MFPInterrupt(int nr) +{ + // fprintf(stderr, "CPU: in MFPInterrupt\n"); + Exception(nr, 0); + + regs.intmask = 6; +} + +int m68k_move2c (int regno, uae_u32 *regp) +{ + switch (regno) { + case 0: regs.sfc = *regp & 7; break; + case 1: regs.dfc = *regp & 7; break; + case 2: regs.cacr = *regp & 0x80008000; +#ifdef USE_JIT + set_cache_state(regs.cacr & 0x8000); + if (*regp & 0x08) { /* Just to be on the safe side */ + flush_icache(); + } +#endif + break; + case 3: mmu_set_tc(*regp & 0xc000); break; + case 4: + case 5: + case 6: + case 7: mmu_set_ttr(regno, *regp & 0xffffe364); break; + case 0x800: regs.usp = *regp; break; + case 0x801: regs.vbr = *regp; break; + case 0x802: regs.caar = *regp & 0xfc; break; + case 0x803: regs.msp = *regp; if (regs.m == 1) m68k_areg(regs, 7) = regs.msp; break; + case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break; + case 0x805: mmu_set_mmusr(*regp); break; + case 0x806: regs.urp = *regp & MMU_ROOT_PTR_ADDR_MASK; break; + case 0x807: regs.srp = *regp & MMU_ROOT_PTR_ADDR_MASK; break; + default: + op_illg (0x4E7B); + return 0; + } + return 1; +} + +int m68k_movec2 (int regno, uae_u32 *regp) +{ + switch (regno) { + case 0: *regp = regs.sfc; break; + case 1: *regp = regs.dfc; break; + case 2: *regp = regs.cacr; break; + case 3: *regp = regs.tc; break; + case 4: *regp = regs.itt0; break; + case 5: *regp = regs.itt1; break; + case 6: *regp = regs.dtt0; break; + case 7: *regp = regs.dtt1; break; + case 0x800: *regp = regs.usp; break; + case 0x801: *regp = regs.vbr; break; + case 0x802: *regp = regs.caar; break; + case 0x803: *regp = regs.m == 1 ? m68k_areg(regs, 7) : regs.msp; break; + case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break; + case 0x805: *regp = regs.mmusr; break; + case 0x806: *regp = regs.urp; break; + case 0x807: *regp = regs.srp; break; + default: + op_illg (0x4E7A); + return 0; + } + return 1; +} + +#if !defined(uae_s64) +static inline int +div_unsigned(uae_u32 src_hi, uae_u32 src_lo, uae_u32 div, uae_u32 *quot, uae_u32 *rem) +{ + uae_u32 q = 0, cbit = 0; + int i; + + if (div <= src_hi) { + return 1; + } + for (i = 0 ; i < 32 ; i++) { + cbit = src_hi & 0x80000000ul; + src_hi <<= 1; + if (src_lo & 0x80000000ul) src_hi++; + src_lo <<= 1; + q = q << 1; + if (cbit || div <= src_hi) { + q |= 1; + src_hi -= div; + } + } + *quot = q; + *rem = src_hi; + return 0; +} +#endif + +void m68k_divl (uae_u32 /*opcode*/, uae_u32 src, uae_u16 extra, uaecptr oldpc) +{ +#if defined(uae_s64) + if (src == 0) { + Exception (5, oldpc); + return; + } + if (extra & 0x800) { + /* signed variant */ + uae_s64 a = (uae_s64)(uae_s32)m68k_dreg(regs, (extra >> 12) & 7); + uae_s64 quot, rem; + + if (extra & 0x400) { + a &= 0xffffffffu; + a |= (uae_s64)m68k_dreg(regs, extra & 7) << 32; + } + rem = a % (uae_s64)(uae_s32)src; + quot = a / (uae_s64)(uae_s32)src; + if ((quot & UVAL64(0xffffffff80000000)) != 0 + && (quot & UVAL64(0xffffffff80000000)) != UVAL64(0xffffffff80000000)) + { + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); + } else { + if (((uae_s32)rem < 0) != ((uae_s64)a < 0)) rem = -rem; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); + m68k_dreg(regs, extra & 7) = rem; + m68k_dreg(regs, (extra >> 12) & 7) = quot; + } + } else { + /* unsigned */ + uae_u64 a = (uae_u64)(uae_u32)m68k_dreg(regs, (extra >> 12) & 7); + uae_u64 quot, rem; + + if (extra & 0x400) { + a &= 0xffffffffu; + a |= (uae_u64)m68k_dreg(regs, extra & 7) << 32; + } + rem = a % (uae_u64)src; + quot = a / (uae_u64)src; + if (quot > 0xffffffffu) { + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); + } else { + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); + m68k_dreg(regs, extra & 7) = rem; + m68k_dreg(regs, (extra >> 12) & 7) = quot; + } + } +#else + if (src == 0) { + Exception (5, oldpc); + return; + } + if (extra & 0x800) { + /* signed variant */ + uae_s32 lo = (uae_s32)m68k_dreg(regs, (extra >> 12) & 7); + uae_s32 hi = lo < 0 ? -1 : 0; + uae_s32 save_high; + uae_u32 quot, rem; + uae_u32 sign; + + if (extra & 0x400) { + hi = (uae_s32)m68k_dreg(regs, extra & 7); + } + save_high = hi; + sign = (hi ^ src); + if (hi < 0) { + hi = ~hi; + lo = -lo; + if (lo == 0) hi++; + } + if ((uae_s32)src < 0) src = -src; + if (div_unsigned(hi, lo, src, ", &rem) || + (sign & 0x80000000) ? quot > 0x80000000 : quot > 0x7fffffff) { + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); + } else { + if (sign & 0x80000000) quot = -quot; + if (((uae_s32)rem < 0) != (save_high < 0)) rem = -rem; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); + m68k_dreg(regs, extra & 7) = rem; + m68k_dreg(regs, (extra >> 12) & 7) = quot; + } + } else { + /* unsigned */ + uae_u32 lo = (uae_u32)m68k_dreg(regs, (extra >> 12) & 7); + uae_u32 hi = 0; + uae_u32 quot, rem; + + if (extra & 0x400) { + hi = (uae_u32)m68k_dreg(regs, extra & 7); + } + if (div_unsigned(hi, lo, src, ", &rem)) { + SET_VFLG (1); + SET_NFLG (1); + SET_CFLG (0); + } else { + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (((uae_s32)quot) == 0); + SET_NFLG (((uae_s32)quot) < 0); + m68k_dreg(regs, extra & 7) = rem; + m68k_dreg(regs, (extra >> 12) & 7) = quot; + } + } +#endif +} + +#if !defined(uae_s64) +static inline void +mul_unsigned(uae_u32 src1, uae_u32 src2, uae_u32 *dst_hi, uae_u32 *dst_lo) +{ + uae_u32 r0 = (src1 & 0xffff) * (src2 & 0xffff); + uae_u32 r1 = ((src1 >> 16) & 0xffff) * (src2 & 0xffff); + uae_u32 r2 = (src1 & 0xffff) * ((src2 >> 16) & 0xffff); + uae_u32 r3 = ((src1 >> 16) & 0xffff) * ((src2 >> 16) & 0xffff); + uae_u32 lo; + + lo = r0 + ((r1 << 16) & 0xffff0000ul); + if (lo < r0) r3++; + r0 = lo; + lo = r0 + ((r2 << 16) & 0xffff0000ul); + if (lo < r0) r3++; + r3 += ((r1 >> 16) & 0xffff) + ((r2 >> 16) & 0xffff); + *dst_lo = lo; + *dst_hi = r3; +} +#endif + +void m68k_mull (uae_u32 /*opcode*/, uae_u32 src, uae_u16 extra) +{ +#if defined(uae_s64) + if (extra & 0x800) { + /* signed variant */ + uae_s64 a = (uae_s64)(uae_s32)m68k_dreg(regs, (extra >> 12) & 7); + + a *= (uae_s64)(uae_s32)src; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (a == 0); + SET_NFLG (a < 0); + if (extra & 0x400) + m68k_dreg(regs, extra & 7) = a >> 32; + else if ((a & UVAL64(0xffffffff80000000)) != 0 + && (a & UVAL64(0xffffffff80000000)) != UVAL64(0xffffffff80000000)) + { + SET_VFLG (1); + } + m68k_dreg(regs, (extra >> 12) & 7) = (uae_u32)a; + } else { + /* unsigned */ + uae_u64 a = (uae_u64)(uae_u32)m68k_dreg(regs, (extra >> 12) & 7); + + a *= (uae_u64)src; + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (a == 0); + SET_NFLG (((uae_s64)a) < 0); + if (extra & 0x400) + m68k_dreg(regs, extra & 7) = a >> 32; + else if ((a & UVAL64(0xffffffff00000000)) != 0) { + SET_VFLG (1); + } + m68k_dreg(regs, (extra >> 12) & 7) = (uae_u32)a; + } +#else + if (extra & 0x800) { + /* signed variant */ + uae_s32 src1,src2; + uae_u32 dst_lo,dst_hi; + uae_u32 sign; + + src1 = (uae_s32)src; + src2 = (uae_s32)m68k_dreg(regs, (extra >> 12) & 7); + sign = (src1 ^ src2); + if (src1 < 0) src1 = -src1; + if (src2 < 0) src2 = -src2; + mul_unsigned((uae_u32)src1,(uae_u32)src2,&dst_hi,&dst_lo); + if (sign & 0x80000000) { + dst_hi = ~dst_hi; + dst_lo = -dst_lo; + if (dst_lo == 0) dst_hi++; + } + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (dst_hi == 0 && dst_lo == 0); + SET_NFLG (((uae_s32)dst_hi) < 0); + if (extra & 0x400) + m68k_dreg(regs, extra & 7) = dst_hi; + else if ((dst_hi != 0 || (dst_lo & 0x80000000) != 0) + && ((dst_hi & 0xffffffff) != 0xffffffff + || (dst_lo & 0x80000000) != 0x80000000)) + { + SET_VFLG (1); + } + m68k_dreg(regs, (extra >> 12) & 7) = dst_lo; + } else { + /* unsigned */ + uae_u32 dst_lo,dst_hi; + + mul_unsigned(src,(uae_u32)m68k_dreg(regs, (extra >> 12) & 7),&dst_hi,&dst_lo); + + SET_VFLG (0); + SET_CFLG (0); + SET_ZFLG (dst_hi == 0 && dst_lo == 0); + SET_NFLG (((uae_s32)dst_hi) < 0); + if (extra & 0x400) + m68k_dreg(regs, extra & 7) = dst_hi; + else if (dst_hi != 0) { + SET_VFLG (1); + } + m68k_dreg(regs, (extra >> 12) & 7) = dst_lo; + } +#endif +} + +// If value is greater than zero, this means we are still processing an EmulOp +// because the counter is incremented only in m68k_execute(), i.e. interpretive +// execution only +#ifdef USE_JIT +static int m68k_execute_depth = 0; +#endif + +void m68k_reset (void) +{ + regs.s = 1; + regs.m = 0; + regs.stopped = 0; + regs.t1 = 0; + regs.t0 = 0; + SET_ZFLG (0); + SET_XFLG (0); + SET_CFLG (0); + SET_VFLG (0); + SET_NFLG (0); + SPCFLAGS_INIT( 0 ); + regs.intmask = 7; + regs.vbr = regs.sfc = regs.dfc = 0; + + // need to ensure the following order of initialization is correct + // (it is definitely better than what it was before this commit + // since it was reading from 0x00000000 in User mode and with active MMU) + mmu_set_tc(regs.tc & ~0x8000); /* disable mmu */ +#if 0 + m68k_areg (regs, 7) = phys_get_long(0x00000000); +#else + m68k_areg (regs, 7) = 0x2000; +#endif +#if 0 + m68k_setpc (phys_get_long(0x00000004)); +#else + m68k_setpc (ROMBaseMac + 0x2a); +#endif + fill_prefetch_0 (); + + /* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init() + regs.fpcr = regs.fpsr = regs.fpiar = 0; */ + fpu_reset(); +#if 0 + // MMU + mmu_reset(); + mmu_set_super(1); + // Cache + regs.cacr = 0; + regs.caar = 0; +#endif +#ifdef FLIGHT_RECORDER + log_ptr = 0; + memset(frlog, 0, sizeof(frlog)); +#endif +} + +void m68k_emulop_return(void) +{ + SPCFLAGS_SET( SPCFLAG_BRK ); + quit_program = 1; +} + +static void save_regs(struct M68kRegisters &r) +{ + int i; + + for (i=0; i<8; i++) { + r.d[i] = m68k_dreg(regs, i); + r.a[i] = m68k_areg(regs, i); + } + r.pc = m68k_getpc(); + MakeSR(); + r.sr = regs.sr; + r.isp = regs.isp; + r.usp = regs.usp; + r.msp = regs.msp; + if ((r.sr & 0x2000) == 0) + r.usp = r.a[7]; + else if ((r.sr & 0x1000) != 0) + r.msp = r.a[7]; + else + r.isp = r.a[7]; +} + +static void restore_regs(struct M68kRegisters &r) +{ + int i; + + for (i=0; i<8; i++) { + m68k_dreg(regs, i) = r.d[i]; + m68k_areg(regs, i) = r.a[i]; + } + regs.isp = r.isp; + regs.usp = r.usp; + regs.msp = r.msp; + regs.sr = r.sr; + MakeFromSR(); +} + +void m68k_emulop(uae_u32 opcode) +{ +#if 0 + struct M68kRegisters r; + save_regs(r); + if (EmulOp(opcode, &r)) + restore_regs(r); +#else + struct M68kRegisters r; + int i; + + for (i=0; i<8; i++) { + r.d[i] = m68k_dreg(regs, i); + r.a[i] = m68k_areg(regs, i); + } + MakeSR(); + r.sr = regs.sr; + EmulOp(opcode, &r); + for (i=0; i<8; i++) { + m68k_dreg(regs, i) = r.d[i]; + m68k_areg(regs, i) = r.a[i]; + } + regs.sr = r.sr; + MakeFromSR(); +#endif +} + +#if 0 +void m68k_natfeat_id(void) +{ + struct M68kRegisters r; + + /* is it really necessary to save all registers? */ + save_regs(r); + + memptr stack = r.a[7] + 4; /* skip return address */ + r.d[0] = nf_get_id(stack); + + restore_regs(r); +} + +void m68k_natfeat_call(void) +{ + struct M68kRegisters r; + + /* is it really necessary to save all registers? */ + save_regs(r); + + memptr stack = r.a[7] + 4; /* skip return address */ + bool isSupervisorMode = ((r.sr & 0x2000) == 0x2000); + r.d[0] = nf_call(stack, isSupervisorMode); + + restore_regs(r); +} +#endif + +static int m68k_call(uae_u32 pc) +{ + VOLATILE int exc = 0; + m68k_setpc(pc); + TRY(prb) { +#ifdef USE_JIT + if (UseJIT) { + exec_nostats(); + // m68k_do_compile_execute(); + // The above call to m68k_do_compile_execute fails with BadAccess in sigsegv_handler (MAC, if it is executed after the first compile_block) + // (NULL pointer to addr_instr). + // Call exec_nostats avoids calling compile_block, because stack modification is only temporary + // which will fill up compile cache with BOGUS data. + // we can call exec_nostats directly, do our code, and return back here. + } + else +#endif + m68k_do_execute(); + } + CATCH(prb) { + exc = int(prb); + } + return exc; +} + +static uae_u32 m68k_alloca(int size) +{ + uae_u32 sp = (m68k_areg(regs, 7) - size) & ~1; + m68k_areg(regs, 7) = sp; + if ((regs.sr & 0x2000) == 0) + regs.usp = sp; + else if ((regs.sr & 0x1000) != 0) + regs.msp = sp; + else + regs.isp = sp; + return sp; +} + +#if 0 +uae_u32 linea68000(volatile uae_u16 opcode) +{ + sigjmp_buf jmp; + struct M68kRegisters r; + volatile uae_u32 abase = 0; + + SAVE_EXCEPTION; + save_regs(r); + + const int sz = 8 + sizeof(void *); + volatile uae_u32 sp = 0; + uae_u32 backup[(sz + 3) / 4]; + + if (sigsetjmp(jmp, 1) == 0) + { + void *p = jmp; + uae_u8 *sp_p; + int exc; + + sp = m68k_alloca(sz); + memcpy(backup, phys_get_real_address(sp), sz); + + WriteHWMemInt16(sp, opcode); + WriteHWMemInt16(sp + 2, 0xa0ff); + WriteHWMemInt32(sp + 4, 13); + sp_p = phys_get_real_address(sp + 8); + *((void **)sp_p) = p; + if ((exc = m68k_call(sp)) != 0) + { + panicbug("exception %d in LINEA", exc); + m68k_dreg(regs, 0) = 0; + } + } else + { + abase = m68k_dreg(regs, 0); + } + + if (sp) { + memcpy(phys_get_real_address(sp), backup, sz); + } + restore_regs(r); + m68k_setpc(r.pc); + RESTORE_EXCEPTION; + return abase; +} +#endif + + +static void rts68000() +{ + uae_u32 SP = m68k_getpc() + 6; + sigjmp_buf *p; + uae_u8 *sp_p = phys_get_real_address(SP); + + p = (sigjmp_buf *)(*((void **)sp_p)); + SP += sizeof(void *); + m68k_areg(regs, 7) = SP; + siglongjmp(*p, 1); +} + +void REGPARAM2 op_illg (uae_u32 opcode) +{ + uaecptr pc = m68k_getpc (); + + if ((opcode & 0xF000) == 0xA000) { +#if 0 + if (opcode == 0xa0ff) + { + uae_u32 call = ReadHWMemInt32(pc + 2); + switch (call) + { + case 13: + rts68000(); + return; + } + m68k_setpc(pc + 6); + } +#endif + Exception(0xA,0); + return; + } + + if ((opcode & 0xF000) == 0xF000) { + Exception(0xB,0); + return; + } + + D(bug("Illegal instruction: %04x at %08x", opcode, pc)); +#if defined(USE_JIT) && defined(JIT_DEBUG) + compiler_dumpstate(); +#endif + + Exception (4,0); + return; +} + +static uaecptr last_trace_ad = 0; + +static void do_trace (void) +{ + if (regs.t0) { + uae_u16 opcode; + /* should also include TRAP, CHK, SR modification FPcc */ + /* probably never used so why bother */ + /* We can afford this to be inefficient... */ + m68k_setpc (m68k_getpc ()); + fill_prefetch_0 (); + opcode = get_word(m68k_getpc()); + if (opcode == 0x4e72 /* RTE */ + || opcode == 0x4e74 /* RTD */ + || opcode == 0x4e75 /* RTS */ + || opcode == 0x4e77 /* RTR */ + || opcode == 0x4e76 /* TRAPV */ + || (opcode & 0xffc0) == 0x4e80 /* JSR */ + || (opcode & 0xffc0) == 0x4ec0 /* JMP */ + || (opcode & 0xff00) == 0x6100 /* BSR */ + || ((opcode & 0xf000) == 0x6000 /* Bcc */ + && cctrue((opcode >> 8) & 0xf)) + || ((opcode & 0xf0f0) == 0x5050 /* DBcc */ + && !cctrue((opcode >> 8) & 0xf) + && (uae_s16)m68k_dreg(regs, opcode & 7) != 0)) + { + last_trace_ad = m68k_getpc (); + SPCFLAGS_CLEAR( SPCFLAG_TRACE ); + SPCFLAGS_SET( SPCFLAG_DOTRACE ); + } + } else if (regs.t1) { + last_trace_ad = m68k_getpc (); + SPCFLAGS_CLEAR( SPCFLAG_TRACE ); + SPCFLAGS_SET( SPCFLAG_DOTRACE ); + } +} + +#if 0 +#define SERVE_VBL_MFP(resetStop) \ +{ \ + if (SPCFLAGS_TEST( SPCFLAG_INT3|SPCFLAG_VBL|SPCFLAG_INT5|SPCFLAG_SCC|SPCFLAG_MFP )) { \ + if (SPCFLAGS_TEST( SPCFLAG_INT3 )) { \ + if (3 > regs.intmask) { \ + Interrupt(3); \ + regs.stopped = 0; \ + SPCFLAGS_CLEAR( SPCFLAG_INT3 ); \ + if (resetStop) \ + SPCFLAGS_CLEAR( SPCFLAG_STOP ); \ + } \ + } \ + if (SPCFLAGS_TEST( SPCFLAG_VBL )) { \ + if (4 > regs.intmask) { \ + Interrupt(4); \ + regs.stopped = 0; \ + SPCFLAGS_CLEAR( SPCFLAG_VBL ); \ + if (resetStop) \ + SPCFLAGS_CLEAR( SPCFLAG_STOP ); \ + } \ + } \ + if (SPCFLAGS_TEST( SPCFLAG_INT5 )) { \ + if (5 > regs.intmask) { \ + Interrupt(5); \ + regs.stopped = 0; \ + SPCFLAGS_CLEAR( SPCFLAG_INT5 ); \ + if (resetStop) \ + SPCFLAGS_CLEAR( SPCFLAG_STOP ); \ + } \ + } \ + if (SPCFLAGS_TEST( SPCFLAG_SCC )) { \ + if (5 > regs.intmask) { \ + int vector_number=SCCdoInterrupt(); \ + if(vector_number){ \ + SCCInterrupt(vector_number); \ + regs.stopped = 0; \ + SPCFLAGS_CLEAR( SPCFLAG_SCC); \ + if (resetStop) \ + SPCFLAGS_CLEAR( SPCFLAG_STOP ); \ + } \ + else \ + SPCFLAGS_CLEAR( SPCFLAG_SCC ); \ + } \ + } \ + if (SPCFLAGS_TEST( SPCFLAG_MFP )) { \ + if (6 > regs.intmask) { \ + int vector_number = MFPdoInterrupt(); \ + if (vector_number) { \ + MFPInterrupt(vector_number); \ + regs.stopped = 0; \ + if (resetStop) \ + SPCFLAGS_CLEAR( SPCFLAG_STOP ); \ + } \ + else \ + SPCFLAGS_CLEAR( SPCFLAG_MFP ); \ + } \ + } \ + } \ +} + +#define SERVE_INTERNAL_IRQ() \ +{ \ + if (SPCFLAGS_TEST( SPCFLAG_INTERNAL_IRQ )) { \ + SPCFLAGS_CLEAR( SPCFLAG_INTERNAL_IRQ ); \ + invoke200HzInterrupt(); \ + } \ +} +#endif + +int m68k_do_specialties(void) +{ +#if 0 + SERVE_INTERNAL_IRQ(); +#endif +#ifdef USE_JIT + // Block was compiled + SPCFLAGS_CLEAR( SPCFLAG_JIT_END_COMPILE ); + + // Retain the request to get out of compiled code until + // we reached the toplevel execution, i.e. the one that + // can compile then run compiled code. This also means + // we processed all (nested) EmulOps + if ((m68k_execute_depth == 0) && SPCFLAGS_TEST( SPCFLAG_JIT_EXEC_RETURN )) + SPCFLAGS_CLEAR( SPCFLAG_JIT_EXEC_RETURN ); +#endif + /*n_spcinsns++;*/ + if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) { + Exception (9,last_trace_ad); + } +#if 0 /* not for ARAnyM; emulating 040 only */ + if ((regs.spcflags & SPCFLAG_STOP) && regs.s == 0 && currprefs.cpu_model <= 68010) { + // 68000/68010 undocumented special case: + // if STOP clears S-bit and T was not set: + // cause privilege violation exception, PC pointing to following instruction. + // If T was set before STOP: STOP works as documented. + m68k_unset_stop(); + Exception(8, 0); + } +#endif + while (SPCFLAGS_TEST( SPCFLAG_STOP )) { + //TODO: Check +#if 0 + if ((regs.sr & 0x700) == 0x700) + { + panicbug("STOPed with interrupts disabled, exiting; pc=$%08x", m68k_getpc()); + m68k_dumpstate (stderr, NULL); + quit_program = 1; +#ifdef FULL_HISTORY + ndebug::showHistory(20, false); + m68k_dumpstate (stderr, NULL); +#endif + return 1; + } +#endif +#if 0 + // give unused time slices back to OS + SleepAndWait(); +#endif + if (SPCFLAGS_TEST( SPCFLAG_INT | SPCFLAG_DOINT )){ + SPCFLAGS_CLEAR( SPCFLAG_INT | SPCFLAG_DOINT ); + int intr = intlev (); + if (intr != -1 && intr > regs.intmask) { + Interrupt (intr); + regs.stopped = 0; + SPCFLAGS_CLEAR( SPCFLAG_STOP ); + } + } + +#if 0 + SERVE_INTERNAL_IRQ(); + SERVE_VBL_MFP(true); +#endif +#if 0 + if (SPCFLAGS_TEST( SPCFLAG_BRK )) + break; +#endif + } + if (SPCFLAGS_TEST( SPCFLAG_TRACE )) + do_trace (); + +#if 0 + SERVE_VBL_MFP(false); +#endif + +/* +// do not understand the INT vs DOINT stuff so I disabled it (joy) + if (regs.spcflags & SPCFLAG_INT) { + regs.spcflags &= ~SPCFLAG_INT; + regs.spcflags |= SPCFLAG_DOINT; + } +*/ + if (SPCFLAGS_TEST( SPCFLAG_DOINT )) { + SPCFLAGS_CLEAR( SPCFLAG_DOINT ); + int intr = intlev (); + if (intr != -1 && intr > regs.intmask) { + Interrupt (intr); + regs.stopped = 0; + } + } + + if (SPCFLAGS_TEST( SPCFLAG_INT )) { + SPCFLAGS_CLEAR( SPCFLAG_INT ); + SPCFLAGS_SET( SPCFLAG_DOINT ); + } + + if (SPCFLAGS_TEST( SPCFLAG_BRK /*| SPCFLAG_MODE_CHANGE*/ )) { + SPCFLAGS_CLEAR( SPCFLAG_BRK /*| SPCFLAG_MODE_CHANGE*/ ); + return 1; + } + + return 0; +} + +void m68k_do_execute (void) +{ + uae_u32 pc; + uae_u32 opcode; + for (;;) { + regs.fault_pc = pc = m68k_getpc(); +#ifdef FULL_HISTORY +#ifdef NEED_TO_DEBUG_BADLY + history[lasthist] = regs; + historyf[lasthist] = regflags; +#else + history[lasthist] = m68k_getpc(); +#endif + if (++lasthist == MAX_HIST) lasthist = 0; + if (lasthist == firsthist) { + if (++firsthist == MAX_HIST) firsthist = 0; + } +#endif + +#ifndef FULLMMU +#ifdef ARAM_PAGE_CHECK + if (((pc ^ pc_page) > ARAM_PAGE_MASK)) { + check_ram_boundary(pc, 2, false); + pc_page = pc; + pc_offset = (uintptr)get_real_address(pc, 0, sz_word) - pc; + } +#else + check_ram_boundary(pc, 2, false); +#endif +#endif + opcode = GET_OPCODE; +#ifdef FLIGHT_RECORDER + m68k_record_step(m68k_getpc(), cft_map(opcode)); +#endif + (*cpufunctbl[opcode])(opcode); + cpu_check_ticks(); + regs.fault_pc = m68k_getpc(); + + if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { + if (m68k_do_specialties()) + return; + } + } +} + +void m68k_execute (void) +{ +#ifdef USE_JIT + m68k_execute_depth++; +#endif +#ifdef DEBUGGER + VOLATILE bool after_exception = false; +#endif + +setjmpagain: + TRY(prb) { + for (;;) { + if (quit_program > 0) { + if (quit_program == 1) { +#ifdef FLIGHT_RECORDER + dump_flight_recorder(); +#endif + break; + } + quit_program = 0; + m68k_reset (); + } +#ifdef DEBUGGER + if (debugging && !after_exception) debug(); + after_exception = false; +#endif + m68k_do_execute(); + } + } + CATCH(prb) { + Exception(prb, 0); +#ifdef DEBUGGER + after_exception = true; +#endif + goto setjmpagain; + } + +#ifdef USE_JIT + m68k_execute_depth--; +#endif +} + +void m68k_disasm (FILE *f, uaecptr addr, uaecptr *nextpc, int cnt) +{ +#ifdef HAVE_DISASM_M68K + char buf[256]; + int size; + + disasm_info.memory_vma = addr; + while (cnt-- > 0) { + size = m68k_disasm_to_buf(&disasm_info, buf, 1); + fprintf(f, "%s\n", buf); + if (size < 0) + break; + } + if (nextpc) + *nextpc = disasm_info.memory_vma; +#else + if (nextpc) + *nextpc = addr; + (void) f; + (void) cnt; +#endif +} + +#ifdef DEBUGGER +void newm68k_disasm(FILE *f, uaecptr addr, uaecptr *nextpc, unsigned int cnt) +{ +#ifdef HAVE_DISASM_M68K + char buf[256]; + + disasm_info.memory_vma = addr; + if (cnt == 0) { + m68k_disasm_to_buf(&disasm_info, buf, 1); + } else { + while (cnt-- > 0) { + m68k_disasm_to_buf(&disasm_info, buf, 1); + fprintf(f, "%s\n", buf); + } + } + if (nextpc) + *nextpc = disasm_info.memory_vma; +#else + if (nextpc) + *nextpc = addr; + (void) cnt; +#endif +} + +#endif /* DEBUGGER */ + +#ifdef FULL_HISTORY +void showDisasm(uaecptr addr) { +#ifdef HAVE_DISASM_M68K + char buf[256]; + + disasm_info.memory_vma = addr; + m68k_disasm_to_buf(&disasm_info, buf, 1); + bug("%s", buf); +#else + (void) addr; +#endif +} +#endif /* FULL_HISTORY */ + +void m68k_dumpstate (FILE *out, uaecptr *nextpc) +{ + int i; + for (i = 0; i < 8; i++){ + fprintf (out, "D%d: %08lx ", i, (unsigned long)m68k_dreg(regs, i)); + if ((i & 3) == 3) fprintf (out, "\n"); + } + for (i = 0; i < 8; i++){ + fprintf (out, "A%d: %08lx ", i, (unsigned long)m68k_areg(regs, i)); + if ((i & 3) == 3) fprintf (out, "\n"); + } + if (regs.s == 0) regs.usp = m68k_areg(regs, 7); + if (regs.s && regs.m) regs.msp = m68k_areg(regs, 7); + if (regs.s && regs.m == 0) regs.isp = m68k_areg(regs, 7); + fprintf (out, "USP=%08lx ISP=%08lx MSP=%08lx VBR=%08lx\n", + (unsigned long)regs.usp, (unsigned long)regs.isp, + (unsigned long)regs.msp, (unsigned long)regs.vbr); + fprintf (out, "T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d TCE=%d TCP=%d\n", + regs.t1, regs.t0, regs.s, regs.m, + (int)GET_XFLG(), (int)GET_NFLG(), (int)GET_ZFLG(), (int)GET_VFLG(), (int)GET_CFLG(), regs.intmask, + regs.mmu_enabled, regs.mmu_pagesize_8k); + fprintf (out, "CACR=%08lx CAAR=%08lx URP=%08lx SRP=%08lx\n", + (unsigned long)regs.cacr, + (unsigned long)regs.caar, + (unsigned long)regs.urp, + (unsigned long)regs.srp); + fprintf (out, "DTT0=%08lx DTT1=%08lx ITT0=%08lx ITT1=%08lx\n", + (unsigned long)regs.dtt0, + (unsigned long)regs.dtt1, + (unsigned long)regs.itt0, + (unsigned long)regs.itt1); + for (i = 0; i < 8; i++){ + fprintf (out, "FP%d: %g ", i, (double)fpu.registers[i]); + if ((i & 3) == 3) fprintf (out, "\n"); + } +#if 0 + fprintf (out, "N=%d Z=%d I=%d NAN=%d\n", + (regs.fpsr & 0x8000000) != 0, + (regs.fpsr & 0x4000000) != 0, + (regs.fpsr & 0x2000000) != 0, + (regs.fpsr & 0x1000000) != 0); +#endif + m68k_disasm(out, m68k_getpc (), nextpc, 1); + if (nextpc) + fprintf (out, "next PC: %08lx\n", (unsigned long)*nextpc); +} diff --git a/BasiliskII/src/uae_cpu_2021/newcpu.h b/BasiliskII/src/uae_cpu_2021/newcpu.h new file mode 100644 index 000000000..478a3785e --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/newcpu.h @@ -0,0 +1,335 @@ +/* + * newcpu.h - CPU emulation + * + * Copyright (c) 2009 ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM 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. + * + * ARAnyM 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 ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + /* + * UAE - The Un*x Amiga Emulator + * + * MC68000 emulation + * + * Copyright 1995 Bernd Schmidt + */ + +#ifndef NEWCPU_H +#define NEWCPU_H + +#include "sysdeps.h" +#include "registers.h" +#include "spcflags.h" +#include "m68k.h" +#include "memory.h" + +# include + +extern struct fixup { + int flag; + uae_u32 reg; + uaecptr value; +}fixup; + +extern int areg_byteinc[]; +extern int imm8_table[]; + +extern int movem_index1[256]; +extern int movem_index2[256]; +extern int movem_next[256]; + +extern int broken_in; + +#ifdef X86_ASSEMBLY +/* This hack seems to force all register saves (pushl %reg) to be moved to the + begining of the function, thus making it possible to cpuopti to remove them + since m68k_run_1 will save those registers before calling the instruction + handler */ +# define cpuop_tag(tag) __asm__ __volatile__ ( "#cpuop_" tag ) +#else +# define cpuop_tag(tag) ; +#endif + +#define cpuop_begin() do { cpuop_tag("begin"); } while (0) +#define cpuop_end() do { cpuop_tag("end"); } while (0) + +typedef void REGPARAM2 cpuop_func (uae_u32) REGPARAM; + +struct cputbl { + cpuop_func *handler; + uae_u16 specific; + uae_u16 opcode; +}; + +extern cpuop_func *cpufunctbl[65536]; + +#ifdef USE_JIT +typedef void compop_func (uae_u32) REGPARAM; + +struct comptbl { + compop_func *handler; + uae_u32 opcode; + uae_u32 specific; +#define COMP_OPCODE_ISJUMP 0x0001 +#define COMP_OPCODE_LONG_OPCODE 0x0002 +#define COMP_OPCODE_CMOV 0x0004 +#define COMP_OPCODE_ISADDX 0x0008 +#define COMP_OPCODE_ISCJUMP 0x0010 +#define COMP_OPCODE_USES_FPU 0x0020 +}; +#endif + +extern void REGPARAM2 op_illg (uae_u32) REGPARAM; + +#define m68k_dreg(r,num) ((r).regs[(num)]) +#define m68k_areg(r,num) (((r).regs + 8)[(num)]) + +#ifdef FULLMMU +static ALWAYS_INLINE uae_u8 get_ibyte(uae_u32 o) +{ + return mmu_get_byte(m68k_getpc() + o + 1, 0, sz_byte); +} +static ALWAYS_INLINE uae_u16 get_iword(uae_u32 o) +{ + return mmu_get_word(m68k_getpc() + o, 0, sz_word); +} +static ALWAYS_INLINE uae_u32 get_ilong(uae_u32 o) +{ + uaecptr addr = m68k_getpc() + o; + + if (unlikely(is_unaligned(addr, 4))) + return mmu_get_long_unaligned(addr, 0); + return mmu_get_long(addr, 0, sz_long); +} + +#else +#define get_ibyte(o) do_get_mem_byte((uae_u8 *)(get_real_address(m68k_getpc(), 0, sz_byte) + (o) + 1)) +#define get_iword(o) do_get_mem_word((uae_u16 *)(get_real_address(m68k_getpc(), 0, sz_word) + (o))) +#define get_ilong(o) do_get_mem_long((uae_u32 *)(get_real_address(m68k_getpc(), 0, sz_long) + (o))) +#endif + +#if 0 +static inline uae_u32 get_ibyte_prefetch (uae_s32 o) +{ + if (o > 3 || o < 0) + return do_get_mem_byte((uae_u8 *)(do_get_real_address(regs.pcp, false, false) + o + 1)); + + return do_get_mem_byte((uae_u8 *)(((uae_u8 *)®s.prefetch) + o + 1)); +} +static inline uae_u32 get_iword_prefetch (uae_s32 o) +{ + if (o > 3 || o < 0) + return do_get_mem_word((uae_u16 *)(do_get_real_address(regs.pcp, false, false) + o)); + + return do_get_mem_word((uae_u16 *)(((uae_u8 *)®s.prefetch) + o)); +} +static inline uae_u32 get_ilong_prefetch (uae_s32 o) +{ + if (o > 3 || o < 0) + return do_get_mem_long((uae_u32 *)(do_get_real_address(regs.pcp, false, false) + o)); + if (o == 0) + return do_get_mem_long(®s.prefetch); + return (do_get_mem_word (((uae_u16 *)®s.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(do_get_real_address(regs.pcp, false, false) + 4)); +} +#endif + +#ifdef FULLMMU +#define m68k_incpc(o) (regs.pc += (o)) +#else +#define m68k_incpc(o) (regs.pc_p += (o)) +#endif + +static inline void fill_prefetch_0 (void) +{ +#if USE_PREFETCH_BUFFER + uae_u32 r; +#ifdef UNALIGNED_PROFITABLE + r = *(uae_u32 *)do_get_real_address(m68k_getpc(), false, false); + regs.prefetch = r; +#else + r = do_get_mem_long ((uae_u32 *)do_get_real_address(m68k_getpc(), false, false)); + do_put_mem_long (®s.prefetch, r); +#endif +#endif +} + +#if 0 +static inline void fill_prefetch_2 (void) +{ + uae_u32 r = do_get_mem_long (®s.prefetch) << 16; + uae_u32 r2 = do_get_mem_word (((uae_u16 *)do_get_real_address(regs.pcp, false, false)) + 1); + r |= r2; + do_put_mem_long (®s.prefetch, r); +} +#else +#define fill_prefetch_2 fill_prefetch_0 +#endif + +/* These are only used by the 68020/68881 code, and therefore don't + * need to handle prefetch. */ +static inline uae_u32 next_ibyte (void) +{ + uae_u32 r = get_ibyte (0); + m68k_incpc (2); + return r; +} + +static inline uae_u32 next_iword (void) +{ + uae_u32 r = get_iword (0); + m68k_incpc (2); + return r; +} + +static inline uae_u32 next_ilong (void) +{ + uae_u32 r = get_ilong (0); + m68k_incpc (4); + return r; +} + +static inline void m68k_setpc (uaecptr newpc) +{ +#ifndef FULLMMU + regs.pc_p = regs.pc_oldp = get_real_address(newpc, 0, sz_word); +#endif + regs.fault_pc = regs.pc = newpc; +} + +#define m68k_setpc_fast m68k_setpc +#define m68k_setpc_bcc m68k_setpc +#define m68k_setpc_rte m68k_setpc + +static inline void m68k_do_rts(void) +{ + m68k_setpc(get_long(m68k_areg(regs, 7))); + m68k_areg(regs, 7) += 4; +} + +static inline void m68k_do_bsr(uaecptr oldpc, uae_s32 offset) +{ + put_long(m68k_areg(regs, 7) - 4, oldpc); + m68k_areg(regs, 7) -= 4; + m68k_incpc(offset); +} + +static inline void m68k_do_jsr(uaecptr oldpc, uaecptr dest) +{ + put_long(m68k_areg(regs, 7) - 4, oldpc); + m68k_areg(regs, 7) -= 4; + m68k_setpc(dest); +} + +static inline void m68k_setstopped (int stop) +{ + regs.stopped = stop; + /* A traced STOP instruction drops through immediately without + actually stopping. */ + if (stop && !( SPCFLAGS_TEST( SPCFLAG_DOTRACE ))) + SPCFLAGS_SET( SPCFLAG_STOP ); +} + +#ifdef FULLMMU +# define GET_OPCODE (get_iword (0)) +#elif defined ARAM_PAGE_CHECK +# ifdef HAVE_GET_WORD_UNSWAPPED +# define GET_OPCODE (do_get_mem_word_unswapped((uae_u16*)(pc + pc_offset))); +# else +# define GET_OPCODE (do_get_mem_word((uae_u16*)(pc + pc_offset))); +# endif +#else +# ifdef HAVE_GET_WORD_UNSWAPPED +# define GET_OPCODE (do_get_mem_word_unswapped ((uae_u16*)get_real_address(m68k_getpc(), 0, sz_word))) +# else +# define GET_OPCODE (get_iword (0)) +# endif +#endif + +extern REGPARAM uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp); +extern REGPARAM uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp); +extern REGPARAM uae_u32 get_bitfield(uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width); +extern REGPARAM void put_bitfield(uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width); + + + +extern void MakeSR (void); +extern void MakeFromSR (void); +extern void Exception (int, uaecptr); +extern void ex_rte(void); +extern void dump_counts (void); +extern int m68k_move2c (int, uae_u32 *); +extern int m68k_movec2 (int, uae_u32 *); +extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr); +extern void m68k_mull (uae_u32, uae_u32, uae_u16); +extern void m68k_emulop (uae_u32); +extern void m68k_emulop_return (void); +extern void m68k_natfeat_id(void); +extern void m68k_natfeat_call(void); +extern void init_m68k (void); +extern void exit_m68k (void); +extern void m68k_dumpstate (FILE *, uaecptr *); +extern void m68k_disasm (FILE *, uaecptr, uaecptr *, int); +extern void newm68k_disasm(FILE *, uaecptr, uaecptr *, unsigned int); +extern void showDisasm(uaecptr); +extern void m68k_reset (void); +extern void m68k_enter_debugger(void); +extern int m68k_do_specialties(void); +extern void m68k_instr_set(void); +uae_u32 linea68000(uae_u16 opcode); + +/* Opcode of faulting instruction */ +extern uae_u16 last_op_for_exception_3; +/* PC at fault time */ +extern uaecptr last_addr_for_exception_3; +/* Address that generated the exception */ +extern uaecptr last_fault_for_exception_3; + +#define CPU_OP_NAME(a) op ## a + +/* 68040+ 68881 */ +extern const struct cputbl op_smalltbl_0_ff[]; +extern const struct cputbl op_smalltbl_0_nf[]; + +#ifdef FLIGHT_RECORDER +extern void m68k_record_step(uaecptr, int); +#endif + +extern void m68k_do_execute(void); +extern void m68k_execute(void); +#ifdef USE_JIT +extern void m68k_compile_execute(void); +extern void m68k_do_compile_execute(void); +#endif +#ifdef USE_CPU_EMUL_SERVICES +extern int32 emulated_ticks; +extern void cpu_do_check_ticks(void); + +static inline void cpu_check_ticks(void) +{ + if (--emulated_ticks <= 0) + cpu_do_check_ticks(); +} +#else +#define cpu_check_ticks() +#define cpu_do_check_ticks() +#endif + +cpuop_func op_illg_1; + +#endif /* NEWCPU_H */ diff --git a/BasiliskII/src/uae_cpu_2021/readcpu.cpp b/BasiliskII/src/uae_cpu_2021/readcpu.cpp new file mode 100644 index 000000000..742e0be5c --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/readcpu.cpp @@ -0,0 +1,934 @@ +/* 2002 MJ */ +/* + * UAE - The Un*x Amiga Emulator + * + * Read 68000 CPU specs from file "table68k" + * + * Copyright 1995,1996 Bernd Schmidt + */ + +#include "sysdeps.h" +#include "readcpu.h" + +#include +#include +#include +#include + +using std::strncmp; +using std::abort; +using std::fprintf; +using std::strcmp; +using std::strlen; +using std::malloc; + +int nr_cpuop_funcs; +struct instr *table68k; +static int readcpu_mismatch; + +struct mnemolookup lookuptab[] = { + { i_ILLG, "ILLEGAL" }, + { i_OR, "OR" }, + { i_CHK, "CHK" }, + { i_CHK2, "CHK2" }, + { i_AND, "AND" }, + { i_EOR, "EOR" }, + { i_ORSR, "ORSR" }, + { i_ANDSR, "ANDSR" }, + { i_EORSR, "EORSR" }, + { i_SUB, "SUB" }, + { i_SUBA, "SUBA" }, + { i_SUBX, "SUBX" }, + { i_SBCD, "SBCD" }, + { i_ADD, "ADD" }, + { i_ADDA, "ADDA" }, + { i_ADDX, "ADDX" }, + { i_ABCD, "ABCD" }, + { i_NEG, "NEG" }, + { i_NEGX, "NEGX" }, + { i_NBCD, "NBCD" }, + { i_CLR, "CLR" }, + { i_NOT, "NOT" }, + { i_TST, "TST" }, + { i_BTST, "BTST" }, + { i_BCHG, "BCHG" }, + { i_BCLR, "BCLR" }, + { i_BSET, "BSET" }, + { i_CMP, "CMP" }, + { i_CMPM, "CMPM" }, + { i_CMPA, "CMPA" }, + { i_MVPRM, "MVPRM" }, + { i_MVPMR, "MVPMR" }, + { i_MOVE, "MOVE" }, + { i_MOVEA, "MOVEA" }, + { i_MVSR2, "MVSR2" }, + { i_MV2SR, "MV2SR" }, + { i_SWAP, "SWAP" }, + { i_EXG, "EXG" }, + { i_EXT, "EXT" }, + { i_MVMEL, "MVMEL" }, + { i_MVMLE, "MVMLE" }, + { i_TRAP, "TRAP" }, + { i_MVR2USP, "MVR2USP" }, + { i_MVUSP2R, "MVUSP2R" }, + { i_NOP, "NOP" }, + { i_RESET, "RESET" }, + { i_RTE, "RTE" }, + { i_RTD, "RTD" }, + { i_LINK, "LINK" }, + { i_UNLK, "UNLK" }, + { i_RTS, "RTS" }, + { i_STOP, "STOP" }, + { i_TRAPV, "TRAPV" }, + { i_RTR, "RTR" }, + { i_JSR, "JSR" }, + { i_JMP, "JMP" }, + { i_BSR, "BSR" }, + { i_Bcc, "Bcc" }, + { i_LEA, "LEA" }, + { i_PEA, "PEA" }, + { i_DBcc, "DBcc" }, + { i_Scc, "Scc" }, + { i_DIVU, "DIVU" }, + { i_DIVS, "DIVS" }, + { i_MULU, "MULU" }, + { i_MULS, "MULS" }, + { i_ASR, "ASR" }, + { i_ASL, "ASL" }, + { i_LSR, "LSR" }, + { i_LSL, "LSL" }, + { i_ROL, "ROL" }, + { i_ROR, "ROR" }, + { i_ROXL, "ROXL" }, + { i_ROXR, "ROXR" }, + { i_ASRW, "ASRW" }, + { i_ASLW, "ASLW" }, + { i_LSRW, "LSRW" }, + { i_LSLW, "LSLW" }, + { i_ROLW, "ROLW" }, + { i_RORW, "RORW" }, + { i_ROXLW, "ROXLW" }, + { i_ROXRW, "ROXRW" }, + + { i_MOVE2C, "MOVE2C" }, + { i_MOVEC2, "MOVEC2" }, + { i_CAS, "CAS" }, + { i_CAS2, "CAS2" }, + { i_MULL, "MULL" }, + { i_DIVL, "DIVL" }, + { i_BFTST, "BFTST" }, + { i_BFEXTU, "BFEXTU" }, + { i_BFCHG, "BFCHG" }, + { i_BFEXTS, "BFEXTS" }, + { i_BFCLR, "BFCLR" }, + { i_BFFFO, "BFFFO" }, + { i_BFSET, "BFSET" }, + { i_BFINS, "BFINS" }, + { i_PACK, "PACK" }, + { i_UNPK, "UNPK" }, + { i_TAS, "TAS" }, + { i_BKPT, "BKPT" }, + { i_CALLM, "CALLM" }, + { i_RTM, "RTM" }, + { i_TRAPcc, "TRAPcc" }, + { i_MOVES, "MOVES" }, + { i_FPP, "FPP" }, + { i_FDBcc, "FDBcc" }, + { i_FScc, "FScc" }, + { i_FTRAPcc, "FTRAPcc" }, + { i_FBcc, "FBcc" }, + { i_FBcc, "FBcc" }, + { i_FSAVE, "FSAVE" }, + { i_FRESTORE, "FRESTORE" }, + + { i_CINVL, "CINVL" }, + { i_CINVP, "CINVP" }, + { i_CINVA, "CINVA" }, + { i_CPUSHL, "CPUSHL" }, + { i_CPUSHP, "CPUSHP" }, + { i_CPUSHA, "CPUSHA" }, + { i_MOVE16, "MOVE16" }, + + { i_EMULOP_RETURN, "EMULOP_RETURN" }, + { i_EMULOP, "EMULOP" }, + + { i_MMUOP, "MMUOP" }, + + {i_NATFEAT_ID, "NATFEAT_ID" }, + {i_NATFEAT_CALL, "NATFEAT_CALL" }, + + { i_ILLG, "" }, +}; + + +static inline amodes mode_from_str (const char *str) +{ + if (strncmp (str, "Dreg", 4) == 0) return Dreg; + if (strncmp (str, "Areg", 4) == 0) return Areg; + if (strncmp (str, "Aind", 4) == 0) return Aind; + if (strncmp (str, "Apdi", 4) == 0) return Apdi; + if (strncmp (str, "Aipi", 4) == 0) return Aipi; + if (strncmp (str, "Ad16", 4) == 0) return Ad16; + if (strncmp (str, "Ad8r", 4) == 0) return Ad8r; + if (strncmp (str, "absw", 4) == 0) return absw; + if (strncmp (str, "absl", 4) == 0) return absl; + if (strncmp (str, "PC16", 4) == 0) return PC16; + if (strncmp (str, "PC8r", 4) == 0) return PC8r; + if (strncmp (str, "Immd", 4) == 0) return imm; + abort (); + return (amodes)0; +} + +static inline amodes mode_from_mr (int mode, int reg) +{ + switch (mode) { + case 0: return Dreg; + case 1: return Areg; + case 2: return Aind; + case 3: return Aipi; + case 4: return Apdi; + case 5: return Ad16; + case 6: return Ad8r; + case 7: + switch (reg) { + case 0: return absw; + case 1: return absl; + case 2: return PC16; + case 3: return PC8r; + case 4: return imm; + case 5: + case 6: + case 7: return am_illg; + } + } + abort (); + return (amodes)0; +} + +static void build_insn (int insn) +{ + int find = -1; + int variants; + struct instr_def id; + const char *opcstr; + int i, n; + + int flaglive = 0, flagdead = 0; + int cflow = 0; + + id = defs68k[insn]; + + // Control flow information + cflow = id.cflow; + + // Mask of flags set/used + unsigned char flags_set(0), flags_used(0); + + for (i = 0, n = 4; i < 5; i++, n--) { + switch (id.flaginfo[i].flagset) { + case fa_unset: case fa_isjmp: break; + default: flags_set |= (1 << n); + } + + switch (id.flaginfo[i].flaguse) { + case fu_unused: case fu_isjmp: break; + default: flags_used |= (1 << n); + } + } + + for (i = 0; i < 5; i++) { + switch (id.flaginfo[i].flagset){ + case fa_unset: break; + case fa_isjmp: break; + case fa_zero: flagdead |= 1 << i; break; + case fa_one: flagdead |= 1 << i; break; + case fa_dontcare: flagdead |= 1 << i; break; + case fa_unknown: flagdead = -1; goto out1; + case fa_set: flagdead |= 1 << i; break; + } + } + + out1: + for (i = 0; i < 5; i++) { + switch (id.flaginfo[i].flaguse) { + case fu_unused: break; + case fu_isjmp: flaglive |= 1 << i; break; + case fu_maybecc: flaglive |= 1 << i; break; + case fu_unknown: flaglive = -1; goto out2; + case fu_used: flaglive |= 1 << i; break; + } + } + out2: + + opcstr = id.opcstr; + for (variants = 0; variants < (1 << id.n_variable); variants++) { + int bitcnt[lastbit]; + int bitval[lastbit]; + int bitpos[lastbit]; + int i; + uae_u16 opc = id.bits; + uae_u16 msk, vmsk; + int pos = 0; + int mnp = 0; + int bitno = 0; + char mnemonic[64]; + + wordsizes sz = sz_long; + int srcgather = 0, dstgather = 0; + int usesrc = 0, usedst = 0; + int srctype = 0; + int srcpos = -1, dstpos = -1; + + amodes srcmode = am_unknown, destmode = am_unknown; + int srcreg = -1, destreg = -1; + + for (i = 0; i < lastbit; i++) + bitcnt[i] = bitval[i] = 0; + + vmsk = 1 << id.n_variable; + + for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { + if (!(msk & id.mask)) { + int currbit = id.bitpos[bitno++]; + int bit_set; + vmsk >>= 1; + bit_set = variants & vmsk ? 1 : 0; + if (bit_set) + opc |= msk; + bitpos[currbit] = 15 - i; + bitcnt[currbit]++; + bitval[currbit] <<= 1; + bitval[currbit] |= bit_set; + } + } + + if (bitval[bitj] == 0) bitval[bitj] = 8; + /* first check whether this one does not match after all */ + if (bitval[bitz] == 3 || bitval[bitC] == 1) + continue; + if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) + continue; + + if (bitcnt[bitE] && (bitval[bitE] == 0x00)) + continue; + + /* bitI and bitC get copied to biti and bitc */ + if (bitcnt[bitI]) { + bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; + } + if (bitcnt[bitC]) + bitval[bitc] = bitval[bitC]; + + pos = 0; + while (opcstr[pos] && !isspace(opcstr[pos])) { + if (opcstr[pos] == '.') { + pos++; + switch (opcstr[pos]) { + + case 'B': sz = sz_byte; break; + case 'W': sz = sz_word; break; + case 'L': sz = sz_long; break; + case 'z': + switch (bitval[bitz]) { + case 0: sz = sz_byte; break; + case 1: sz = sz_word; break; + case 2: sz = sz_long; break; + default: abort(); + } + break; + default: abort(); + } + } else { + mnemonic[mnp] = opcstr[pos]; + if (mnemonic[mnp] == 'f') { + find = -1; + switch (bitval[bitf]) { + case 0: mnemonic[mnp] = 'R'; break; + case 1: mnemonic[mnp] = 'L'; break; + default: abort(); + } + } + mnp++; + if ((unsigned)mnp >= (sizeof(mnemonic)-1)) { + mnemonic[sizeof(mnemonic)-1] = '\0'; + fprintf(stderr, "WTF!!! Instruction '%s' overflow\n", mnemonic); + abort(); + } + } + pos++; + } + mnemonic[mnp] = 0; + + /* now, we have read the mnemonic and the size */ + while (opcstr[pos] && isspace(opcstr[pos])) + pos++; + + /* A goto a day keeps the D******a away. */ + if (opcstr[pos] == 0) + goto endofline; + + /* parse the source address */ + usesrc = 1; + switch (opcstr[pos++]) { + case 'D': + srcmode = Dreg; + switch (opcstr[pos++]) { + case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; + case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; + default: abort(); + } + + break; + case 'A': + srcmode = Areg; + switch (opcstr[pos++]) { + case 'l': srcmode = absl; break; + case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; + case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; + default: abort(); + } + switch (opcstr[pos]) { + case 'p': srcmode = Apdi; pos++; break; + case 'P': srcmode = Aipi; pos++; break; + } + break; +#if 0 + case 'L': + srcmode = absl; + break; +#endif + case '#': + switch (opcstr[pos++]) { + case 'z': srcmode = imm; break; + case '0': srcmode = imm0; break; + case '1': srcmode = imm1; break; + case '2': srcmode = imm2; break; + case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; + if (CPU_EMU_SIZE < 4) { + /* Used for branch instructions */ + srctype = 1; + srcgather = 1; + srcpos = bitpos[biti]; + } + break; + case 'j': srcmode = immi; srcreg = bitval[bitj]; + if (CPU_EMU_SIZE < 3) { + /* 1..8 for ADDQ/SUBQ and rotshi insns */ + srcgather = 1; + srctype = 3; + srcpos = bitpos[bitj]; + } + break; + case 'J': srcmode = immi; srcreg = bitval[bitJ]; + if (CPU_EMU_SIZE < 5) { + /* 0..15 */ + srcgather = 1; + srctype = 2; + srcpos = bitpos[bitJ]; + } + break; + case 'k': srcmode = immi; srcreg = bitval[bitk]; + if (CPU_EMU_SIZE < 3) { + srcgather = 1; + srctype = 4; + srcpos = bitpos[bitk]; + } + break; + case 'K': srcmode = immi; srcreg = bitval[bitK]; + if (CPU_EMU_SIZE < 5) { + /* 0..15 */ + srcgather = 1; + srctype = 5; + srcpos = bitpos[bitK]; + } + break; + case 'E': srcmode = immi; srcreg = bitval[bitE]; + if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ?? + /* 1..255 */ + srcgather = 1; + srctype = 6; + srcpos = bitpos[bitE]; + } + break; + case 'p': srcmode = immi; srcreg = bitval[bitp]; + if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ?? + /* 0..3 */ + srcgather = 1; + srctype = 7; + srcpos = bitpos[bitp]; + } + break; + default: abort(); + } + break; + case 'd': + srcreg = bitval[bitD]; + srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); + if (srcmode == am_illg) + continue; + if (CPU_EMU_SIZE < 2 && + (srcmode == Areg || srcmode == Dreg || srcmode == Aind + || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi + || srcmode == Apdi)) + { + srcgather = 1; srcpos = bitpos[bitD]; + } + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == srcmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == srcmode) + srcmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != srcmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + break; + } + } + } + /* Some addressing modes are invalid as destination */ + if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) + goto nomatch; + break; + case 's': + srcreg = bitval[bitS]; + srcmode = mode_from_mr(bitval[bits],bitval[bitS]); + + if (srcmode == am_illg) + continue; + if (CPU_EMU_SIZE < 2 && + (srcmode == Areg || srcmode == Dreg || srcmode == Aind + || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi + || srcmode == Apdi)) + { + srcgather = 1; srcpos = bitpos[bitS]; + } + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == srcmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == srcmode) + srcmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != srcmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + } + } + } + break; + default: abort(); + } + /* safety check - might have changed */ + if (srcmode != Areg && srcmode != Dreg && srcmode != Aind + && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi + && srcmode != Apdi && srcmode != immi) + { + srcgather = 0; + } + if (srcmode == Areg && sz == sz_byte) + goto nomatch; + + if (opcstr[pos] != ',') + goto endofline; + pos++; + + /* parse the destination address */ + usedst = 1; + switch (opcstr[pos++]) { + case 'D': + destmode = Dreg; + switch (opcstr[pos++]) { + case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; + case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + default: abort(); + } + if (dstpos < 0 || dstpos >= 32) + abort(); + break; + case 'A': + destmode = Areg; + switch (opcstr[pos++]) { + case 'l': destmode = absl; break; + case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; + case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; + default: abort(); + } + switch (opcstr[pos]) { + case 'p': destmode = Apdi; pos++; break; + case 'P': destmode = Aipi; pos++; break; + } + break; +#if 0 + case 'L': + destmode = absl; + break; +#endif + case '#': + switch (opcstr[pos++]) { + case 'z': destmode = imm; break; + case '0': destmode = imm0; break; + case '1': destmode = imm1; break; + case '2': destmode = imm2; break; + case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; + case 'j': destmode = immi; destreg = bitval[bitj]; break; + case 'J': destmode = immi; destreg = bitval[bitJ]; break; + case 'k': destmode = immi; destreg = bitval[bitk]; break; + case 'K': destmode = immi; destreg = bitval[bitK]; break; + default: abort(); + } + break; + case 'd': + destreg = bitval[bitD]; + destmode = mode_from_mr(bitval[bitd],bitval[bitD]); + if (destmode == am_illg) + continue; + if (CPU_EMU_SIZE < 1 && + (destmode == Areg || destmode == Dreg || destmode == Aind + || destmode == Ad16 || destmode == Ad8r || destmode == Aipi + || destmode == Apdi)) + { + dstgather = 1; dstpos = bitpos[bitD]; + } + + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == destmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == destmode) + destmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != destmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + break; + } + } + } + /* Some addressing modes are invalid as destination */ + if (destmode == imm || destmode == PC16 || destmode == PC8r) + goto nomatch; + break; + case 's': + destreg = bitval[bitS]; + destmode = mode_from_mr(bitval[bits],bitval[bitS]); + + if (destmode == am_illg) + continue; + if (CPU_EMU_SIZE < 1 && + (destmode == Areg || destmode == Dreg || destmode == Aind + || destmode == Ad16 || destmode == Ad8r || destmode == Aipi + || destmode == Apdi)) + { + dstgather = 1; dstpos = bitpos[bitS]; + } + + if (opcstr[pos] == '[') { + pos++; + if (opcstr[pos] == '!') { + /* exclusion */ + do { + pos++; + if (mode_from_str(opcstr+pos) == destmode) + goto nomatch; + pos += 4; + } while (opcstr[pos] == ','); + pos++; + } else { + if (opcstr[pos+4] == '-') { + /* replacement */ + if (mode_from_str(opcstr+pos) == destmode) + destmode = mode_from_str(opcstr+pos+5); + else + goto nomatch; + pos += 10; + } else { + /* normal */ + while(mode_from_str(opcstr+pos) != destmode) { + pos += 4; + if (opcstr[pos] == ']') + goto nomatch; + pos++; + } + while(opcstr[pos] != ']') pos++; + pos++; + } + } + } + break; + default: abort(); + } + /* safety check - might have changed */ + if (destmode != Areg && destmode != Dreg && destmode != Aind + && destmode != Ad16 && destmode != Ad8r && destmode != Aipi + && destmode != Apdi) + { + dstgather = 0; + } + + if (destmode == Areg && sz == sz_byte) + goto nomatch; +#if 0 + if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { + dstgather = 0; + } +#endif + endofline: + /* now, we have a match */ + if (table68k[opc].mnemo != i_ILLG) + fprintf(stderr, "Double match: %x: %s\n", opc, opcstr); + if (find == -1) { + for (find = 0;; find++) { + if (strcmp(mnemonic, lookuptab[find].name) == 0) { + table68k[opc].mnemo = lookuptab[find].mnemo; + break; + } + if (strlen(lookuptab[find].name) == 0) abort(); + } + } + else { + table68k[opc].mnemo = lookuptab[find].mnemo; + } + table68k[opc].cc = bitval[bitc]; + if (table68k[opc].mnemo == i_BTST + || table68k[opc].mnemo == i_BSET + || table68k[opc].mnemo == i_BCLR + || table68k[opc].mnemo == i_BCHG) + { + sz = destmode == Dreg ? sz_long : sz_byte; + } + table68k[opc].size = sz; + table68k[opc].sreg = srcreg; + table68k[opc].dreg = destreg; + table68k[opc].smode = srcmode; + table68k[opc].dmode = destmode; + table68k[opc].spos = srcgather ? srcpos : -1; + table68k[opc].dpos = dstgather ? dstpos : -1; + table68k[opc].suse = usesrc; + table68k[opc].duse = usedst; + table68k[opc].stype = srctype; + table68k[opc].plev = id.plevel; + table68k[opc].clev = id.cpulevel; +#if 0 + for (i = 0; i < 5; i++) { + table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; + table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; + } +#endif + + // Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions + if ( table68k[opc].mnemo == i_Scc + || table68k[opc].mnemo == i_Bcc + || table68k[opc].mnemo == i_DBcc + || table68k[opc].mnemo == i_TRAPcc + ) { + switch (table68k[opc].cc) { + // CC mask: XNZVC + // 8421 + case 0: flags_used = 0x00; break; /* T */ + case 1: flags_used = 0x00; break; /* F */ + case 2: flags_used = 0x05; break; /* HI */ + case 3: flags_used = 0x05; break; /* LS */ + case 4: flags_used = 0x01; break; /* CC */ + case 5: flags_used = 0x01; break; /* CS */ + case 6: flags_used = 0x04; break; /* NE */ + case 7: flags_used = 0x04; break; /* EQ */ + case 8: flags_used = 0x02; break; /* VC */ + case 9: flags_used = 0x02; break; /* VS */ + case 10:flags_used = 0x08; break; /* PL */ + case 11:flags_used = 0x08; break; /* MI */ + case 12:flags_used = 0x0A; break; /* GE */ + case 13:flags_used = 0x0A; break; /* LT */ + case 14:flags_used = 0x0E; break; /* GT */ + case 15:flags_used = 0x0E; break; /* LE */ + } + } + +#if 1 + /* gb-- flagdead and flaglive would not have correct information */ + table68k[opc].flagdead = flags_set; + table68k[opc].flaglive = flags_used; +#else + table68k[opc].flagdead = flagdead; + table68k[opc].flaglive = flaglive; +#endif + table68k[opc].cflow = cflow; + nomatch: + /* FOO! */; + } +} + + +static void handle_merges (long int opcode) +{ + uae_u16 smsk; + uae_u16 dmsk; + int sbitdst, dstend; + int srcreg, dstreg; + + if (table68k[opcode].spos == -1) { + sbitdst = 1; smsk = 0; + } else { + switch (table68k[opcode].stype) { + case 0: + smsk = 7; sbitdst = 8; break; + case 1: + smsk = 255; sbitdst = 256; break; + case 2: + smsk = 15; sbitdst = 16; break; + case 3: + smsk = 7; sbitdst = 8; break; + case 4: + smsk = 7; sbitdst = 8; break; + case 5: + smsk = 63; sbitdst = 64; break; + case 6: + smsk = 255; sbitdst = 256; break; + case 7: + smsk = 3; sbitdst = 4; break; + default: + smsk = 0; sbitdst = 0; + abort(); + break; + } + smsk <<= table68k[opcode].spos; + } + if (table68k[opcode].dpos == -1) { + dstend = 1; dmsk = 0; + } else { + dmsk = 7 << table68k[opcode].dpos; + dstend = 8; + } + for (srcreg=0; srcreg < sbitdst; srcreg++) { + for (dstreg=0; dstreg < dstend; dstreg++) { + uae_u16 code = opcode; + + code = (code & ~smsk) | (srcreg << table68k[opcode].spos); + code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); + + /* Check whether this is in fact the same instruction. + * The instructions should never differ, except for the + * Bcc.(BW) case. */ + if (table68k[code].mnemo != table68k[opcode].mnemo + || table68k[code].size != table68k[opcode].size + || table68k[code].suse != table68k[opcode].suse + || table68k[code].duse != table68k[opcode].duse) + { + readcpu_mismatch++; continue; + } + if (table68k[opcode].suse + && (table68k[opcode].spos != table68k[code].spos + || table68k[opcode].smode != table68k[code].smode + || table68k[opcode].stype != table68k[code].stype)) + { + readcpu_mismatch++; continue; + } + if (table68k[opcode].duse + && (table68k[opcode].dpos != table68k[code].dpos + || table68k[opcode].dmode != table68k[code].dmode)) + { + readcpu_mismatch++; continue; + } + + if (code != opcode) + table68k[code].handler = opcode; + } + } +} + +static void do_merges (void) +{ + long int opcode; + int nr = 0; + readcpu_mismatch = 0; + for (opcode = 0; opcode < 65536; opcode++) { + if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) + continue; + nr++; + handle_merges (opcode); + } + nr_cpuop_funcs = nr; +} + + +void init_table68k (void) +{ + int i; + + free(table68k); + table68k = (struct instr *)malloc (65536 * sizeof (struct instr)); + for (i = 0; i < 65536; i++) { + table68k[i].mnemo = i_ILLG; + table68k[i].handler = -1; + } + for (i = 0; i < n_defs68k; i++) { + build_insn (i); + } + do_merges(); +} + + +void exit_table68k (void) +{ + free(table68k); + table68k = NULL; +} diff --git a/BasiliskII/src/uae_cpu_2021/readcpu.h b/BasiliskII/src/uae_cpu_2021/readcpu.h new file mode 100644 index 000000000..3bdc0cd60 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/readcpu.h @@ -0,0 +1,125 @@ +#ifndef UAE_READCPU_H +#define UAE_READCPU_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, + absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg +} amodes; + +typedef enum { + i_ILLG, + + i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR, + i_SUB, i_SUBA, i_SUBX, i_SBCD, + i_ADD, i_ADDA, i_ADDX, i_ABCD, + i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST, + i_BTST, i_BCHG, i_BCLR, i_BSET, + i_CMP, i_CMPM, i_CMPA, + i_MVPRM, i_MVPMR, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR, + i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE, + i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD, + i_LINK, i_UNLK, + i_RTS, i_TRAPV, i_RTR, + i_JSR, i_JMP, i_BSR, i_Bcc, + i_LEA, i_PEA, i_DBcc, i_Scc, + i_DIVU, i_DIVS, i_MULU, i_MULS, + i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR, + i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW, + i_CHK,i_CHK2, + i_MOVEC2, i_MOVE2C, i_CAS, i_CAS2, i_DIVL, i_MULL, + i_BFTST,i_BFEXTU,i_BFCHG,i_BFEXTS,i_BFCLR,i_BFFFO,i_BFSET,i_BFINS, + i_PACK, i_UNPK, i_TAS, i_BKPT, i_CALLM, i_RTM, i_TRAPcc, i_MOVES, + i_FPP, i_FDBcc, i_FScc, i_FTRAPcc, i_FBcc, i_FSAVE, i_FRESTORE, + i_CINVL, i_CINVP, i_CINVA, i_CPUSHL, i_CPUSHP, i_CPUSHA, i_MOVE16, + i_MMUOP, i_EMULOP_RETURN, i_EMULOP, i_NATFEAT_ID, i_NATFEAT_CALL +} instrmnem; + +extern struct mnemolookup { + instrmnem mnemo; + const char *name; +} lookuptab[]; + +typedef enum { + sz_byte, sz_word, sz_long +} wordsizes; + +typedef enum { + fa_set, fa_unset, fa_zero, fa_one, fa_dontcare, fa_unknown, fa_isjmp, + fa_isbranch +} flagaffect; + +typedef enum { + fu_used, fu_unused, fu_maybecc, fu_unknown, fu_isjmp +} flaguse; + +typedef enum { + fl_normal = 0, + fl_branch = 1, + fl_jump = 2, + fl_return = 3, + fl_trap = 4, + fl_const_jump = 8, + /* Instructions that can trap don't mark the end of a block */ + fl_end_block = 3 +} cflow_t; + +typedef enum { + bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bitk, bitK, + bits, bitS, bitd, bitD, bitr, bitR, bitz, bitE, bitp, lastbit +} bitvals; + +struct instr_def { + unsigned int bits; + int n_variable; + char bitpos[16]; + unsigned int mask; + int cpulevel; + int plevel; + struct { + unsigned int flaguse:3; + unsigned int flagset:3; + } flaginfo[5]; + unsigned char cflow; + unsigned char sduse; + const char *opcstr; +}; + +extern struct instr_def defs68k[]; +extern int n_defs68k; + +extern struct instr { + long int handler; + unsigned char dreg; + unsigned char sreg; + signed char dpos; + signed char spos; + unsigned char sduse; + int flagdead:8, flaglive:8; + unsigned int mnemo:8; + unsigned int cc:4; + unsigned int plev:2; + wordsizes size:2; + amodes smode:5; + unsigned int stype:3; + amodes dmode:5; + unsigned int suse:1; + unsigned int duse:1; + unsigned int unused1:1; + unsigned int clev:3; + unsigned int cflow:3; + unsigned int unused2:2; +} *table68k; + +extern void init_table68k(void); +extern void exit_table68k(void); +extern int nr_cpuop_funcs; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/registers.h b/BasiliskII/src/uae_cpu_2021/registers.h new file mode 100644 index 000000000..16f670926 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/registers.h @@ -0,0 +1,115 @@ +/* 2001 MJ */ + +#ifndef REGISTERS_H +#define REGISTERS_H + +#include "sysdeps.h" +#include "spcflags.h" +typedef char flagtype; + + +struct xttrx { + uae_u32 log_addr_base : 8; + uae_u32 log_addr_mask : 8; + uae_u32 enable : 1; + uae_u32 s_field : 2; + uae_u32 : 3; + uae_u32 usr1 : 1; + uae_u32 usr0 : 1; + uae_u32 : 1; + uae_u32 cmode : 2; + uae_u32 : 2; + uae_u32 write : 1; + uae_u32 : 2; +}; + +struct mmusr_t { + uae_u32 phys_addr : 20; + uae_u32 bus_err : 1; + uae_u32 global : 1; + uae_u32 usr1 : 1; + uae_u32 usr0 : 1; + uae_u32 super : 1; + uae_u32 cmode : 2; + uae_u32 modif : 1; + uae_u32 : 1; + uae_u32 write : 1; + uae_u32 ttrhit : 1; + uae_u32 resident : 1; +}; + +struct log_addr4 { + uae_u32 rif : 7; + uae_u32 pif : 7; + uae_u32 paif : 6; + uae_u32 poff : 12; +}; + +struct log_addr8 { + uae_u32 rif : 7; + uae_u32 pif : 7; + uae_u32 paif : 5; + uae_u32 poff : 13; +}; + +extern struct regstruct +{ + uae_u32 regs[16]; + uaecptr usp,isp,msp; + uae_u16 sr; + flagtype t1; + flagtype t0; + flagtype s; + flagtype m; + flagtype stopped; + uint32_t intmask; + + uae_u32 pc; + uae_u32 fault_pc; + uae_u8 *pc_p; + uae_u8 *pc_oldp; + + uae_u32 vbr,sfc,dfc; + + volatile uae_u32 spcflags; + +#if 0 + uae_u32 kick_mask; + + /* Fellow sources say this is 4 longwords. That's impossible. It needs + * to be at least a longword. The HRM has some cryptic comment about two + * instructions being on the same longword boundary. + * The way this is implemented now seems like a good compromise. + */ + uae_u32 prefetch; +#endif + + /* MMU reg*/ + uae_u32 urp,srp; + uae_u32 tc; + + int mmu_enabled; /* flagtype tce; */ + int mmu_pagesize_8k; /* flagtype tcp; */ + + uae_u32 dtt0,dtt1,itt0,itt1; + uae_u32 mmusr; + + uae_u32 mmu_fslw, mmu_fault_addr; + uae_u16 mmu_ssw; + uae_u32 wb3_data; + uae_u16 wb3_status; + + /* Cache reg*/ + uae_u32 cacr,caar; +} regs; + +static inline uaecptr m68k_getpc (void) +{ +#ifdef FULLMMU + return regs.pc; +#else + return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp); +#endif +} + +#endif diff --git a/BasiliskII/src/uae_cpu_2021/spcflags.h b/BasiliskII/src/uae_cpu_2021/spcflags.h new file mode 100644 index 000000000..eb465e727 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/spcflags.h @@ -0,0 +1,175 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * MC68000 emulation + * + * Copyright 1995 Bernd Schmidt + */ + +#ifndef SPCFLAGS_H +#define SPCFLAGS_H + +#if 0 +#include "SDL_compat.h" +#endif + +enum { + SPCFLAG_STOP = 0x01, +#if 0 + SPCFLAG_INTERNAL_IRQ = 0x02, +#else + SPCFLAG_INT = 0x02, +#endif + SPCFLAG_BRK = 0x04, + SPCFLAG_TRACE = 0x08, + SPCFLAG_DOTRACE = 0x10, + SPCFLAG_DOINT = 0x20, +#ifdef USE_JIT + SPCFLAG_JIT_END_COMPILE = 0x40, + SPCFLAG_JIT_EXEC_RETURN = 0x80, +#else + SPCFLAG_JIT_END_COMPILE = 0, + SPCFLAG_JIT_EXEC_RETURN = 0, +#endif + SPCFLAG_VBL = 0x100, + SPCFLAG_MFP = 0x200, + SPCFLAG_INT3 = 0x800, + SPCFLAG_INT5 = 0x1000, + SPCFLAG_SCC = 0x2000, +// SPCFLAG_MODE_CHANGE = 0x4000, + SPCFLAG_ALL = SPCFLAG_STOP +#if 0 + | SPCFLAG_INTERNAL_IRQ +#else + | SPCFLAG_INT +#endif + | SPCFLAG_BRK + | SPCFLAG_TRACE + | SPCFLAG_DOTRACE + | SPCFLAG_DOINT + | SPCFLAG_JIT_END_COMPILE + | SPCFLAG_JIT_EXEC_RETURN + | SPCFLAG_INT3 + | SPCFLAG_VBL + | SPCFLAG_INT5 + | SPCFLAG_SCC + | SPCFLAG_MFP + , + + SPCFLAG_ALL_BUT_EXEC_RETURN = SPCFLAG_ALL & ~SPCFLAG_JIT_EXEC_RETURN + +}; + +#if 0 +#define SPCFLAGS_TEST(m) \ + (regs.spcflags & (m)) +#else +#define SPCFLAGS_TEST(m) \ + ((regs.spcflags & (m)) != 0) +#endif + +/* Macro only used in m68k_reset() */ +#define SPCFLAGS_INIT(m) do { \ + regs.spcflags = (m); \ +} while (0) + +#include "main.h" +extern B2_mutex *spcflags_lock; + +#define SPCFLAGS_SET(m) do { \ + B2_lock_mutex(spcflags_lock); \ + regs.spcflags |= (m); \ + B2_unlock_mutex(spcflags_lock); \ +} while (0) + +#define SPCFLAGS_CLEAR(m) do { \ + B2_lock_mutex(spcflags_lock); \ + regs.spcflags &= ~(m); \ + B2_unlock_mutex(spcflags_lock); \ +} while (0) + +#define SleepAndWait() usleep(1000); + +#if 0 +#ifndef ENABLE_EXCLUSIVE_SPCFLAGS + +#define SPCFLAGS_SET(m) do { \ + regs.spcflags |= (m); \ +} while (0) + +#define SPCFLAGS_CLEAR(m) do { \ + regs.spcflags &= ~(m); \ +} while (0) + +#if 0 +#define SleepAndWait() usleep(1000) +#endif + +#elif defined(X86_ASSEMBLY) +// #elif (defined(CPU_i386) || defined(CPU_x86_64)) && defined(X86_ASSEMBLY) && !defined(ENABLE_REALSTOP) + +// #define HAVE_HARDWARE_LOCKS 1 +#define HAVE_HARDWARE_LOCKS + +#define SPCFLAGS_SET(m) do { \ + __asm__ __volatile__("lock\n\torl %1,%0" : "=m" (regs.spcflags) : "i" ((m))); \ +} while (0) + +#define SPCFLAGS_CLEAR(m) do { \ + __asm__ __volatile__("lock\n\tandl %1,%0" : "=m" (regs.spcflags) : "i" (~(m))); \ +} while (0) + +// #define SleepAndWait() usleep(1000) + +// #elif !defined(ENABLE_REALSTOP) + +// #undef HAVE_HARDWARE_LOCKS +// extern SDL_mutex *spcflags_lock; + +// #define SPCFLAGS_SET(m) do { \ +// SDL_LockMutex(spcflags_lock); \ +// regs.spcflags |= (m); \ +// SDL_UnlockMutex(spcflags_lock); \ +// } while (0) + +// #define SPCFLAGS_CLEAR(m) do { \ +// SDL_LockMutex(spcflags_lock); \ +// regs.spcflags &= ~(m); \ +// SDL_UnlockMutex(spcflags_lock); \ +// } while (0) + +// #define SleepAndWait() usleep(1000) + +#else +/// Full STOP instruction implementation (default configuration) + +#undef HAVE_HARDWARE_LOCKS +#if 0 +extern SDL_mutex *spcflags_lock; +extern SDL_cond *stop_condition; + +#define SPCFLAGS_SET(m) do { \ + SDL_LockMutex(spcflags_lock); \ + regs.spcflags |= (m); \ + if (regs.spcflags & SPCFLAG_STOP) \ + SDL_CondSignal(stop_condition); \ + SDL_UnlockMutex(spcflags_lock); \ +} while (0) + +#define SPCFLAGS_CLEAR(m) do { \ + SDL_LockMutex(spcflags_lock); \ + regs.spcflags &= ~(m); \ + SDL_UnlockMutex(spcflags_lock); \ +} while (0) + +#define SleepAndWait() do { \ + SDL_LockMutex(spcflags_lock); \ + SDL_CondWait(stop_condition, spcflags_lock); \ + SDL_UnlockMutex(spcflags_lock); \ +} while (0) +#endif + +#endif +#endif + +#endif /* SPCFLAGS_H */ diff --git a/BasiliskII/src/uae_cpu_2021/table68k b/BasiliskII/src/uae_cpu_2021/table68k new file mode 100644 index 000000000..7405bd310 --- /dev/null +++ b/BasiliskII/src/uae_cpu_2021/table68k @@ -0,0 +1,287 @@ +% 0: bit 0 +% 1: bit 1 +% c: condition code +% C: condition codes, except F +% f: direction +% i: immediate +% E: immediate, except 00 (for EmulOp instructions) +% I: immediate, except 00 and ff +% j: immediate 1..8 +% J: immediate 0..15 +% k: immediate 0..7 +% K: immediate 0..63 +% p: immediate 0..3 (CINV and CPUSH: cache field) +% s: source mode +% S: source reg +% d: dest mode +% D: dest reg +% r: reg +% z: size +% +% Actually, a sssSSS may appear as a destination, and +% vice versa. The only difference between sssSSS and +% dddDDD are the valid addressing modes. There is +% no match for immediate and pc-rel. addressing modes +% in case of dddDDD. +% +% Arp: --> -(Ar) +% ArP: --> (Ar)+ +% L: --> (xxx.L) +% +% Fields on a line: +% 16 chars bitpattern : +% CPU level / privildge level : +% CPU level 0: 68000 +% 1: 68010 +% 2: 68020 +% 3: 68020/68881 +% 4: 68040 +% 5: 68060 +% privilege level 0: not privileged +% 1: unprivileged only on 68000 (check regs.s) +% 2: privileged (check regs.s) +% 3: privileged if size == word (check regs.s) +% Flags set by instruction: XNZVC : +% Flags used by instruction: XNZVC : +% - means flag unaffected / unused +% 0 means flag reset +% 1 means flag set +% ? means programmer was too lazy to check or instruction may trap +% + means instruction is conditional branch (ignored, only for sync) +% / means instruction is unconditional branch/call (ignored, only for sync) +% x means flag is unknown and well-behaved programs shouldn't check it +% everything else means flag set/used +% +% Control flow +% two letters, combination of +% - nothing +% T the instruction may trap or cause an exception +% B branch instruction +% J jump instruction +% R return instruction +% +% srcaddr status destaddr status : +% bitmasks of +% 1 means fetched +% 2 means stored +% 4 means jump offset +% 8 means jump address +% instruction +% + +0000 0000 0011 1100:00:XNZVC:XNZVC:--:10: ORSR.B #1 +0000 0000 0111 1100:02:XNZVC:XNZVC:T-:10: ORSR.W #1 +0000 0zz0 11ss sSSS:20:-?Z?C:-----:T-:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] +0000 0000 zzdd dDDD:00:-NZ00:-----:--:13: OR.z #z,d[!Areg] +0000 0010 0011 1100:00:XNZVC:XNZVC:--:10: ANDSR.B #1 +0000 0010 0111 1100:02:XNZVC:XNZVC:T-:10: ANDSR.W #1 +0000 0010 zzdd dDDD:00:-NZ00:-----:--:13: AND.z #z,d[!Areg] +0000 0100 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z #z,d[!Areg] +0000 0110 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z #z,d[!Areg] +0000 0110 11ss sSSS:20:-----:XNZVC:--:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] +0000 0110 11ss sSSS:20:XNZVC:-----:-R:10: RTM s[Dreg,Areg] +0000 1000 00ss sSSS:00:--Z--:-----:--:11: BTST #1,s[!Areg] +0000 1000 01ss sSSS:00:--Z--:-----:--:13: BCHG #1,s[!Areg,Immd] +0000 1000 10ss sSSS:00:--Z--:-----:--:13: BCLR #1,s[!Areg,Immd] +0000 1000 11ss sSSS:00:--Z--:-----:--:13: BSET #1,s[!Areg,Immd] +0000 1010 0011 1100:00:XNZVC:XNZVC:--:10: EORSR.B #1 +0000 1010 0111 1100:02:XNZVC:XNZVC:T-:10: EORSR.W #1 +0000 1010 zzdd dDDD:00:-NZ00:-----:--:13: EOR.z #z,d[!Areg] +0000 1100 zzss sSSS:00:-NZVC:-----:--:11: CMP.z #z,s[!Areg,Immd] + +0000 1010 11ss sSSS:20:-NZVC:-----:--:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1100 11ss sSSS:20:-NZVC:-----:--:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1100 1111 1100:20:-NZVC:-----:--:10: CAS2.W #2 +0000 1110 zzss sSSS:22:-----:-----:T-:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1110 11ss sSSS:20:-NZVC:-----:--:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16] +0000 1110 1111 1100:20:-NZVC:-----:--:10: CAS2.L #2 + +0000 rrr1 00dd dDDD:00:-----:-----:--:12: MVPMR.W d[Areg-Ad16],Dr +0000 rrr1 01dd dDDD:00:-----:-----:--:12: MVPMR.L d[Areg-Ad16],Dr +0000 rrr1 10dd dDDD:00:-----:-----:--:12: MVPRM.W Dr,d[Areg-Ad16] +0000 rrr1 11dd dDDD:00:-----:-----:--:12: MVPRM.L Dr,d[Areg-Ad16] +0000 rrr1 00ss sSSS:00:--Z--:-----:--:11: BTST Dr,s[!Areg] +0000 rrr1 01ss sSSS:00:--Z--:-----:--:13: BCHG Dr,s[!Areg,Immd] +0000 rrr1 10ss sSSS:00:--Z--:-----:--:13: BCLR Dr,s[!Areg,Immd] +0000 rrr1 11ss sSSS:00:--Z--:-----:--:13: BSET Dr,s[!Areg,Immd] + +0001 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.B s,d[!Areg] +0010 DDDd ddss sSSS:00:-----:-----:--:12: MOVEA.L s,d[Areg] +0010 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.L s,d[!Areg] +0011 DDDd ddss sSSS:00:-----:-----:--:12: MOVEA.W s,d[Areg] +0011 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.W s,d[!Areg] + +0100 0000 zzdd dDDD:00:XNZVC:X-Z--:--:30: NEGX.z d[!Areg] +0100 0000 11dd dDDD:01:-----:XNZVC:T-:10: MVSR2.W d[!Areg] +0100 0010 zzdd dDDD:00:-0100:-----:--:20: CLR.z d[!Areg] +0100 0010 11dd dDDD:10:-----:XNZVC:--:10: MVSR2.B d[!Areg] +0100 0100 zzdd dDDD:00:XNZVC:-----:--:30: NEG.z d[!Areg] +0100 0100 11ss sSSS:00:XNZVC:-----:--:10: MV2SR.B s[!Areg] +0100 0110 zzdd dDDD:00:-NZ00:-----:--:30: NOT.z d[!Areg] +0100 0110 11ss sSSS:02:XNZVC:XNZVC:T-:10: MV2SR.W s[!Areg] +0100 1000 0000 1rrr:20:-----:-----:--:31: LINK.L Ar,#2 +0100 1000 00dd dDDD:00:X?Z?C:X-Z--:--:30: NBCD.B d[!Areg] +0100 1000 0100 1kkk:20:-----:-----:T-:10: BKPT #k +0100 1000 01ss sSSS:00:-NZ00:-----:--:30: SWAP.W s[Dreg] +0100 1000 01ss sSSS:00:-----:-----:--:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 1000 10dd dDDD:00:-NZ00:-----:--:30: EXT.W d[Dreg] +0100 1000 10dd dDDD:00:-----:-----:--:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] +0100 1000 11dd dDDD:00:-NZ00:-----:--:30: EXT.L d[Dreg] +0100 1000 11dd dDDD:00:-----:-----:--:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] +0100 1001 11dd dDDD:00:-NZ00:-----:--:30: EXT.B d[Dreg] +0100 1010 zzss sSSS:00:-NZ00:-----:--:10: TST.z s +0100 1010 11dd dDDD:00:-NZ00:-----:--:30: TAS.B d[!Areg] +0100 1010 1111 1100:00:-----:-----:T-:00: ILLEGAL +0100 1100 00ss sSSS:20:-NZVC:-----:--:13: MULL.L #1,s[!Areg] +0100 1100 01ss sSSS:20:-NZV0:-----:T-:13: DIVL.L #1,s[!Areg] +0100 1100 10ss sSSS:00:-----:-----:--:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] +0100 1100 11ss sSSS:00:-----:-----:--:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] +0100 1110 0100 JJJJ:00:-----:XNZVC:--:10: TRAP #J +0100 1110 0101 0rrr:00:-----:-----:--:31: LINK.W Ar,#1 +0100 1110 0101 1rrr:00:-----:-----:--:30: UNLK.L Ar +0100 1110 0110 0rrr:02:-----:-----:T-:10: MVR2USP.L Ar +0100 1110 0110 1rrr:02:-----:-----:T-:20: MVUSP2R.L Ar +0100 1110 0111 0000:02:-----:-----:T-:00: RESET +0100 1110 0111 0001:00:-----:-----:--:00: NOP +0100 1110 0111 0010:02:XNZVC:-----:T-:10: STOP #1 +0100 1110 0111 0011:02:XNZVC:-----:TR:00: RTE +0100 1110 0111 0100:00:-----:-----:-R:10: RTD #1 +0100 1110 0111 0101:00:-----:-----:-R:00: RTS +0100 1110 0111 0110:00:-----:XNZVC:T-:00: TRAPV +0100 1110 0111 0111:00:XNZVC:-----:-R:00: RTR +0100 1110 0111 1010:12:-----:-----:T-:10: MOVEC2 #1 +0100 1110 0111 1011:12:-----:-----:T-:10: MOVE2C #1 +0100 1110 10ss sSSS:00://///://///:-J:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 rrr1 00ss sSSS:00:-N???:-----:T-:11: CHK.L s[!Areg],Dr +0100 rrr1 10ss sSSS:00:-N???:-----:T-:11: CHK.W s[!Areg],Dr +0100 1110 11ss sSSS:00://///://///:-J:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] +0100 rrr1 11ss sSSS:00:-----:-----:--:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar + +% This variant of ADDQ is word and long sized only +0101 jjj0 01dd dDDD:00:-----:-----:--:13: ADDA.W #j,d[Areg] +0101 jjj0 10dd dDDD:00:-----:-----:--:13: ADDA.L #j,d[Areg] +0101 jjj0 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z #j,d[!Areg] + +% This variant of SUBQ is word and long sized only +0101 jjj1 01dd dDDD:00:-----:-----:--:13: SUBA.W #j,d[Areg] +0101 jjj1 10dd dDDD:00:-----:-----:--:13: SUBA.L #j,d[Areg] +0101 jjj1 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z #j,d[!Areg] + +0101 cccc 1100 1rrr:00:-----:-++++:-B:31: DBcc.W Dr,#1 +0101 cccc 11dd dDDD:00:-----:-++++:--:20: Scc.B d[!Areg] +0101 cccc 1111 1010:20:-----:-????:T-:10: TRAPcc #1 +0101 cccc 1111 1011:20:-----:-????:T-:10: TRAPcc #2 +0101 cccc 1111 1100:20:-----:-????:T-:00: TRAPcc + +% Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal +% instruction exceptions when compiling a 68000 only emulation, which isn't +% what we want either. +0110 0001 0000 0000:00://///://///:-B:40: BSR.W #1 +0110 0001 IIII IIII:00://///://///:-B:40: BSR.B #i +0110 0001 1111 1111:00://///://///:-B:40: BSR.L #2 +0110 CCCC 0000 0000:00:-----:-++++:-B:40: Bcc.W #1 +0110 CCCC IIII IIII:00:-----:-++++:-B:40: Bcc.B #i +0110 CCCC 1111 1111:00:-----:-++++:-B:40: Bcc.L #2 + +0111 rrr0 iiii iiii:00:-NZ00:-----:--:12: MOVE.L #i,Dr + +1000 rrr0 zzss sSSS:00:-NZ00:-----:--:13: OR.z s[!Areg],Dr +1000 rrr0 11ss sSSS:00:-NZV0:-----:T-:13: DIVU.W s[!Areg],Dr +1000 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: SBCD.B d[Dreg],Dr +1000 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: SBCD.B d[Areg-Apdi],Arp +1000 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: OR.z Dr,d[!Areg,Dreg] +1000 rrr1 01dd dDDD:20:-----:-----:--:12: PACK d[Dreg],Dr +1000 rrr1 01dd dDDD:20:-----:-----:--:12: PACK d[Areg-Apdi],Arp +1000 rrr1 10dd dDDD:20:-----:-----:--:12: UNPK d[Dreg],Dr +1000 rrr1 10dd dDDD:20:-----:-----:--:12: UNPK d[Areg-Apdi],Arp +1000 rrr1 11ss sSSS:00:-NZV0:-----:T-:13: DIVS.W s[!Areg],Dr + +1001 rrr0 zzss sSSS:00:XNZVC:-----:--:13: SUB.z s,Dr +1001 rrr0 11ss sSSS:00:-----:-----:--:13: SUBA.W s,Ar +1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: SUBX.z d[Dreg],Dr +1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: SUBX.z d[Areg-Apdi],Arp +1001 rrr1 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z Dr,d[!Areg,Dreg] +1001 rrr1 11ss sSSS:00:-----:-----:--:13: SUBA.L s,Ar + +1011 rrr0 zzss sSSS:00:-NZVC:-----:--:11: CMP.z s,Dr +1011 rrr0 11ss sSSS:00:-NZVC:-----:--:11: CMPA.W s,Ar +1011 rrr1 11ss sSSS:00:-NZVC:-----:--:11: CMPA.L s,Ar +1011 rrr1 zzdd dDDD:00:-NZVC:-----:--:11: CMPM.z d[Areg-Aipi],ArP +1011 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: EOR.z Dr,d[!Areg] + +1100 rrr0 zzss sSSS:00:-NZ00:-----:--:13: AND.z s[!Areg],Dr +1100 rrr0 11ss sSSS:00:-NZ00:-----:--:13: MULU.W s[!Areg],Dr +1100 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: ABCD.B d[Dreg],Dr +1100 rrr1 00dd dDDD:00:X?Z?C:X-Z--:--:13: ABCD.B d[Areg-Apdi],Arp +1100 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: AND.z Dr,d[!Areg,Dreg] +1100 rrr1 01dd dDDD:00:-----:-----:--:33: EXG.L Dr,d[Dreg] +1100 rrr1 01dd dDDD:00:-----:-----:--:33: EXG.L Ar,d[Areg] +1100 rrr1 10dd dDDD:00:-----:-----:--:33: EXG.L Dr,d[Areg] +1100 rrr1 11ss sSSS:00:-NZ00:-----:--:13: MULS.W s[!Areg],Dr + +1101 rrr0 zzss sSSS:00:XNZVC:-----:--:13: ADD.z s,Dr +1101 rrr0 11ss sSSS:00:-----:-----:--:13: ADDA.W s,Ar +1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: ADDX.z d[Dreg],Dr +1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: ADDX.z d[Areg-Apdi],Arp +1101 rrr1 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z Dr,d[!Areg,Dreg] +1101 rrr1 11ss sSSS:00:-----:-----:--:13: ADDA.L s,Ar + +1110 jjjf zz00 0RRR:00:XNZVC:-----:--:13: ASf.z #j,DR +1110 jjjf zz00 1RRR:00:XNZ0C:-----:--:13: LSf.z #j,DR +1110 jjjf zz01 0RRR:00:XNZ0C:X----:--:13: ROXf.z #j,DR +1110 jjjf zz01 1RRR:00:-NZ0C:-----:--:13: ROf.z #j,DR +1110 rrrf zz10 0RRR:00:XNZVC:X----:--:13: ASf.z Dr,DR +1110 rrrf zz10 1RRR:00:XNZ0C:X----:--:13: LSf.z Dr,DR +1110 rrrf zz11 0RRR:00:XNZ0C:X----:--:13: ROXf.z Dr,DR +1110 rrrf zz11 1RRR:00:-NZ0C:-----:--:13: ROf.z Dr,DR +1110 000f 11dd dDDD:00:XNZVC:-----:--:13: ASfW.W d[!Dreg,Areg] +1110 001f 11dd dDDD:00:XNZ0C:-----:--:13: LSfW.W d[!Dreg,Areg] +1110 010f 11dd dDDD:00:XNZ0C:X----:--:13: ROXfW.W d[!Dreg,Areg] +1110 011f 11dd dDDD:00:-NZ0C:-----:--:13: ROfW.W d[!Dreg,Areg] + +1110 1000 11ss sSSS:20:-NZ00:-----:--:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd] +1110 1001 11ss sSSS:20:-NZ00:-----:--:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd] +1110 1010 11ss sSSS:20:-NZ00:-----:--:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1011 11ss sSSS:20:-NZ00:-----:--:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd] +1110 1100 11ss sSSS:20:-NZ00:-----:--:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1101 11ss sSSS:20:-NZ00:-----:--:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd] +1110 1110 11ss sSSS:20:-NZ00:-----:--:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] +1110 1111 11ss sSSS:20:-NZ00:-----:--:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] + +% floating point co processor +1111 0010 00ss sSSS:30:-----:-----:--:11: FPP #1,s +1111 0010 01ss sSSS:30:-----:-----:-B:11: FDBcc #1,s[Areg-Dreg] +1111 0010 01ss sSSS:30:-----:-----:--:11: FScc #1,s[!Areg,Immd,PC8r,PC16] +1111 0010 0111 1010:30:-----:-----:T-:10: FTRAPcc #1 +1111 0010 0111 1011:30:-----:-----:T-:10: FTRAPcc #2 +1111 0010 0111 1100:30:-----:-----:T-:00: FTRAPcc +1111 0010 10KK KKKK:30:-----:-----:-B:11: FBcc #K,#1 +1111 0010 11KK KKKK:30:-----:-----:-B:11: FBcc #K,#2 +1111 0011 00ss sSSS:32:-----:-----:--:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16] +1111 0011 01ss sSSS:32:-----:-----:--:10: FRESTORE s[!Dreg,Areg,Apdi,Immd] + +% 68040 instructions +1111 0100 pp00 1rrr:42:-----:-----:T-:02: CINVL #p,Ar +1111 0100 pp01 0rrr:42:-----:-----:T-:02: CINVP #p,Ar +1111 0100 pp01 1rrr:42:-----:-----:T-:00: CINVA #p +1111 0100 pp10 1rrr:42:-----:-----:T-:02: CPUSHL #p,Ar +1111 0100 pp11 0rrr:42:-----:-----:T-:02: CPUSHP #p,Ar +1111 0100 pp11 1rrr:42:-----:-----:T-:00: CPUSHA #p +% destination register number is encoded in the following word +1111 0110 0010 0rrr:40:-----:-----:--:12: MOVE16 ArP,AxP +1111 0110 00ss sSSS:40:-----:-----:--:12: MOVE16 s[Dreg-Aipi],Al +1111 0110 00dd dDDD:40:-----:-----:--:12: MOVE16 Al,d[Areg-Aipi] +1111 0110 00ss sSSS:40:-----:-----:--:12: MOVE16 s[Aind],Al +1111 0110 00dd dDDD:40:-----:-----:--:12: MOVE16 Al,d[Aipi-Aind] + +% MMU disabled +% 1111 0101 iiii iSSS:42:?????:?????:T-:11: MMUOP #i,s + +% EmulOp instructions (used by linux68k) +0111 0001 0000 0000:02:-----:XNZVC:-R:00: EMULOP_RETURN +0111 0001 EEEE EEEE:00:-----:XNZVC:-J:10: EMULOP #E + +% NatFea instructions (do I have the srcaddr correct?) +% NatFeat disabled +% 0111 0011 0000 0000:00:-----:XNZVC:-J:00: NATFEAT_ID +% 0111 0011 0000 0001:00:-----:XNZVC:-J:00: NATFEAT_CALL diff --git a/BasiliskII/src/user_strings.cpp b/BasiliskII/src/user_strings.cpp index f6b59ed4c..2c813157c 100644 --- a/BasiliskII/src/user_strings.cpp +++ b/BasiliskII/src/user_strings.cpp @@ -33,17 +33,13 @@ #include "sysdeps.h" #include "user_strings.h" -#ifdef __BEOS__ -#define ELLIPSIS "\xE2\x80\xA6" -#else #define ELLIPSIS "..." -#endif +#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"}, @@ -177,6 +173,12 @@ user_string_def common_strings[] = { {STR_24_BIT_1600x1200_LAB, "1600x1200, 24 Bit"}, {STR_SOUND_CTRL, "Sound"}, {STR_NOSOUND_CTRL, "Disable Sound Output"}, + {STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL, "Render Driver"}, + {STR_SOFTWARE_LAB, "Software"}, + {STR_OPENGL_LAB, "OpenGL"}, + {STR_DIRECT3D_LAB, "Direct3D"}, + {STR_GRAPHICS_SDL_VSYNC_CTRL, "Vertical Sync (Software)"}, + {STR_DEFAULT_LAB, "Default"}, {STR_SERIAL_NETWORK_PANE_TITLE, "Serial/Network"}, {STR_SERIALA_CTRL, "Modem Port"}, @@ -203,36 +205,7 @@ user_string_def common_strings[] = { {STR_RAMSIZE_FMT, "%ld MB"}, {STR_MODELID_CTRL, "Mac Model ID"}, {STR_MODELID_5_LAB, "Mac IIci (MacOS 7.x)"}, - {STR_MODELID_7_LAB, "Mac IIfx (MacOS 7.x)"}, - {STR_MODELID_12_LAB, "Mac IIsi (MacOS 7.x"}, - {STR_MODELID_13_LAB, "Mac LC (MacOS 7.x"}, {STR_MODELID_14_LAB, "Quadra 900 (MacOS 8.x)"}, - {STR_MODELID_15_LAB, "PowerBook 170 (MacOS 7.x)"}, - {STR_MODELID_16_LAB, "Quadra 700 (MacOS 8.x)"}, - {STR_MODELID_19_LAB, "PowerBook 140 (MacOS 7.x)"}, - {STR_MODELID_20_LAB, "Quadra 950 (MacOS 8.x)"}, - {STR_MODELID_21_LAB, "Mac LC III-Performa 450 (MacOS 7.x)"}, - {STR_MODELID_24_LAB, "Centris 650 (MacOS 8.x)"}, - {STR_MODELID_29_LAB, "Quadra 800 (MacOS 8.x)"}, - {STR_MODELID_30_LAB, "Quadra 650 (MacOS 8.x)"}, - {STR_MODELID_31_LAB, "Mac LC II (MacOS 7.x)"}, - {STR_MODELID_38_LAB, "Mac IIvi (MacOS 7.x)"}, - {STR_MODELID_39_LAB, "Performa 600 (MacOS 7.x)"}, - {STR_MODELID_42_LAB, "Mac IIvx (MacOS 7.x)"}, - {STR_MODELID_43_LAB, "Color Classic (MacOS 7.x)"}, - {STR_MODELID_46_LAB, "Centris 610 (MacOS 8.x)"}, - {STR_MODELID_47_LAB, "Quadra 610 (MacOS 8.x)"}, - {STR_MODELID_50_LAB, "Mac LC 520 (MacOS 7.x)"}, - {STR_MODELID_54_LAB, "Centris-Quadra 660AV (MacOS 8.x)"}, - {STR_MODELID_56_LAB, "Performa 46x (MacOS 7.x)"}, - {STR_MODELID_72_LAB, "Quadra 840AV (MacOS 8.x)"}, - {STR_MODELID_74_LAB, "Mac LC-Performa 550 (MacOS 7.x)"}, - {STR_MODELID_82_LAB, "Mac TV (MacOS 7.x)"}, - {STR_MODELID_83_LAB, "Mac LC 475-Performa 47x (MacOS 8.x)"}, - {STR_MODELID_86_LAB, "Mac LC 575-Performa 57x (MacOS 8.x)"}, - {STR_MODELID_87_LAB, "Quadra 605 (MacOS 8.x)"}, - {STR_MODELID_92_LAB, "Mac LC-Performa-Quadra 630 (MacOS 8.x)"}, - {STR_MODELID_93_LAB, "Mac LC 580 (MacOS 8.x)"}, {STR_CPU_CTRL, "CPU Type"}, {STR_CPU_68020_LAB, "68020"}, {STR_CPU_68020_FPU_LAB, "68020 with FPU"}, @@ -241,6 +214,7 @@ user_string_def common_strings[] = { {STR_CPU_68040_LAB, "68040"}, {STR_ROM_FILE_CTRL, "ROM File"}, {STR_IDLEWAIT_CTRL, "Don't Use CPU When Idle"}, + {STR_JIT_PANE_TITLE, "JIT Compiler"}, {STR_JIT_CTRL, "Enable JIT Compiler"}, {STR_JIT_FPU_CTRL, "Compile FPU Instructions"}, @@ -253,11 +227,9 @@ user_string_def common_strings[] = { {STR_JIT_FOLLOW_CONST_JUMPS, "Translate through constant jumps (inline blocks)"}, {STR_WINDOW_TITLE, "Basilisk II"}, - {STR_WINDOW_TITLE_FROZEN, "Basilisk II *** FROZEN ***"}, - {STR_WINDOW_TITLE_GRABBED, "Basilisk II (mouse grabbed, press Ctrl-F5 to release)"}, - {STR_WINDOW_TITLE_GRABBED0, "Basilisk II (mouse grabbed, press "}, + {STR_WINDOW_TITLE_GRABBED0, " (mouse grabbed, press "}, {STR_WINDOW_TITLE_GRABBED1, "Ctrl-"}, -#ifdef __MACOSX__ +#ifdef __APPLE__ {STR_WINDOW_TITLE_GRABBED2, "Opt-"}, {STR_WINDOW_TITLE_GRABBED3, "Cmd-"}, #else @@ -271,6 +243,8 @@ user_string_def common_strings[] = { {STR_WINDOW_ITEM_MOUNT, "Mount"}, {STR_SUSPEND_WINDOW_TITLE, "Basilisk II suspended. Press space to reactivate."}, + {STR_SOUND_IN_NAME, "\010Built-In"}, + {STR_EXTFS_NAME, "Host Directory Tree"}, {STR_EXTFS_VOLUME_NAME, "Host"}, diff --git a/BasiliskII/src/video.cpp b/BasiliskII/src/video.cpp index 8f84f48de..bd78fdbd9 100644 --- a/BasiliskII/src/video.cpp +++ b/BasiliskII/src/video.cpp @@ -48,6 +48,23 @@ uint8 monitor_desc::next_slot_id = 0x80; vector VideoMonitors; +/* + * Converts a video_depth to a C-String name ("VDEPTH_1BIT", "VDEPTH_2BIT", etc.) + */ +const char * NameOfDepth(video_depth depth) +{ + switch (depth) { + case VDEPTH_1BIT: return "VDEPTH_1BIT"; + case VDEPTH_2BIT: return "VDEPTH_2BIT"; + case VDEPTH_4BIT: return "VDEPTH_4BIT"; + case VDEPTH_8BIT: return "VDEPTH_8BIT"; + case VDEPTH_16BIT: return "VDEPTH_16BIT"; + case VDEPTH_32BIT: return "VDEPTH_32BIT"; + } + return ""; +} + + /* * Find palette size for given color depth */ @@ -218,10 +235,10 @@ void monitor_desc::set_gray_palette(void) /* - * Load gamma-corrected black-to-white ramp to palette for direct-color mode + * Load gamma-corrected black-to-white ramp */ -void monitor_desc::load_ramp_palette(void) +void monitor_desc::load_gamma_ramp(void) { // Find tables for gamma correction uint8 *red_gamma = NULL, *green_gamma = NULL, *blue_gamma = NULL; @@ -256,7 +273,7 @@ void monitor_desc::load_ramp_palette(void) *p++ = blue; } - set_palette(palette, num); + set_gamma(palette, num); } @@ -337,8 +354,7 @@ int16 monitor_desc::set_gamma_table(uint32 user_table) Mac2Mac_memcpy(gamma_table, user_table, size); } - if (IsDirectMode(*current_mode)) - load_ramp_palette(); + load_gamma_ramp(); return noErr; } @@ -619,8 +635,7 @@ int16 monitor_desc::driver_control(uint16 code, uint32 param, uint32 dce) pat = ~pat; } - if (IsDirectMode(*current_mode)) - load_ramp_palette(); + load_gamma_ramp(); return noErr; } diff --git a/README.md b/README.md index 6c6227d8e..6156fd01c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,86 @@ -# BasiliskII -[![Build Status](https://travis-ci.org/rickyzhang82/macemu.svg?branch=upstream-master)](https://travis-ci.org/rickyzhang82/macemu) +#### BasiliskII +``` +macOS x86_64 JIT / arm64 non-JIT +Linux x86 x86_64 JIT +MinGW x86 JIT +``` +#### SheepShaver +``` +macOS x86_64 JIT / arm64 non-JIT +Linux x86 x86_64 JIT +MinGW x86 JIT +``` +### How To Build +These builds need to be installed SDL2.0.10+ framework/library. +#### BasiliskII +##### macOS +BasiliskII for macOS can be built with Apple Silicon Mac. + +preparation: + +Download gmp-6.2.1.tar.xz from https://gmplib.org. +``` +$ cd ~/Downloads +$ tar xf gmp-6.2.1.tar.xz +$ cd gmp-6.2.1 +$ ./configure --disable-shared +$ make +$ make check +$ sudo make install +``` +Download mpfr-4.1.0.tar.xz from https://www.mpfr.org. +``` +$ cd ~/Downloads +$ tar xf mpfr-4.1.0.tar.xz +$ cd mpfr-4.1.0 +$ ./configure --disable-shared +$ make +$ make check +$ sudo make install +``` +For Intel Mac, checkout `has_fpu_bug` branch. But it has FPU issue if the binary runs on Apple Silicon Mac. + +1. Open BasiliskII/src/MacOSX/BasiliskII.xcodeproj +1. Set Build Configuration to Release +1. Build + +or same as Linux (x86_64 only) + +##### Linux(x86/x86_64) +``` +$ cd macemu/BasiliskII/src/Unix +$ ./autogen.sh +$ make +``` +##### MinGW32/MSYS2 +``` +$ cd macemu/BasiliskII/src/Windows +$ ../Unix/autogen.sh +$ make +``` +#### SheepShaver +##### macOS +1. Open SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj +1. Set Build Configuration to Release +1. Build + +or same as Linux (x86_64 only) + +##### Linux(x86/x86_64) +``` +$ cd macemu/SheepShaver/src/Unix +$ ./autogen.sh +$ make +``` +##### MinGW32/MSYS2 +``` +$ cd macemu/SheepShaver +$ make links +$ cd src/Windows +$ ../Unix/autogen.sh +$ make +``` +### Recommended key bindings for gnome +https://github.com/kanjitalk755/macemu/blob/master/SheepShaver/doc/Linux/gnome_keybindings.txt + +(from https://github.com/kanjitalk755/macemu/issues/59) diff --git a/SheepShaver/Makefile b/SheepShaver/Makefile index 2fec37a17..cfc9e217b 100644 --- a/SheepShaver/Makefile +++ b/SheepShaver/Makefile @@ -49,33 +49,33 @@ $(SRCARCHIVE): $(SRCS) $(DOCS) # Links to Basilisk II sources # links: + (cd src/Windows; if [ ! -e m4 ]; then ln -s ../../../BasiliskII/src/Unix/m4; fi) @list='adb.cpp audio.cpp cdrom.cpp disk.cpp extfs.cpp pict.c \ prefs.cpp scsi.cpp sony.cpp xpram.cpp \ + bincue.cpp include/bincue.h \ include/adb.h include/audio.h include/audio_defs.h \ include/cdrom.h include/clip.h include/debug.h include/disk.h \ include/extfs.h include/extfs_defs.h include/pict.h \ 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/sigsegv.cpp 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 Unix/bincue_unix.cpp Unix/bincue_unix.h \ + CrossPlatform/sigsegv.h \ + CrossPlatform/video_blit.h CrossPlatform/video_blit.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 \ 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/lowmem.c Unix/Darwin/pagezero.c Unix/Darwin/testlmem.sh \ + 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 \ @@ -87,7 +87,6 @@ links: Windows/posix_emu.cpp Windows/posix_emu.h Windows/sys_windows.cpp \ Windows/timer_windows.cpp Windows/util_windows.cpp \ Windows/util_windows.h Windows/xpram_windows.cpp \ - Windows/kernel_windows.h Windows/kernel_windows.cpp \ Windows/serial_windows.cpp Windows/router Windows/b2ether \ Windows/ether_windows.h Windows/ether_windows.cpp \ Windows/serial_windows.cpp Windows/prefs_editor_gtk.cpp \ @@ -98,7 +97,8 @@ links: echo $$i; o=$$i; \ case $$i in *codegen_x86.h) o=kpx_cpu/src/cpu/jit/x86/codegen_x86.h;; esac; \ SUB=`echo $$o | sed 's;[^/]*/;../;g' | sed 's;[^/]*$$;;'` ;\ - ln -sf "$$PREFIX$$SUB$(B2_TOPDIR)/src/$$i" src/$$o; \ + cur_link=src/$$o ;\ + if [ -e "$$cur_link" ]; then rm -rf "$$cur_link"; fi ;\ + ln -sf "$$PREFIX$$SUB$(B2_TOPDIR)/src/$$i" $$cur_link; \ fi; \ - done; \ - ln -sf ../../../../../SheepShaver/src/Unix/config.h $(B2_TOPDIR)/src/Unix/Linux/NetDriver/config.h + done; 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 10a335538..000000000 Binary files a/SheepShaver/doc/BeOS/graphics.gif and /dev/null differ 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 51368b117..000000000 Binary files a/SheepShaver/doc/BeOS/icon.gif and /dev/null differ diff --git a/SheepShaver/doc/BeOS/iconsmall.gif b/SheepShaver/doc/BeOS/iconsmall.gif deleted file mode 100644 index 708ee3bf0..000000000 Binary files a/SheepShaver/doc/BeOS/iconsmall.gif and /dev/null differ 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 9867b003e..000000000 Binary files a/SheepShaver/doc/BeOS/memory.gif and /dev/null differ 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 b491d769d..000000000 Binary files a/SheepShaver/doc/BeOS/serial.gif and /dev/null differ 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 857dd0a21..000000000 Binary files a/SheepShaver/doc/BeOS/volumes.gif and /dev/null differ diff --git a/SheepShaver/doc/Linux/gnome_keybindings.txt b/SheepShaver/doc/Linux/gnome_keybindings.txt new file mode 100644 index 000000000..37ceadcf7 --- /dev/null +++ b/SheepShaver/doc/Linux/gnome_keybindings.txt @@ -0,0 +1,162 @@ +------------------------------------------------------------------------------------------------------ +org.gnome.desktop.wm.keybindings: + + CHANGE ALL SETTINGS TO: + UseDefaultValue: OFF + Custom Value: [] + +------------------------------------------------------------------------------------------------------ +org.gnome.mutter: + +org.gnome.mutter.overlay-key + DEFAULT: 'Super_L' + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: + + +------------------------------------------------------------------------------------------------------ +org.gnome.mutter.keybindings: + +org.gnome.mutter.keybindings.switch-monitor + DEFAULT: ['p', 'XF86Display'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: ['XF86Display'] + + +org.gnome.mutter.keybindings.toggle-tiled-left + DEFAULT: ['Left'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.gnome.mutter.keybindings.toggle-tiled-right + DEFAULT: ['Right'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +------------------------------------------------------------------------------------------------------ +org.gnome.mutter.wayland.keybindings: + +org.gnome.mutter.wayland.keybindings.restore-shortcuts + DEFAULT: ['Escape'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + + +------------------------------------------------------------------------------------------------------ +org.pantheon.desktop.gala.keybindings: + +org.pantheon.desktop.gala.keybindings.cycle-workspaces-next + DEFAULT: ['Tab'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: ['Tab'] + + +org.pantheon.desktop.gala.keybindings.cycle-workspaces-previous + DEFAULT: ['Tab'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: ['Tab'] + + +org.pantheon.desktop.gala.keybindings.expose-all-windows + DEFAULT: ['a'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.expose-windows + DEFAULT: ['w'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.move-to-workspace-first + DEFAULT: ['Home'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.move-to-workspace-last + DEFAULT: ['End', '0'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.pip + DEFAULT: ['f'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.switch-input-source + DEFAULT: [''] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.switch-input-source-backward + DEFAULT: ['Space'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.switch-to-workspace-first + DEFAULT: ['Home'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.switch-to-workspace-last + DEFAULT: ['End', '0'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.zoom-in + DEFAULT: ['plus', 'KP_Add'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] + + +org.pantheon.desktop.gala.keybindings.zoom-out + DEFAULT: ['minus', 'KP_Subtract'] + + CHANGE TO: + UseDefaultValue: OFF + Custom Value: [] 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 a61919ba8..000000000 Binary files a/SheepShaver/src/BeOS/SaveROM/SaveROM.rsrc and /dev/null differ diff --git a/SheepShaver/src/BeOS/SheepDriver b/SheepShaver/src/BeOS/SheepDriver deleted file mode 120000 index 9e581b7f6..000000000 --- a/SheepShaver/src/BeOS/SheepDriver +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/SheepDriver \ No newline at end of file diff --git a/SheepShaver/src/BeOS/SheepNet b/SheepShaver/src/BeOS/SheepNet deleted file mode 120000 index 7d7d72572..000000000 --- a/SheepShaver/src/BeOS/SheepNet +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/BeOS/SheepNet \ No newline at end of file diff --git a/SheepShaver/src/BeOS/SheepShaver.rsrc b/SheepShaver/src/BeOS/SheepShaver.rsrc deleted file mode 100644 index 60e6f805f..000000000 Binary files a/SheepShaver/src/BeOS/SheepShaver.rsrc and /dev/null differ diff --git a/SheepShaver/src/BeOS/about_window_beos.cpp b/SheepShaver/src/BeOS/about_window_beos.cpp deleted file mode 100644 index 3d1536dc5..000000000 --- a/SheepShaver/src/BeOS/about_window_beos.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * about_window_beos.cpp - "About" window, 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 "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/CrossPlatform/sigsegv.cpp b/SheepShaver/src/CrossPlatform/sigsegv.cpp deleted file mode 120000 index a41f4a068..000000000 --- a/SheepShaver/src/CrossPlatform/sigsegv.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/CrossPlatform/sigsegv.cpp \ No newline at end of file diff --git a/SheepShaver/src/CrossPlatform/sigsegv.cpp b/SheepShaver/src/CrossPlatform/sigsegv.cpp new file mode 100644 index 000000000..70a43be2c --- /dev/null +++ b/SheepShaver/src/CrossPlatform/sigsegv.cpp @@ -0,0 +1,3517 @@ +/* + * sigsegv.cpp - SIGSEGV signals support + * + * Derived from Bruno Haible's work on his SIGSEGV library for clisp + * + * + * MacOS X support derived from the post by Timothy J. Wood to the + * omnigroup macosx-dev list: + * Mach Exception Handlers 101 (Was Re: ptrace, gdb) + * tjw@omnigroup.com Sun, 4 Jun 2000 + * www.omnigroup.com/mailman/archive/macosx-dev/2000-June/002030.html + * + * 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_UNISTD_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include "sigsegv.h" + +#ifndef NO_STD_NAMESPACE +using std::list; +#endif + +// Return value type of a signal handler (standard type if not defined) +#ifndef RETSIGTYPE +#define RETSIGTYPE void +#endif + +// Size of an unsigned integer large enough to hold all bits of a pointer +// NOTE: this can be different than SIGSEGV_REGISTER_TYPE. In +// particular, on ILP32 systems with a 64-bit kernel (HP-UX/ia64?) +#if defined(HAVE_WIN32_VM) +// Windows is either ILP32 or LLP64 +#include +typedef UINT_PTR sigsegv_uintptr_t; +#else +// Other systems are sane enough to follow ILP32 or LP64 models +typedef unsigned long sigsegv_uintptr_t; +#endif + +// Type of the system signal handler +typedef RETSIGTYPE (*signal_handler)(int); + +// User's SIGSEGV handler +static sigsegv_fault_handler_t sigsegv_fault_handler = 0; + +// Function called to dump state if we can't handle the fault +static sigsegv_state_dumper_t sigsegv_state_dumper = 0; + +#if defined(HAVE_SIGINFO_T) || defined(HAVE_SIGCONTEXT_SUBTERFUGE) +// Actual SIGSEGV handler installer +static bool sigsegv_do_install_handler(int sig); +#endif + +/* + * Instruction decoding aids + */ + +// Transfer type +enum transfer_type_t { + SIGSEGV_TRANSFER_UNKNOWN = 0, + SIGSEGV_TRANSFER_LOAD = 1, + SIGSEGV_TRANSFER_STORE = 2 +}; + +// Transfer size +enum transfer_size_t { + SIZE_UNKNOWN, + SIZE_BYTE, + SIZE_WORD, // 2 bytes + SIZE_LONG, // 4 bytes + SIZE_QUAD // 8 bytes +}; + +#if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)) +// Addressing mode +enum addressing_mode_t { + MODE_UNKNOWN, + MODE_NORM, + MODE_U, + MODE_X, + MODE_UX +}; + +// Decoded instruction +struct instruction_t { + transfer_type_t transfer_type; + transfer_size_t transfer_size; + addressing_mode_t addr_mode; + unsigned int addr; + char ra, rd; +}; + +static void powerpc_decode_instruction(instruction_t *instruction, unsigned int nip, unsigned long * gpr) +{ + // Get opcode and divide into fields + unsigned int opcode = *((unsigned int *)(unsigned long)nip); + unsigned int primop = opcode >> 26; + unsigned int exop = (opcode >> 1) & 0x3ff; + unsigned int ra = (opcode >> 16) & 0x1f; + unsigned int rb = (opcode >> 11) & 0x1f; + unsigned int rd = (opcode >> 21) & 0x1f; + signed int imm = (signed short)(opcode & 0xffff); + + // Analyze opcode + transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; + transfer_size_t transfer_size = SIZE_UNKNOWN; + addressing_mode_t addr_mode = MODE_UNKNOWN; + switch (primop) { + case 31: + switch (exop) { + case 23: // lwzx + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_X; break; + case 55: // lwzux + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break; + case 87: // lbzx + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; + case 119: // lbzux + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; + case 151: // stwx + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_X; break; + case 183: // stwux + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break; + case 215: // stbx + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break; + case 247: // stbux + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break; + case 279: // lhzx + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; + case 311: // lhzux + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; + case 343: // lhax + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; + case 375: // lhaux + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; + case 407: // sthx + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break; + case 439: // sthux + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break; + } + break; + + case 32: // lwz + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break; + case 33: // lwzu + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_U; break; + case 34: // lbz + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; + case 35: // lbzu + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; + case 36: // stw + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break; + case 37: // stwu + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_U; break; + case 38: // stb + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break; + case 39: // stbu + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break; + case 40: // lhz + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; + case 41: // lhzu + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; + case 42: // lha + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; + case 43: // lhau + transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; + case 44: // sth + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break; + case 45: // sthu + transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break; + case 58: // ld, ldu, lwa + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_QUAD; + addr_mode = ((opcode & 3) == 1) ? MODE_U : MODE_NORM; + imm &= ~3; + break; + case 62: // std, stdu, stq + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_QUAD; + addr_mode = ((opcode & 3) == 1) ? MODE_U : MODE_NORM; + imm &= ~3; + break; + } + + // Calculate effective address + unsigned int addr = 0; + switch (addr_mode) { + case MODE_X: + case MODE_UX: + if (ra == 0) + addr = gpr[rb]; + else + addr = gpr[ra] + gpr[rb]; + break; + case MODE_NORM: + case MODE_U: + if (ra == 0) + addr = (signed int)(signed short)imm; + else + addr = gpr[ra] + (signed int)(signed short)imm; + break; + default: + break; + } + + // Commit decoded instruction + instruction->addr = addr; + instruction->addr_mode = addr_mode; + instruction->transfer_type = transfer_type; + instruction->transfer_size = transfer_size; + instruction->ra = ra; + instruction->rd = rd; +} +#endif + + +/* + * OS-dependant SIGSEGV signals support section + */ + +#if HAVE_SIGINFO_T +// Generic extended signal handler +#if defined(__hpux) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) FAULT_HANDLER(SIGBUS) +#else +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#endif +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp +#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 siginfo_t *sip, void *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sip, scp +#define SIGSEGV_FAULT_ADDRESS sip->si_addr +#if (defined(sgi) || defined(__sgi)) +#include +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) +#define SIGSEGV_FAULT_INSTRUCTION (unsigned long)SIGSEGV_CONTEXT_REGS[CTX_EPC] +#if (defined(mips) || defined(__mips)) +#define SIGSEGV_REGISTER_FILE &SIGSEGV_CONTEXT_REGS[CTX_EPC], &SIGSEGV_CONTEXT_REGS[CTX_R0] +#define SIGSEGV_SKIP_INSTRUCTION mips_skip_instruction +#endif +#endif +#if defined(__sun__) +#if (defined(sparc) || defined(__sparc__)) +#include +#include +#include +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_PC] +#define SIGSEGV_SPARC_GWINDOWS (((ucontext_t *)scp)->uc_mcontext.gwins) +#define SIGSEGV_SPARC_RWINDOW (struct rwindow *)((char *)SIGSEGV_CONTEXT_REGS[REG_SP] + STACK_BIAS) +#define SIGSEGV_REGISTER_FILE ((unsigned long *)SIGSEGV_CONTEXT_REGS), SIGSEGV_SPARC_GWINDOWS, SIGSEGV_SPARC_RWINDOW +#define SIGSEGV_SKIP_INSTRUCTION sparc_skip_instruction +#endif +#if defined(__i386__) +#include +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[EIP] +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#endif +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if (defined(i386) || defined(__i386__)) +#undef SIGSEGV_ALL_SIGNALS +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) +#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_eip) +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */ +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#elif (defined(x86_64) || defined(__x86_64__)) +#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_rip) +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&(((struct sigcontext *)scp)->sc_rdi)) +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#endif +#if defined(__NetBSD__) +#if (defined(i386) || defined(__i386__)) +#include +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_EIP] +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#if (defined(powerpc) || defined(__powerpc__)) +#include +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_PC] +#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIGSEGV_CONTEXT_REGS[_REG_PC], (unsigned long *)&SIGSEGV_CONTEXT_REGS[_REG_R0] +#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction +#endif +#endif +#if defined(__linux__) +#if HAVE_ASM_UCONTEXT +#include /* use kernel structure, glibc may not be in sync */ +#else +#include +#endif +#if (defined(hppa) || defined(__hppa__)) +#undef SIGSEGV_FAULT_ADDRESS +#define SIGSEGV_FAULT_ADDRESS sip->si_ptr +#endif +#if (defined(i386) || defined(__i386__)) +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[14] /* should use REG_EIP instead */ +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#elif (defined(x86_64) || defined(__x86_64__)) +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */ +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#elif (defined(ia64) || defined(__ia64__)) +#define SIGSEGV_CONTEXT_REGS ((struct sigcontext *)scp) +#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS->sc_ip & ~0x3ULL) /* slot number is in bits 0 and 1 */ +#define SIGSEGV_REGISTER_FILE SIGSEGV_CONTEXT_REGS +#define SIGSEGV_SKIP_INSTRUCTION ia64_skip_instruction +#elif (defined(powerpc) || defined(__powerpc__)) +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.regs) +#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS->nip) +#define SIGSEGV_REGISTER_FILE (unsigned long *)&SIGSEGV_CONTEXT_REGS->nip, (unsigned long *)(SIGSEGV_CONTEXT_REGS->gpr) +#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction +#elif (defined(arm) || defined(__arm__)) +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext) +#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.arm_pc) +#define SIGSEGV_REGISTER_FILE (&SIGSEGV_CONTEXT_REGS.arm_r0) +#define SIGSEGV_SKIP_INSTRUCTION arm_skip_instruction +#elif (defined(mips) || defined(__mips__)) +#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext) +#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.pc) +#define SIGSEGV_REGISTER_FILE &SIGSEGV_CONTEXT_REGS.pc, &SIGSEGV_CONTEXT_REGS.gregs[0] +#define SIGSEGV_SKIP_INSTRUCTION mips_skip_instruction +#endif +#endif // defined(__linux__) +#if (defined(__hpux) || defined(__hpux__)) +#if (defined(__hppa) || defined(__hppa__)) +#define SIGSEGV_CONTEXT_REGS (&((ucontext_t *)scp)->uc_mcontext) +#define SIGSEGV_FAULT_INSTRUCTION_32 (SIGSEGV_CONTEXT_REGS->ss_narrow.ss_pcoq_head & ~3ul) +#define SIGSEGV_FAULT_INSTRUCTION_64 (SIGSEGV_CONTEXT_REGS->ss_wide.ss_64.ss_pcoq_head & ~3ull) +#if defined(__LP64__) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_FAULT_INSTRUCTION_64 +#else +#define SIGSEGV_FAULT_INSTRUCTION ((SIGSEGV_CONTEXT_REGS->ss_flags & SS_WIDEREGS) ? \ + (uint32_t)SIGSEGV_FAULT_INSTRUCTION_64 : \ + SIGSEGV_FAULT_INSTRUCTION_32) +#endif +#endif +#if (defined(__ia64) || defined(__ia64__)) +#include +#define SIGSEGV_CONTEXT_REGS ((ucontext_t *)scp) +#define SIGSEGV_FAULT_INSTRUCTION get_fault_instruction(SIGSEGV_CONTEXT_REGS) +#define SIGSEGV_REGISTER_FILE SIGSEGV_CONTEXT_REGS +#define SIGSEGV_SKIP_INSTRUCTION ia64_skip_instruction + +#include +static inline sigsegv_address_t get_fault_instruction(const ucontext_t *ucp) +{ + uint64_t ip; + if (__uc_get_ip(ucp, &ip) != 0) + return SIGSEGV_INVALID_ADDRESS; + return (sigsegv_address_t)(ip & ~3ULL); +} +#endif +#endif +#endif + +#if HAVE_SIGCONTEXT_SUBTERFUGE +// Linux kernels prior to 2.4 ? +#if defined(__linux__) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#if (defined(i386) || defined(__i386__)) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, struct sigcontext scs +#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS &scs +#define SIGSEGV_FAULT_ADDRESS scp->cr2 +#define SIGSEGV_FAULT_INSTRUCTION scp->eip +#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)scp +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#if (defined(sparc) || defined(__sparc__)) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, char *addr +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp, addr +#define SIGSEGV_FAULT_ADDRESS addr +#endif +#if (defined(powerpc) || defined(__powerpc__)) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, scp +#define SIGSEGV_FAULT_ADDRESS scp->regs->dar +#define SIGSEGV_FAULT_INSTRUCTION scp->regs->nip +#define SIGSEGV_REGISTER_FILE (unsigned long *)&scp->regs->nip, (unsigned long *)(scp->regs->gpr) +#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction +#endif +#if (defined(alpha) || defined(__alpha__)) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) +#define SIGSEGV_FAULT_INSTRUCTION scp->sc_pc +#endif +#if (defined(arm) || defined(__arm__)) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int r1, int r2, int r3, struct sigcontext sc +#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS &sc +#define SIGSEGV_FAULT_ADDRESS scp->fault_address +#define SIGSEGV_FAULT_INSTRUCTION scp->arm_pc +#define SIGSEGV_REGISTER_FILE &scp->arm_r0 +#define SIGSEGV_SKIP_INSTRUCTION arm_skip_instruction +#endif +#endif + +// Irix 5 or 6 on MIPS +#if (defined(sgi) || defined(__sgi)) && (defined(SYSTYPE_SVR4) || defined(_SYSTYPE_SVR4)) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS (unsigned long)scp->sc_badvaddr +#define SIGSEGV_FAULT_INSTRUCTION (unsigned long)scp->sc_pc +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#endif + +// HP-UX +#if (defined(hpux) || defined(__hpux__)) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS scp->sc_sl.sl_ss.ss_narrow.ss_cr21 +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) FAULT_HANDLER(SIGBUS) +#endif + +// OSF/1 on Alpha +#if defined(__osf__) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS scp->sc_traparg_a0 +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#endif + +// AIX +#if defined(_AIX) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS scp->sc_jmpbuf.jmp_context.o_vaddr +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#endif + +// NetBSD +#if defined(__NetBSD__) +#if (defined(m68k) || defined(__m68k__)) +#include +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) + +// Use decoding scheme from BasiliskII/m68k native +static sigsegv_address_t get_fault_address(struct sigcontext *scp) +{ + struct sigstate { + int ss_flags; + struct frame ss_frame; + }; + struct sigstate *state = (struct sigstate *)scp->sc_ap; + char *fault_addr; + switch (state->ss_frame.f_format) { + case 7: /* 68040 access error */ + /* "code" is sometimes unreliable (i.e. contains NULL or a bogus address), reason unknown */ + fault_addr = state->ss_frame.f_fmt7.f_fa; + break; + default: + fault_addr = (char *)code; + break; + } + return (sigsegv_address_t)fault_addr; +} +#endif +#if (defined(alpha) || defined(__alpha__)) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) +#endif +#if (defined(i386) || defined(__i386__)) +#error "FIXME: need to decode instruction and compute EA" +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#endif +#endif +#if defined(__FreeBSD__) +#if (defined(i386) || defined(__i386__)) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, char *addr +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp, addr +#define SIGSEGV_FAULT_ADDRESS addr +#define SIGSEGV_FAULT_INSTRUCTION scp->sc_eip +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&scp->sc_edi) +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#if (defined(alpha) || defined(__alpha__)) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGSEGV) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, char *addr, struct sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, addr, scp +#define SIGSEGV_FAULT_ADDRESS addr +#define SIGSEGV_FAULT_INSTRUCTION scp->sc_pc +#endif +#endif + +// Extract fault address out of a sigcontext +#if (defined(alpha) || defined(__alpha__)) +// From Boehm's GC 6.0alpha8 +static sigsegv_address_t get_fault_address(struct sigcontext *scp) +{ + unsigned int instruction = *((unsigned int *)(scp->sc_pc)); + unsigned long fault_address = scp->sc_regs[(instruction >> 16) & 0x1f]; + fault_address += (signed long)(signed short)(instruction & 0xffff); + return (sigsegv_address_t)fault_address; +} +#endif + + +// MacOS X, not sure which version this works in. Under 10.1 +// vm_protect does not appear to work from a signal handler. Under +// 10.2 signal handlers get siginfo type arguments but the si_addr +// field is the address of the faulting instruction and not the +// address that caused the SIGBUS. Maybe this works in 10.0? In any +// case with Mach exception handlers there is a way to do what this +// was meant to do. +#ifndef HAVE_MACH_EXCEPTIONS +#if defined(__APPLE__) && defined(__MACH__) +#if (defined(ppc) || defined(__ppc__)) +#define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct __darwin_sigcontext *scp +#define SIGSEGV_FAULT_HANDLER_ARGS sig, code, scp +#define SIGSEGV_FAULT_ADDRESS get_fault_address(scp) +#define SIGSEGV_FAULT_INSTRUCTION scp->MACH_FIELD_NAME(sc_ir) +#define SIGSEGV_ALL_SIGNALS FAULT_HANDLER(SIGBUS) +#define SIGSEGV_REGISTER_FILE (unsigned int *)&scp->sc_ir, &((unsigned int *) scp->sc_regs)[2] +#define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction + +// Use decoding scheme from SheepShaver +static sigsegv_address_t get_fault_address(struct sigcontext *scp) +{ + unsigned int nip = (unsigned int) scp->MACH_FIELD_NAME(sc_ir); + unsigned int * gpr = &((unsigned int *) scp->MACH_FIELD_NAME(sc_regs))[2]; + instruction_t instr; + + powerpc_decode_instruction(&instr, nip, (long unsigned int*)gpr); + return (sigsegv_address_t)instr.addr; +} +#endif +#endif +#endif +#endif + +#if HAVE_WIN32_EXCEPTIONS +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include +#include + +#define SIGSEGV_FAULT_HANDLER_ARGLIST EXCEPTION_POINTERS *ExceptionInfo +#define SIGSEGV_FAULT_HANDLER_ARGS ExceptionInfo +#define SIGSEGV_FAULT_ADDRESS ExceptionInfo->ExceptionRecord->ExceptionInformation[1] +#define SIGSEGV_CONTEXT_REGS ExceptionInfo->ContextRecord +#if defined(_M_IX86) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->Eip +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIGSEGV_CONTEXT_REGS->Edi) +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#if defined(_M_X64) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->Rip +#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIGSEGV_CONTEXT_REGS->Rax) +#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction +#endif +#if defined(_M_IA64) +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS->StIIP +#endif +#endif + +#if HAVE_MACH_EXCEPTIONS + +// This can easily be extended to other Mach systems, but really who +// uses HURD (oops GNU/HURD), Darwin/x86, NextStep, Rhapsody, or CMU +// Mach 2.5/3.0? +#if defined(__APPLE__) && defined(__MACH__) + +#include +#include +#include +#include + +/* + * If you are familiar with MIG then you will understand the frustration + * that was necessary to get these embedded into C++ code by hand. + */ +extern "C" { +#include +#include + +#ifndef HAVE_MACH64_VM + +// Undefine this to prevent a preprocessor warning when compiling on a +// 32-bit machine with Mac OS X 10.5. +#undef MACH_EXCEPTION_CODES + +#define MACH_EXCEPTION_CODES 0 +#define mach_exception_data_t exception_data_t +#define mach_exception_data_type_t exception_data_type_t +#define mach_exc_server exc_server +#define catch_mach_exception_raise catch_exception_raise +#define mach_exception_raise exception_raise +#define mach_exception_raise_state exception_raise_state +#define mach_exception_raise_state_identity exception_raise_state_identity +#endif + +extern boolean_t mach_exc_server(mach_msg_header_t *, mach_msg_header_t *); +extern kern_return_t catch_mach_exception_raise(mach_port_t, mach_port_t, + mach_port_t, exception_type_t, mach_exception_data_t, mach_msg_type_number_t); +extern kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, + exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t code_count, + int *flavor, + thread_state_t old_state, mach_msg_type_number_t old_state_count, + thread_state_t new_state, mach_msg_type_number_t *new_state_count); +extern kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, + mach_port_t thread_port, mach_port_t task_port, exception_type_t exception, + mach_exception_data_t code, mach_msg_type_number_t code_count, + int *flavor, + thread_state_t old_state, mach_msg_type_number_t old_state_count, + thread_state_t new_state, mach_msg_type_number_t *new_state_count); +extern kern_return_t mach_exception_raise(mach_port_t, mach_port_t, mach_port_t, + exception_type_t, mach_exception_data_t, mach_msg_type_number_t); +extern kern_return_t mach_exception_raise_state(mach_port_t, exception_type_t, + mach_exception_data_t, mach_msg_type_number_t, thread_state_flavor_t *, + thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t *); +extern kern_return_t mach_exception_raise_state_identity(mach_port_t, mach_port_t, mach_port_t, + exception_type_t, mach_exception_data_t, mach_msg_type_number_t, thread_state_flavor_t *, + thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t *); +} + +// Could make this dynamic by looking for a result of MIG_ARRAY_TOO_LARGE +#define HANDLER_COUNT 64 + +// structure to tuck away existing exception handlers +typedef struct _ExceptionPorts { + mach_msg_type_number_t maskCount; + exception_mask_t masks[HANDLER_COUNT]; + exception_handler_t handlers[HANDLER_COUNT]; + exception_behavior_t behaviors[HANDLER_COUNT]; + thread_state_flavor_t flavors[HANDLER_COUNT]; +} ExceptionPorts; + +// exception handler thread +static pthread_t exc_thread; + +// place where old exception handler info is stored +static ExceptionPorts ports; + +// our exception port +static mach_port_t _exceptionPort = MACH_PORT_NULL; + +#define MACH_CHECK_ERROR(name,ret) \ +if (ret != KERN_SUCCESS) { \ + mach_error(#name, ret); \ + exit (1); \ +} + +#ifndef MACH_FIELD_NAME +#define MACH_FIELD_NAME(X) X +#endif + +// Since there can only be one exception thread running at any time +// this is not a problem. +#define MSG_SIZE 512 +static char msgbuf[MSG_SIZE]; +static char replybuf[MSG_SIZE]; + +/* + * This is the entry point for the exception handler thread. The job + * of this thread is to wait for exception messages on the exception + * port that was setup beforehand and to pass them on to exc_server. + * exc_server is a MIG generated function that is a part of Mach. + * Its job is to decide what to do with the exception message. In our + * case exc_server calls catch_exception_raise on our behalf. After + * exc_server returns, it is our responsibility to send the reply. + */ +static void * +handleExceptions(void *priv) +{ + mach_msg_header_t *msg, *reply; + kern_return_t krc; + + msg = (mach_msg_header_t *)msgbuf; + reply = (mach_msg_header_t *)replybuf; + + for (;;) { + krc = mach_msg(msg, MACH_RCV_MSG, MSG_SIZE, MSG_SIZE, + _exceptionPort, 0, MACH_PORT_NULL); + MACH_CHECK_ERROR(mach_msg, krc); + + if (!mach_exc_server(msg, reply)) { + fprintf(stderr, "exc_server hated the message\n"); + exit(1); + } + + krc = mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, + msg->msgh_local_port, 0, MACH_PORT_NULL); + if (krc != KERN_SUCCESS) { + fprintf(stderr, "Error sending message to original reply port, krc = %d, %s", + krc, mach_error_string(krc)); + exit(1); + } + } +} +#endif +#endif + + +/* + * Instruction skipping + */ + +#ifndef SIGSEGV_REGISTER_TYPE +#define SIGSEGV_REGISTER_TYPE sigsegv_uintptr_t +#endif + +#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION +// Decode and skip X86 instruction +#if (defined(i386) || defined(__i386__) || defined(_M_IX86)) || (defined(__x86_64__) || defined(_M_X64)) +#if defined(__linux__) +enum { +#if (defined(i386) || defined(__i386__)) + X86_REG_EIP = 14, + X86_REG_EAX = 11, + X86_REG_ECX = 10, + X86_REG_EDX = 9, + X86_REG_EBX = 8, + X86_REG_ESP = 7, + X86_REG_EBP = 6, + X86_REG_ESI = 5, + X86_REG_EDI = 4 +#endif +#if defined(__x86_64__) + X86_REG_R8 = 0, + X86_REG_R9 = 1, + X86_REG_R10 = 2, + X86_REG_R11 = 3, + X86_REG_R12 = 4, + X86_REG_R13 = 5, + X86_REG_R14 = 6, + X86_REG_R15 = 7, + X86_REG_EDI = 8, + X86_REG_ESI = 9, + X86_REG_EBP = 10, + X86_REG_EBX = 11, + X86_REG_EDX = 12, + X86_REG_EAX = 13, + X86_REG_ECX = 14, + X86_REG_ESP = 15, + X86_REG_EIP = 16 +#endif +}; +#endif +#if defined(__NetBSD__) +enum { +#if (defined(i386) || defined(__i386__)) + X86_REG_EIP = _REG_EIP, + X86_REG_EAX = _REG_EAX, + X86_REG_ECX = _REG_ECX, + X86_REG_EDX = _REG_EDX, + X86_REG_EBX = _REG_EBX, + X86_REG_ESP = _REG_ESP, + X86_REG_EBP = _REG_EBP, + X86_REG_ESI = _REG_ESI, + X86_REG_EDI = _REG_EDI +#endif +}; +#endif +#if defined(__FreeBSD__) +enum { +#if (defined(i386) || defined(__i386__)) + X86_REG_EIP = 10, + X86_REG_EAX = 7, + X86_REG_ECX = 6, + X86_REG_EDX = 5, + X86_REG_EBX = 4, + X86_REG_ESP = 13, + X86_REG_EBP = 2, + X86_REG_ESI = 1, + X86_REG_EDI = 0 +#endif +#if (defined(x86_64) || defined(__x86_64__)) + X86_REG_EDI = 0, + X86_REG_ESI = 1, + X86_REG_EDX = 2, + X86_REG_ECX = 3, + X86_REG_R8 = 4, + X86_REG_R9 = 5, + X86_REG_EAX = 6, + X86_REG_EBX = 7, + X86_REG_EBP = 8, + X86_REG_R10 = 9, + X86_REG_R11 = 10, + X86_REG_R12 = 11, + X86_REG_R13 = 12, + X86_REG_R14 = 13, + X86_REG_R15 = 14, + X86_REG_EIP = 19, + X86_REG_ESP = 22, +#endif +}; +#endif +#if defined(__OpenBSD__) +enum { +#if defined(__i386__) + // EDI is the first register we consider +#define OREG(REG) offsetof(struct sigcontext, sc_##REG) +#define DREG(REG) ((OREG(REG) - OREG(edi)) / 4) + X86_REG_EIP = DREG(eip), // 7 + X86_REG_EAX = DREG(eax), // 6 + X86_REG_ECX = DREG(ecx), // 5 + X86_REG_EDX = DREG(edx), // 4 + X86_REG_EBX = DREG(ebx), // 3 + X86_REG_ESP = DREG(esp), // 10 + X86_REG_EBP = DREG(ebp), // 2 + X86_REG_ESI = DREG(esi), // 1 + X86_REG_EDI = DREG(edi) // 0 +#undef DREG +#undef OREG +#endif +}; +#endif +#if defined(__sun__) +// Same as for Linux, need to check for x86-64 +enum { +#if defined(__i386__) + X86_REG_EIP = EIP, + X86_REG_EAX = EAX, + X86_REG_ECX = ECX, + X86_REG_EDX = EDX, + X86_REG_EBX = EBX, + X86_REG_ESP = ESP, + X86_REG_EBP = EBP, + X86_REG_ESI = ESI, + X86_REG_EDI = EDI +#endif +}; +#endif +#if defined(__APPLE__) && defined(__MACH__) +enum { +#if (defined(i386) || defined(__i386__)) +#ifdef i386_SAVED_STATE + // same as FreeBSD (in Open Darwin 8.0.1) + X86_REG_EIP = 10, + X86_REG_EAX = 7, + X86_REG_ECX = 6, + X86_REG_EDX = 5, + X86_REG_EBX = 4, + X86_REG_ESP = 13, + X86_REG_EBP = 2, + X86_REG_ESI = 1, + X86_REG_EDI = 0 +#else + // new layout (MacOS X 10.4.4 for x86) + X86_REG_EIP = 10, + X86_REG_EAX = 0, + X86_REG_ECX = 2, + X86_REG_EDX = 3, + X86_REG_EBX = 1, + X86_REG_ESP = 7, + X86_REG_EBP = 6, + X86_REG_ESI = 5, + X86_REG_EDI = 4 +#endif +#endif +#if defined(__x86_64__) + X86_REG_R8 = 8, + X86_REG_R9 = 9, + X86_REG_R10 = 10, + X86_REG_R11 = 11, + X86_REG_R12 = 12, + X86_REG_R13 = 13, + X86_REG_R14 = 14, + X86_REG_R15 = 15, + X86_REG_EDI = 4, + X86_REG_ESI = 5, + X86_REG_EBP = 6, + X86_REG_EBX = 1, + X86_REG_EDX = 3, + X86_REG_EAX = 0, + X86_REG_ECX = 2, + X86_REG_ESP = 7, + X86_REG_EIP = 16 +#endif +}; +#endif +#if defined(_WIN32) +enum { +#if defined(_M_IX86) + X86_REG_EIP = 7, + X86_REG_EAX = 5, + X86_REG_ECX = 4, + X86_REG_EDX = 3, + X86_REG_EBX = 2, + X86_REG_ESP = 10, + X86_REG_EBP = 6, + X86_REG_ESI = 1, + X86_REG_EDI = 0 +#endif +#if defined(_M_X64) + X86_REG_EAX = 0, + X86_REG_ECX = 1, + X86_REG_EDX = 2, + X86_REG_EBX = 3, + X86_REG_ESP = 4, + X86_REG_EBP = 5, + X86_REG_ESI = 6, + X86_REG_EDI = 7, + X86_REG_R8 = 8, + X86_REG_R9 = 9, + X86_REG_R10 = 10, + X86_REG_R11 = 11, + X86_REG_R12 = 12, + X86_REG_R13 = 13, + X86_REG_R14 = 14, + X86_REG_R15 = 15, + X86_REG_EIP = 16 +#endif +}; +#endif +// FIXME: this is partly redundant with the instruction decoding phase +// to discover transfer type and register number +static inline int ix86_step_over_modrm(unsigned char * p) +{ + int mod = (p[0] >> 6) & 3; + int rm = p[0] & 7; + int offset = 0; + + // ModR/M Byte + switch (mod) { + case 0: // [reg] + if (rm == 5) return 4; // disp32 + break; + case 1: // disp8[reg] + offset = 1; + break; + case 2: // disp32[reg] + offset = 4; + break; + case 3: // register + return 0; + } + + // SIB Byte + if (rm == 4) { + if (mod == 0 && (p[1] & 7) == 5) + offset = 5; // disp32[index] + else + offset++; + } + + return offset; +} + +static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs) +{ + unsigned char * eip = (unsigned char *)regs[X86_REG_EIP]; + + if (eip == 0) + return false; +#ifdef _WIN32 + if (IsBadCodePtr((FARPROC)eip)) + return false; +#endif + + enum instruction_type_t { + i_MOV, + i_ADD + }; + + transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; + transfer_size_t transfer_size = SIZE_LONG; + instruction_type_t instruction_type = i_MOV; + + int reg = -1; + int len = 0; + +#if DEBUG + printf("IP: %p [%02x %02x %02x %02x...]\n", + eip, eip[0], eip[1], eip[2], eip[3]); +#endif + + // Operand size prefix + if (*eip == 0x66) { + eip++; + len++; + transfer_size = SIZE_WORD; + } + +#if defined(__x86_64__) || defined(_M_X64) + // Address size override + if (*eip == 0x67) { + // 32-bit address + eip++; + len++; + } +#endif + + // REX prefix +#if defined(__x86_64__) || defined(_M_X64) + struct rex_t { + unsigned char W; + unsigned char R; + unsigned char X; + unsigned char B; + }; + rex_t rex = { 0, 0, 0, 0 }; + bool has_rex = false; + if ((*eip & 0xf0) == 0x40) { + has_rex = true; + const unsigned char b = *eip; + rex.W = b & (1 << 3); + rex.R = b & (1 << 2); + rex.X = b & (1 << 1); + rex.B = b & (1 << 0); +#if DEBUG + printf("REX: %c,%c,%c,%c\n", + rex.W ? 'W' : '_', + rex.R ? 'R' : '_', + rex.X ? 'X' : '_', + rex.B ? 'B' : '_'); +#endif + eip++; + len++; + if (rex.W) + transfer_size = SIZE_QUAD; + } +#else + const bool has_rex = false; +#endif + + // Decode instruction + int op_len = 1; + int target_size = SIZE_UNKNOWN; + switch (eip[0]) { + case 0x0f: + target_size = transfer_size; + switch (eip[1]) { + case 0xbe: // MOVSX r32, r/m8 + case 0xb6: // MOVZX r32, r/m8 + transfer_size = SIZE_BYTE; + goto do_mov_extend; + case 0xbf: // MOVSX r32, r/m16 + case 0xb7: // MOVZX r32, r/m16 + transfer_size = SIZE_WORD; + goto do_mov_extend; + do_mov_extend: + op_len = 2; + goto do_transfer_load; + } + break; +#if defined(__x86_64__) || defined(_M_X64) + case 0x63: // MOVSXD r64, r/m32 + if (has_rex && rex.W) { + transfer_size = SIZE_LONG; + target_size = SIZE_QUAD; + } + else if (transfer_size != SIZE_WORD) { + transfer_size = SIZE_LONG; + target_size = SIZE_QUAD; + } + goto do_transfer_load; +#endif + case 0x02: // ADD r8, r/m8 + transfer_size = SIZE_BYTE; + // fall through + case 0x03: // ADD r32, r/m32 + instruction_type = i_ADD; + goto do_transfer_load; + case 0x8a: // MOV r8, r/m8 + transfer_size = SIZE_BYTE; + // fall through + case 0x8b: // MOV r32, r/m32 (or 16-bit operation) + do_transfer_load: + switch (eip[op_len] & 0xc0) { + case 0x80: + reg = (eip[op_len] >> 3) & 7; + transfer_type = SIGSEGV_TRANSFER_LOAD; + break; + case 0x40: + reg = (eip[op_len] >> 3) & 7; + transfer_type = SIGSEGV_TRANSFER_LOAD; + break; + case 0x00: + reg = (eip[op_len] >> 3) & 7; + transfer_type = SIGSEGV_TRANSFER_LOAD; + break; + } + len += 1 + op_len + ix86_step_over_modrm(eip + op_len); + break; + case 0x00: // ADD r/m8, r8 + transfer_size = SIZE_BYTE; + // fall through + case 0x01: // ADD r/m32, r32 + instruction_type = i_ADD; + goto do_transfer_store; + case 0x88: // MOV r/m8, r8 + transfer_size = SIZE_BYTE; + // fall through + case 0x89: // MOV r/m32, r32 (or 16-bit operation) + do_transfer_store: + switch (eip[op_len] & 0xc0) { + case 0x80: + reg = (eip[op_len] >> 3) & 7; + transfer_type = SIGSEGV_TRANSFER_STORE; + break; + case 0x40: + reg = (eip[op_len] >> 3) & 7; + transfer_type = SIGSEGV_TRANSFER_STORE; + break; + case 0x00: + reg = (eip[op_len] >> 3) & 7; + transfer_type = SIGSEGV_TRANSFER_STORE; + break; + } + len += 1 + op_len + ix86_step_over_modrm(eip + op_len); + break; + } + if (target_size == SIZE_UNKNOWN) + target_size = transfer_size; + + if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { + // Unknown machine code, let it crash. Then patch the decoder + return false; + } + +#if defined(__x86_64__) || defined(_M_X64) + if (rex.R) + reg += 8; +#endif + + if (instruction_type == i_MOV && transfer_type == SIGSEGV_TRANSFER_LOAD && reg != -1) { + static const int x86_reg_map[] = { + X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX, + X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI, +#if defined(__x86_64__) || defined(_M_X64) + X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, + X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, +#endif + }; + + if (reg < 0 || reg >= (sizeof(x86_reg_map)/sizeof(x86_reg_map[0]) - 1)) + return false; + + // Set 0 to the relevant register part + // NOTE: this is only valid for MOV alike instructions + int rloc = x86_reg_map[reg]; + switch (target_size) { + case SIZE_BYTE: + if (has_rex || reg < 4) + regs[rloc] = (regs[rloc] & ~0x00ffL); + else { + rloc = x86_reg_map[reg - 4]; + regs[rloc] = (regs[rloc] & ~0xff00L); + } + break; + case SIZE_WORD: + regs[rloc] = (regs[rloc] & ~0xffffL); + break; + case SIZE_LONG: + case SIZE_QUAD: // zero-extension + regs[rloc] = 0; + break; + } + } + +#if DEBUG + printf("%p: %s %s access", (void *)regs[X86_REG_EIP], + transfer_size == SIZE_BYTE ? "byte" : + transfer_size == SIZE_WORD ? "word" : + transfer_size == SIZE_LONG ? "long" : + transfer_size == SIZE_QUAD ? "quad" : "unknown", + transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write"); + + if (reg != -1) { + static const char * x86_byte_reg_str_map[] = { + "al", "cl", "dl", "bl", + "spl", "bpl", "sil", "dil", + "r8b", "r9b", "r10b", "r11b", + "r12b", "r13b", "r14b", "r15b", + "ah", "ch", "dh", "bh", + }; + static const char * x86_word_reg_str_map[] = { + "ax", "cx", "dx", "bx", + "sp", "bp", "si", "di", + "r8w", "r9w", "r10w", "r11w", + "r12w", "r13w", "r14w", "r15w", + }; + static const char *x86_long_reg_str_map[] = { + "eax", "ecx", "edx", "ebx", + "esp", "ebp", "esi", "edi", + "r8d", "r9d", "r10d", "r11d", + "r12d", "r13d", "r14d", "r15d", + }; + static const char *x86_quad_reg_str_map[] = { + "rax", "rcx", "rdx", "rbx", + "rsp", "rbp", "rsi", "rdi", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15", + }; + const char * reg_str = NULL; + switch (target_size) { + case SIZE_BYTE: + reg_str = x86_byte_reg_str_map[(!has_rex && reg >= 4 ? 12 : 0) + reg]; + break; + case SIZE_WORD: reg_str = x86_word_reg_str_map[reg]; break; + case SIZE_LONG: reg_str = x86_long_reg_str_map[reg]; break; + case SIZE_QUAD: reg_str = x86_quad_reg_str_map[reg]; break; + } + if (reg_str) + printf(" %s register %%%s", + transfer_type == SIGSEGV_TRANSFER_LOAD ? "to" : "from", + reg_str); + } + printf(", %d bytes instruction\n", len); +#endif + + regs[X86_REG_EIP] += len; + return true; +} +#endif + +// Decode and skip IA-64 instruction +#if defined(__ia64) || defined(__ia64__) +typedef uint64_t ia64_bundle_t[2]; +#if defined(__linux__) +// We can directly patch the slot number +#define IA64_CAN_PATCH_IP_SLOT 1 +// Helper macros to access the machine context +#define IA64_CONTEXT_TYPE struct sigcontext * +#define IA64_CONTEXT scp +#define IA64_GET_IP() (IA64_CONTEXT->sc_ip) +#define IA64_SET_IP(V) (IA64_CONTEXT->sc_ip = (V)) +#define IA64_GET_PR(P) ((IA64_CONTEXT->sc_pr >> (P)) & 1) +#define IA64_GET_NAT(I) ((IA64_CONTEXT->sc_nat >> (I)) & 1) +#define IA64_GET_GR(R) (IA64_CONTEXT->sc_gr[(R)]) +#define _IA64_SET_GR(R,V) (IA64_CONTEXT->sc_gr[(R)] = (V)) +#define _IA64_SET_NAT(I,V) (IA64_CONTEXT->sc_nat = (IA64_CONTEXT->sc_nat & ~(1ull << (I))) | (((uint64_t)!!(V)) << (I))) +#define IA64_SET_GR(R,V,N) (_IA64_SET_GR(R,V), _IA64_SET_NAT(R,N)) + +// Load bundle (in little-endian) +static inline void ia64_load_bundle(ia64_bundle_t bundle, uint64_t raw_ip) +{ + uint64_t *ip = (uint64_t *)(raw_ip & ~3ull); + bundle[0] = ip[0]; + bundle[1] = ip[1]; +} +#endif +#if defined(__hpux) || defined(__hpux__) +// We can directly patch the slot number +#define IA64_CAN_PATCH_IP_SLOT 1 +// Helper macros to access the machine context +#define IA64_CONTEXT_TYPE ucontext_t * +#define IA64_CONTEXT ucp +#define IA64_GET_IP() ia64_get_ip(IA64_CONTEXT) +#define IA64_SET_IP(V) ia64_set_ip(IA64_CONTEXT, V) +#define IA64_GET_PR(P) ia64_get_pr(IA64_CONTEXT, P) +#define IA64_GET_NAT(I) ia64_get_nat(IA64_CONTEXT, I) +#define IA64_GET_GR(R) ia64_get_gr(IA64_CONTEXT, R) +#define IA64_SET_GR(R,V,N) ia64_set_gr(IA64_CONTEXT, R, V, N) +#define UC_ACCESS(FUNC,ARGS) do { if (__uc_##FUNC ARGS != 0) abort(); } while (0) + +static inline uint64_t ia64_get_ip(IA64_CONTEXT_TYPE IA64_CONTEXT) + { uint64_t v; UC_ACCESS(get_ip,(IA64_CONTEXT, &v)); return v; } +static inline void ia64_set_ip(IA64_CONTEXT_TYPE IA64_CONTEXT, uint64_t v) + { UC_ACCESS(set_ip,(IA64_CONTEXT, v)); } +static inline unsigned int ia64_get_pr(IA64_CONTEXT_TYPE IA64_CONTEXT, int pr) + { uint64_t v; UC_ACCESS(get_prs,(IA64_CONTEXT, &v)); return (v >> pr) & 1; } +static inline unsigned int ia64_get_nat(IA64_CONTEXT_TYPE IA64_CONTEXT, int r) + { uint64_t v; unsigned int nat; UC_ACCESS(get_grs,(IA64_CONTEXT, r, 1, &v, &nat)); return (nat >> r) & 1; } +static inline uint64_t ia64_get_gr(IA64_CONTEXT_TYPE IA64_CONTEXT, int r) + { uint64_t v; unsigned int nat; UC_ACCESS(get_grs,(IA64_CONTEXT, r, 1, &v, &nat)); return v; } + +static void ia64_set_gr(IA64_CONTEXT_TYPE IA64_CONTEXT, int r, uint64_t v, unsigned int nat) +{ + if (r == 0) + return; + if (r > 0 && r < 32) + UC_ACCESS(set_grs,(IA64_CONTEXT, r, 1, &v, (!!nat) << r)); + else { + uint64_t bsp, bspstore; + UC_ACCESS(get_ar_bsp,(IA64_CONTEXT, &bsp)); + UC_ACCESS(get_ar_bspstore,(IA64_CONTEXT, &bspstore)); + abort(); /* XXX: use libunwind, this is not fun... */ + } +} + +// Byte-swapping +#if defined(__GNUC__) +#define BSWAP64(V) ({ uint64_t r; __asm__ __volatile__("mux1 %0=%1,@rev;;" : "=r" (r) : "r" (V)); r; }) +#elif defined (__HP_aCC) +#define BSWAP64(V) _Asm_mux1(_MBTYPE_REV, V) +#else +#error "Define byte-swap instruction" +#endif + +// Load bundle (in little-endian) +static inline void ia64_load_bundle(ia64_bundle_t bundle, uint64_t raw_ip) +{ + uint64_t *ip = (uint64_t *)(raw_ip & ~3ull); + bundle[0] = BSWAP64(ip[0]); + bundle[1] = BSWAP64(ip[1]); +} +#endif + +// Instruction operations +enum { + IA64_INST_UNKNOWN = 0, + IA64_INST_LD1, // ld1 op0=[op1] + IA64_INST_LD1_UPDATE, // ld1 op0=[op1],op2 + IA64_INST_LD2, // ld2 op0=[op1] + IA64_INST_LD2_UPDATE, // ld2 op0=[op1],op2 + IA64_INST_LD4, // ld4 op0=[op1] + IA64_INST_LD4_UPDATE, // ld4 op0=[op1],op2 + IA64_INST_LD8, // ld8 op0=[op1] + IA64_INST_LD8_UPDATE, // ld8 op0=[op1],op2 + IA64_INST_ST1, // st1 [op0]=op1 + IA64_INST_ST1_UPDATE, // st1 [op0]=op1,op2 + IA64_INST_ST2, // st2 [op0]=op1 + IA64_INST_ST2_UPDATE, // st2 [op0]=op1,op2 + IA64_INST_ST4, // st4 [op0]=op1 + IA64_INST_ST4_UPDATE, // st4 [op0]=op1,op2 + IA64_INST_ST8, // st8 [op0]=op1 + IA64_INST_ST8_UPDATE, // st8 [op0]=op1,op2 + IA64_INST_ADD, // add op0=op1,op2,op3 + IA64_INST_SUB, // sub op0=op1,op2,op3 + IA64_INST_SHLADD, // shladd op0=op1,op3,op2 + IA64_INST_AND, // and op0=op1,op2 + IA64_INST_ANDCM, // andcm op0=op1,op2 + IA64_INST_OR, // or op0=op1,op2 + IA64_INST_XOR, // xor op0=op1,op2 + IA64_INST_SXT1, // sxt1 op0=op1 + IA64_INST_SXT2, // sxt2 op0=op1 + IA64_INST_SXT4, // sxt4 op0=op1 + IA64_INST_ZXT1, // zxt1 op0=op1 + IA64_INST_ZXT2, // zxt2 op0=op1 + IA64_INST_ZXT4, // zxt4 op0=op1 + IA64_INST_NOP // nop op0 +}; + +const int IA64_N_OPERANDS = 4; + +// Decoded operand type +struct ia64_operand_t { + uint8_t commit; // commit result of operation to register file? + uint8_t valid; // XXX: not really used, can be removed (debug) + int8_t index; // index of GPR, or -1 if immediate value + uint8_t nat; // NaT state before operation + uint64_t value; // register contents or immediate value +}; + +// Decoded instruction type +struct ia64_instruction_t { + uint8_t mnemo; // operation to perform + uint8_t pred; // predicate register to check + uint8_t no_memory; // used to emulated main fault instruction + uint64_t inst; // the raw instruction bits (41-bit wide) + ia64_operand_t operands[IA64_N_OPERANDS]; +}; + +// Get immediate sign-bit +static inline int ia64_inst_get_sbit(uint64_t inst) +{ + return (inst >> 36) & 1; +} + +// Get 8-bit immediate value (A3, A8, I27, M30) +static inline uint64_t ia64_inst_get_imm8(uint64_t inst) +{ + uint64_t value = (inst >> 13) & 0x7full; + if (ia64_inst_get_sbit(inst)) + value |= ~0x7full; + return value; +} + +// Get 9-bit immediate value (M3) +static inline uint64_t ia64_inst_get_imm9b(uint64_t inst) +{ + uint64_t value = (((inst >> 27) & 1) << 7) | ((inst >> 13) & 0x7f); + if (ia64_inst_get_sbit(inst)) + value |= ~0xffull; + return value; +} + +// Get 9-bit immediate value (M5) +static inline uint64_t ia64_inst_get_imm9a(uint64_t inst) +{ + uint64_t value = (((inst >> 27) & 1) << 7) | ((inst >> 6) & 0x7f); + if (ia64_inst_get_sbit(inst)) + value |= ~0xffull; + return value; +} + +// Get 14-bit immediate value (A4) +static inline uint64_t ia64_inst_get_imm14(uint64_t inst) +{ + uint64_t value = (((inst >> 27) & 0x3f) << 7) | (inst & 0x7f); + if (ia64_inst_get_sbit(inst)) + value |= ~0x1ffull; + return value; +} + +// Get 22-bit immediate value (A5) +static inline uint64_t ia64_inst_get_imm22(uint64_t inst) +{ + uint64_t value = ((((inst >> 22) & 0x1f) << 16) | + (((inst >> 27) & 0x1ff) << 7) | + (inst & 0x7f)); + if (ia64_inst_get_sbit(inst)) + value |= ~0x1fffffull; + return value; +} + +// Get 21-bit immediate value (I19) +static inline uint64_t ia64_inst_get_imm21(uint64_t inst) +{ + return (((inst >> 36) & 1) << 20) | ((inst >> 6) & 0xfffff); +} + +// Get 2-bit count value (A2) +static inline int ia64_inst_get_count2(uint64_t inst) +{ + return (inst >> 27) & 0x3; +} + +// Get bundle template +static inline unsigned int ia64_get_template(uint64_t ip) +{ + ia64_bundle_t bundle; + ia64_load_bundle(bundle, ip); + return bundle[0] & 0x1f; +} + +// Get specified instruction in bundle +static uint64_t ia64_get_instruction(uint64_t ip, int slot) +{ + uint64_t inst; + ia64_bundle_t bundle; + ia64_load_bundle(bundle, ip); +#if DEBUG + printf("Bundle: %016llx%016llx\n", bundle[1], bundle[0]); +#endif + + switch (slot) { + case 0: + inst = (bundle[0] >> 5) & 0x1ffffffffffull; + break; + case 1: + inst = ((bundle[1] & 0x7fffffull) << 18) | ((bundle[0] >> 46) & 0x3ffffull); + break; + case 2: + inst = (bundle[1] >> 23) & 0x1ffffffffffull; + break; + case 3: + fprintf(stderr, "ERROR: ia64_get_instruction(), invalid slot number %d\n", slot); + abort(); + break; + } + +#if DEBUG + printf(" Instruction %d: 0x%016llx\n", slot, inst); +#endif + return inst; +} + +// Decode group 0 instructions +static bool ia64_decode_instruction_0(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + const int r1 = (inst->inst >> 6) & 0x7f; + const int r3 = (inst->inst >> 20) & 0x7f; + + const int x3 = (inst->inst >> 33) & 0x07; + const int x6 = (inst->inst >> 27) & 0x3f; + const int x2 = (inst->inst >> 31) & 0x03; + const int x4 = (inst->inst >> 27) & 0x0f; + + if (x3 == 0) { + switch (x6) { + case 0x01: // nop.i (I19) + inst->mnemo = IA64_INST_NOP; + inst->operands[0].valid = true; + inst->operands[0].index = -1; + inst->operands[0].value = ia64_inst_get_imm21(inst->inst); + return true; + case 0x14: // sxt1 (I29) + case 0x15: // sxt2 (I29) + case 0x16: // sxt4 (I29) + case 0x10: // zxt1 (I29) + case 0x11: // zxt2 (I29) + case 0x12: // zxt4 (I29) + switch (x6) { + case 0x14: inst->mnemo = IA64_INST_SXT1; break; + case 0x15: inst->mnemo = IA64_INST_SXT2; break; + case 0x16: inst->mnemo = IA64_INST_SXT4; break; + case 0x10: inst->mnemo = IA64_INST_ZXT1; break; + case 0x11: inst->mnemo = IA64_INST_ZXT2; break; + case 0x12: inst->mnemo = IA64_INST_ZXT4; break; + default: abort(); + } + inst->operands[0].valid = true; + inst->operands[0].index = r1; + inst->operands[1].valid = true; + inst->operands[1].index = r3; + inst->operands[1].value = IA64_GET_GR(r3); + inst->operands[1].nat = IA64_GET_NAT(r3); + return true; + } + } + return false; +} + +// Decode group 4 instructions (load/store instructions) +static bool ia64_decode_instruction_4(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + const int r1 = (inst->inst >> 6) & 0x7f; + const int r2 = (inst->inst >> 13) & 0x7f; + const int r3 = (inst->inst >> 20) & 0x7f; + + const int m = (inst->inst >> 36) & 1; + const int x = (inst->inst >> 27) & 1; + const int x6 = (inst->inst >> 30) & 0x3f; + + switch (x6) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + if (x == 0) { + inst->operands[0].valid = true; + inst->operands[0].index = r1; + inst->operands[1].valid = true; + inst->operands[1].index = r3; + inst->operands[1].value = IA64_GET_GR(r3); + inst->operands[1].nat = IA64_GET_NAT(r3); + if (m == 0) { + switch (x6) { + case 0x00: inst->mnemo = IA64_INST_LD1; break; + case 0x01: inst->mnemo = IA64_INST_LD2; break; + case 0x02: inst->mnemo = IA64_INST_LD4; break; + case 0x03: inst->mnemo = IA64_INST_LD8; break; + } + } + else { + inst->operands[2].valid = true; + inst->operands[2].index = r2; + inst->operands[2].value = IA64_GET_GR(r2); + inst->operands[2].nat = IA64_GET_NAT(r2); + switch (x6) { + case 0x00: inst->mnemo = IA64_INST_LD1_UPDATE; break; + case 0x01: inst->mnemo = IA64_INST_LD2_UPDATE; break; + case 0x02: inst->mnemo = IA64_INST_LD4_UPDATE; break; + case 0x03: inst->mnemo = IA64_INST_LD8_UPDATE; break; + } + } + return true; + } + break; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + if (m == 0 && x == 0) { + inst->operands[0].valid = true; + inst->operands[0].index = r3; + inst->operands[0].value = IA64_GET_GR(r3); + inst->operands[0].nat = IA64_GET_NAT(r3); + inst->operands[1].valid = true; + inst->operands[1].index = r2; + inst->operands[1].value = IA64_GET_GR(r2); + inst->operands[1].nat = IA64_GET_NAT(r2); + switch (x6) { + case 0x30: inst->mnemo = IA64_INST_ST1; break; + case 0x31: inst->mnemo = IA64_INST_ST2; break; + case 0x32: inst->mnemo = IA64_INST_ST4; break; + case 0x33: inst->mnemo = IA64_INST_ST8; break; + } + return true; + } + break; + } + return false; +} + +// Decode group 5 instructions (load/store instructions) +static bool ia64_decode_instruction_5(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + const int r1 = (inst->inst >> 6) & 0x7f; + const int r2 = (inst->inst >> 13) & 0x7f; + const int r3 = (inst->inst >> 20) & 0x7f; + + const int x6 = (inst->inst >> 30) & 0x3f; + + switch (x6) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + inst->operands[0].valid = true; + inst->operands[0].index = r1; + inst->operands[1].valid = true; + inst->operands[1].index = r3; + inst->operands[1].value = IA64_GET_GR(r3); + inst->operands[1].nat = IA64_GET_NAT(r3); + inst->operands[2].valid = true; + inst->operands[2].index = -1; + inst->operands[2].value = ia64_inst_get_imm9b(inst->inst); + inst->operands[2].nat = 0; + switch (x6) { + case 0x00: inst->mnemo = IA64_INST_LD1_UPDATE; break; + case 0x01: inst->mnemo = IA64_INST_LD2_UPDATE; break; + case 0x02: inst->mnemo = IA64_INST_LD4_UPDATE; break; + case 0x03: inst->mnemo = IA64_INST_LD8_UPDATE; break; + } + return true; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + inst->operands[0].valid = true; + inst->operands[0].index = r3; + inst->operands[0].value = IA64_GET_GR(r3); + inst->operands[0].nat = IA64_GET_NAT(r3); + inst->operands[1].valid = true; + inst->operands[1].index = r2; + inst->operands[1].value = IA64_GET_GR(r2); + inst->operands[1].nat = IA64_GET_NAT(r2); + inst->operands[2].valid = true; + inst->operands[2].index = -1; + inst->operands[2].value = ia64_inst_get_imm9a(inst->inst); + inst->operands[2].nat = 0; + switch (x6) { + case 0x30: inst->mnemo = IA64_INST_ST1_UPDATE; break; + case 0x31: inst->mnemo = IA64_INST_ST2_UPDATE; break; + case 0x32: inst->mnemo = IA64_INST_ST4_UPDATE; break; + case 0x33: inst->mnemo = IA64_INST_ST8_UPDATE; break; + } + return true; + } + return false; +} + +// Decode group 8 instructions (ALU integer) +static bool ia64_decode_instruction_8(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + const int r1 = (inst->inst >> 6) & 0x7f; + const int r2 = (inst->inst >> 13) & 0x7f; + const int r3 = (inst->inst >> 20) & 0x7f; + + const int x2a = (inst->inst >> 34) & 0x3; + const int x2b = (inst->inst >> 27) & 0x3; + const int x4 = (inst->inst >> 29) & 0xf; + const int ve = (inst->inst >> 33) & 0x1; + + // destination register (r1) is always valid in this group + inst->operands[0].valid = true; + inst->operands[0].index = r1; + + // source register (r3) is always valid in this group + inst->operands[2].valid = true; + inst->operands[2].index = r3; + inst->operands[2].value = IA64_GET_GR(r3); + inst->operands[2].nat = IA64_GET_NAT(r3); + + if (x2a == 0 && ve == 0) { + inst->operands[1].valid = true; + inst->operands[1].index = r2; + inst->operands[1].value = IA64_GET_GR(r2); + inst->operands[1].nat = IA64_GET_NAT(r2); + switch (x4) { + case 0x0: // add (A1) + inst->mnemo = IA64_INST_ADD; + inst->operands[3].valid = true; + inst->operands[3].index = -1; + inst->operands[3].value = x2b == 1; + return true; + case 0x1: // add (A1) + inst->mnemo = IA64_INST_SUB; + inst->operands[3].valid = true; + inst->operands[3].index = -1; + inst->operands[3].value = x2b == 0; + return true; + case 0x4: // shladd (A2) + inst->mnemo = IA64_INST_SHLADD; + inst->operands[3].valid = true; + inst->operands[3].index = -1; + inst->operands[3].value = ia64_inst_get_count2(inst->inst); + return true; + case 0x9: + if (x2b == 1) { + inst->mnemo = IA64_INST_SUB; + inst->operands[1].index = -1; + inst->operands[1].value = ia64_inst_get_imm8(inst->inst); + inst->operands[1].nat = 0; + return true; + } + break; + case 0xb: + inst->operands[1].index = -1; + inst->operands[1].value = ia64_inst_get_imm8(inst->inst); + inst->operands[1].nat = 0; + // fall-through + case 0x3: + switch (x2b) { + case 0: inst->mnemo = IA64_INST_AND; break; + case 1: inst->mnemo = IA64_INST_ANDCM; break; + case 2: inst->mnemo = IA64_INST_OR; break; + case 3: inst->mnemo = IA64_INST_XOR; break; + } + return true; + } + } + return false; +} + +// Decode instruction +static bool ia64_decode_instruction(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + const int major = (inst->inst >> 37) & 0xf; + + inst->mnemo = IA64_INST_UNKNOWN; + inst->pred = inst->inst & 0x3f; + memset(&inst->operands[0], 0, sizeof(inst->operands)); + + switch (major) { + case 0x0: return ia64_decode_instruction_0(inst, IA64_CONTEXT); + case 0x4: return ia64_decode_instruction_4(inst, IA64_CONTEXT); + case 0x5: return ia64_decode_instruction_5(inst, IA64_CONTEXT); + case 0x8: return ia64_decode_instruction_8(inst, IA64_CONTEXT); + } + return false; +} + +static bool ia64_emulate_instruction(ia64_instruction_t *inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + // XXX: handle Register NaT Consumption fault? + // XXX: this simple emulator assumes instructions in a bundle + // don't depend on effects of other instructions in the same + // bundle. It probably would be simpler to JIT-generate code to be + // executed natively but probably more costly (inject/extract CPU state) + if (inst->mnemo == IA64_INST_UNKNOWN) + return false; + if (inst->pred && !IA64_GET_PR(inst->pred)) + return true; + + uint8_t nat, nat2; + uint64_t dst, dst2, src1, src2, src3; + + switch (inst->mnemo) { + case IA64_INST_NOP: + break; + case IA64_INST_ADD: + case IA64_INST_SUB: + case IA64_INST_SHLADD: + src3 = inst->operands[3].value; + // fall-through + case IA64_INST_AND: + case IA64_INST_ANDCM: + case IA64_INST_OR: + case IA64_INST_XOR: + src1 = inst->operands[1].value; + src2 = inst->operands[2].value; + switch (inst->mnemo) { + case IA64_INST_ADD: dst = src1 + src2 + src3; break; + case IA64_INST_SUB: dst = src1 - src2 - src3; break; + case IA64_INST_SHLADD: dst = (src1 << src3) + src2; break; + case IA64_INST_AND: dst = src1 & src2; break; + case IA64_INST_ANDCM: dst = src1 &~ src2; break; + case IA64_INST_OR: dst = src1 | src2; break; + case IA64_INST_XOR: dst = src1 ^ src2; break; + } + inst->operands[0].commit = true; + inst->operands[0].value = dst; + inst->operands[0].nat = inst->operands[1].nat | inst->operands[2].nat; + break; + case IA64_INST_SXT1: + case IA64_INST_SXT2: + case IA64_INST_SXT4: + case IA64_INST_ZXT1: + case IA64_INST_ZXT2: + case IA64_INST_ZXT4: + src1 = inst->operands[1].value; + switch (inst->mnemo) { + case IA64_INST_SXT1: dst = (int64_t)(int8_t)src1; break; + case IA64_INST_SXT2: dst = (int64_t)(int16_t)src1; break; + case IA64_INST_SXT4: dst = (int64_t)(int32_t)src1; break; + case IA64_INST_ZXT1: dst = (uint8_t)src1; break; + case IA64_INST_ZXT2: dst = (uint16_t)src1; break; + case IA64_INST_ZXT4: dst = (uint32_t)src1; break; + } + inst->operands[0].commit = true; + inst->operands[0].value = dst; + inst->operands[0].nat = inst->operands[1].nat; + break; + case IA64_INST_LD1_UPDATE: + case IA64_INST_LD2_UPDATE: + case IA64_INST_LD4_UPDATE: + case IA64_INST_LD8_UPDATE: + inst->operands[1].commit = true; + dst2 = inst->operands[1].value + inst->operands[2].value; + nat2 = inst->operands[2].nat ? inst->operands[2].nat : 0; + // fall-through + case IA64_INST_LD1: + case IA64_INST_LD2: + case IA64_INST_LD4: + case IA64_INST_LD8: + src1 = inst->operands[1].value; + if (inst->no_memory) + dst = 0; + else { + switch (inst->mnemo) { + case IA64_INST_LD1: case IA64_INST_LD1_UPDATE: dst = *((uint8_t *)src1); break; + case IA64_INST_LD2: case IA64_INST_LD2_UPDATE: dst = *((uint16_t *)src1); break; + case IA64_INST_LD4: case IA64_INST_LD4_UPDATE: dst = *((uint32_t *)src1); break; + case IA64_INST_LD8: case IA64_INST_LD8_UPDATE: dst = *((uint64_t *)src1); break; + } + } + inst->operands[0].commit = true; + inst->operands[0].value = dst; + inst->operands[0].nat = 0; + inst->operands[1].value = dst2; + inst->operands[1].nat = nat2; + break; + case IA64_INST_ST1_UPDATE: + case IA64_INST_ST2_UPDATE: + case IA64_INST_ST4_UPDATE: + case IA64_INST_ST8_UPDATE: + inst->operands[0].commit = 0; + dst2 = inst->operands[0].value + inst->operands[2].value; + nat2 = inst->operands[2].nat ? inst->operands[2].nat : 0; + // fall-through + case IA64_INST_ST1: + case IA64_INST_ST2: + case IA64_INST_ST4: + case IA64_INST_ST8: + dst = inst->operands[0].value; + src1 = inst->operands[1].value; + if (!inst->no_memory) { + switch (inst->mnemo) { + case IA64_INST_ST1: case IA64_INST_ST1_UPDATE: *((uint8_t *)dst) = src1; break; + case IA64_INST_ST2: case IA64_INST_ST2_UPDATE: *((uint16_t *)dst) = src1; break; + case IA64_INST_ST4: case IA64_INST_ST4_UPDATE: *((uint32_t *)dst) = src1; break; + case IA64_INST_ST8: case IA64_INST_ST8_UPDATE: *((uint64_t *)dst) = src1; break; + } + } + inst->operands[0].value = dst2; + inst->operands[0].nat = nat2; + break; + default: + return false; + } + + for (int i = 0; i < IA64_N_OPERANDS; i++) { + ia64_operand_t const & op = inst->operands[i]; + if (!op.commit) + continue; + if (op.index == -1) + return false; // XXX: internal error + IA64_SET_GR(op.index, op.value, op.nat); + } + return true; +} + +static bool ia64_emulate_instruction(uint64_t raw_inst, IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + ia64_instruction_t inst; + memset(&inst, 0, sizeof(inst)); + inst.inst = raw_inst; + if (!ia64_decode_instruction(&inst, IA64_CONTEXT)) + return false; + return ia64_emulate_instruction(&inst, IA64_CONTEXT); +} + +static bool ia64_skip_instruction(IA64_CONTEXT_TYPE IA64_CONTEXT) +{ + uint64_t ip = IA64_GET_IP(); +#if DEBUG + printf("IP: 0x%016llx\n", ip); +#if 0 + printf(" Template 0x%02x\n", ia64_get_template(ip)); + ia64_get_instruction(ip, 0); + ia64_get_instruction(ip, 1); + ia64_get_instruction(ip, 2); +#endif +#endif + + // Select which decode switch to use + ia64_instruction_t inst; + inst.inst = ia64_get_instruction(ip, ip & 3); + if (!ia64_decode_instruction(&inst, IA64_CONTEXT)) { + fprintf(stderr, "ERROR: ia64_skip_instruction(): could not decode instruction\n"); + return false; + } + + transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; + transfer_size_t transfer_size = SIZE_UNKNOWN; + + switch (inst.mnemo) { + case IA64_INST_LD1: + case IA64_INST_LD2: + case IA64_INST_LD4: + case IA64_INST_LD8: + case IA64_INST_LD1_UPDATE: + case IA64_INST_LD2_UPDATE: + case IA64_INST_LD4_UPDATE: + case IA64_INST_LD8_UPDATE: + transfer_type = SIGSEGV_TRANSFER_LOAD; + break; + case IA64_INST_ST1: + case IA64_INST_ST2: + case IA64_INST_ST4: + case IA64_INST_ST8: + case IA64_INST_ST1_UPDATE: + case IA64_INST_ST2_UPDATE: + case IA64_INST_ST4_UPDATE: + case IA64_INST_ST8_UPDATE: + transfer_type = SIGSEGV_TRANSFER_STORE; + break; + } + + if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { + // Unknown machine code, let it crash. Then patch the decoder + fprintf(stderr, "ERROR: ia64_skip_instruction(): not a load/store instruction\n"); + return false; + } + + switch (inst.mnemo) { + case IA64_INST_LD1: + case IA64_INST_LD1_UPDATE: + case IA64_INST_ST1: + case IA64_INST_ST1_UPDATE: + transfer_size = SIZE_BYTE; + break; + case IA64_INST_LD2: + case IA64_INST_LD2_UPDATE: + case IA64_INST_ST2: + case IA64_INST_ST2_UPDATE: + transfer_size = SIZE_WORD; + break; + case IA64_INST_LD4: + case IA64_INST_LD4_UPDATE: + case IA64_INST_ST4: + case IA64_INST_ST4_UPDATE: + transfer_size = SIZE_LONG; + break; + case IA64_INST_LD8: + case IA64_INST_LD8_UPDATE: + case IA64_INST_ST8: + case IA64_INST_ST8_UPDATE: + transfer_size = SIZE_QUAD; + break; + } + + if (transfer_size == SIZE_UNKNOWN) { + // Unknown machine code, let it crash. Then patch the decoder + fprintf(stderr, "ERROR: ia64_skip_instruction(): unknown transfer size\n"); + return false; + } + + inst.no_memory = true; + if (!ia64_emulate_instruction(&inst, IA64_CONTEXT)) { + fprintf(stderr, "ERROR: ia64_skip_instruction(): could not emulate fault instruction\n"); + return false; + } + + int slot = ip & 3; + bool emulate_next = false; + switch (slot) { + case 0: + switch (ia64_get_template(ip)) { + case 0x2: // MI;I + case 0x3: // MI;I; + emulate_next = true; + slot = 2; + break; + case 0xa: // M;MI + case 0xb: // M;MI; + emulate_next = true; + slot = 1; + break; + } + break; + } + if (emulate_next && !IA64_CAN_PATCH_IP_SLOT) { + while (slot < 3) { + if (!ia64_emulate_instruction(ia64_get_instruction(ip, slot), IA64_CONTEXT)) { + fprintf(stderr, "ERROR: ia64_skip_instruction(): could not emulate instruction\n"); + return false; + } + ++slot; + } + } + +#if IA64_CAN_PATCH_IP_SLOT + if ((slot = ip & 3) < 2) + IA64_SET_IP((ip & ~3ull) + (slot + 1)); + else +#endif + IA64_SET_IP((ip & ~3ull) + 16); +#if DEBUG + printf("IP: 0x%016llx\n", IA64_GET_IP()); +#endif + return true; +} +#endif + +// Decode and skip PPC instruction +#if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)) +static bool powerpc_skip_instruction(unsigned long * nip_p, unsigned long * regs) +{ + instruction_t instr; + powerpc_decode_instruction(&instr, *nip_p, regs); + + if (instr.transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { + // Unknown machine code, let it crash. Then patch the decoder + return false; + } + +#if DEBUG + printf("%08x: %s %s access", *nip_p, + instr.transfer_size == SIZE_BYTE ? "byte" : + instr.transfer_size == SIZE_WORD ? "word" : + instr.transfer_size == SIZE_LONG ? "long" : "quad", + instr.transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write"); + + if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX) + printf(" r%d (ra = %08x)\n", instr.ra, instr.addr); + if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD) + printf(" r%d (rd = 0)\n", instr.rd); +#endif + + if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX) + regs[instr.ra] = instr.addr; + if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD) + regs[instr.rd] = 0; + + *nip_p += 4; + return true; +} +#endif + +// Decode and skip MIPS instruction +#if (defined(mips) || defined(__mips)) +static bool mips_skip_instruction(greg_t * pc_p, greg_t * regs) +{ + unsigned int * epc = (unsigned int *)(unsigned long)*pc_p; + + if (epc == 0) + return false; + +#if DEBUG + printf("IP: %p [%08x]\n", epc, epc[0]); +#endif + + transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; + transfer_size_t transfer_size = SIZE_LONG; + int direction = 0; + + const unsigned int opcode = epc[0]; + switch (opcode >> 26) { + case 32: // Load Byte + case 36: // Load Byte Unsigned + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_BYTE; + break; + case 33: // Load Halfword + case 37: // Load Halfword Unsigned + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_WORD; + break; + case 35: // Load Word + case 39: // Load Word Unsigned + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_LONG; + break; + case 34: // Load Word Left + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_LONG; + direction = -1; + break; + case 38: // Load Word Right + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_LONG; + direction = 1; + break; + case 55: // Load Doubleword + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_QUAD; + break; + case 26: // Load Doubleword Left + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_QUAD; + direction = -1; + break; + case 27: // Load Doubleword Right + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_QUAD; + direction = 1; + break; + case 40: // Store Byte + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_BYTE; + break; + case 41: // Store Halfword + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_WORD; + break; + case 43: // Store Word + case 42: // Store Word Left + case 46: // Store Word Right + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_LONG; + break; + case 63: // Store Doubleword + case 44: // Store Doubleword Left + case 45: // Store Doubleword Right + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_QUAD; + break; + /* Misc instructions unlikely to be used within CPU emulators */ + case 48: // Load Linked Word + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_LONG; + break; + case 52: // Load Linked Doubleword + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_QUAD; + break; + case 56: // Store Conditional Word + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_LONG; + break; + case 60: // Store Conditional Doubleword + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_QUAD; + break; + } + + if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { + // Unknown machine code, let it crash. Then patch the decoder + return false; + } + + // Zero target register in case of a load operation + const int reg = (opcode >> 16) & 0x1f; + if (transfer_type == SIGSEGV_TRANSFER_LOAD) { + if (direction == 0) + regs[reg] = 0; + else { + // FIXME: untested code + unsigned long ea = regs[(opcode >> 21) & 0x1f]; + ea += (signed long)(signed int)(signed short)(opcode & 0xffff); + const int offset = ea & (transfer_size == SIZE_LONG ? 3 : 7); + unsigned long value; + if (direction > 0) { + const unsigned long rmask = ~((1L << ((offset + 1) * 8)) - 1); + value = regs[reg] & rmask; + } + else { + const unsigned long lmask = (1L << (offset * 8)) - 1; + value = regs[reg] & lmask; + } + // restore most significant bits + if (transfer_size == SIZE_LONG) + value = (signed long)(signed int)value; + regs[reg] = value; + } + } + +#if DEBUG +#if (defined(_ABIN32) || defined(_ABI64)) + static const char * mips_gpr_names[32] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" + }; +#else + static const char * mips_gpr_names[32] = { + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" + }; +#endif + printf("%s %s register %s\n", + transfer_size == SIZE_BYTE ? "byte" : + transfer_size == SIZE_WORD ? "word" : + transfer_size == SIZE_LONG ? "long" : + transfer_size == SIZE_QUAD ? "quad" : "unknown", + transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from", + mips_gpr_names[reg]); +#endif + + *pc_p += 4; + return true; +} +#endif + +// Decode and skip SPARC instruction +#if (defined(sparc) || defined(__sparc__)) +enum { +#if (defined(__sun__)) + SPARC_REG_G1 = REG_G1, + SPARC_REG_O0 = REG_O0, + SPARC_REG_PC = REG_PC, + SPARC_REG_nPC = REG_nPC +#endif +}; +static bool sparc_skip_instruction(unsigned long * regs, gwindows_t * gwins, struct rwindow * rwin) +{ + unsigned int * pc = (unsigned int *)regs[SPARC_REG_PC]; + + if (pc == 0) + return false; + +#if DEBUG + printf("IP: %p [%08x]\n", pc, pc[0]); +#endif + + transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; + transfer_size_t transfer_size = SIZE_LONG; + bool register_pair = false; + + const unsigned int opcode = pc[0]; + if ((opcode >> 30) != 3) + return false; + switch ((opcode >> 19) & 0x3f) { + case 9: // Load Signed Byte + case 1: // Load Unsigned Byte + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_BYTE; + break; + case 10:// Load Signed Halfword + case 2: // Load Unsigned Word + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_WORD; + break; + case 8: // Load Word + case 0: // Load Unsigned Word + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_LONG; + break; + case 11:// Load Extended Word + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_QUAD; + break; + case 3: // Load Doubleword + transfer_type = SIGSEGV_TRANSFER_LOAD; + transfer_size = SIZE_LONG; + register_pair = true; + break; + case 5: // Store Byte + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_BYTE; + break; + case 6: // Store Halfword + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_WORD; + break; + case 4: // Store Word + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_LONG; + break; + case 14:// Store Extended Word + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_QUAD; + break; + case 7: // Store Doubleword + transfer_type = SIGSEGV_TRANSFER_STORE; + transfer_size = SIZE_LONG; + register_pair = true; + break; + } + + if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) { + // Unknown machine code, let it crash. Then patch the decoder + return false; + } + + const int reg = (opcode >> 25) & 0x1f; + +#if DEBUG + static const char * reg_names[] = { + "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7" + }; + printf("%s %s register %s\n", + transfer_size == SIZE_BYTE ? "byte" : + transfer_size == SIZE_WORD ? "word" : + transfer_size == SIZE_LONG ? "long" : + transfer_size == SIZE_QUAD ? "quad" : "unknown", + transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from", + reg_names[reg]); +#endif + + // Zero target register in case of a load operation + if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != 0) { + // FIXME: code to handle local & input registers is not tested + if (reg >= 1 && reg < 8) { + // global registers + regs[reg - 1 + SPARC_REG_G1] = 0; + } + else if (reg >= 8 && reg < 16) { + // output registers + regs[reg - 8 + SPARC_REG_O0] = 0; + } + else if (reg >= 16 && reg < 24) { + // local registers (in register windows) + if (gwins) + gwins->wbuf->rw_local[reg - 16] = 0; + else + rwin->rw_local[reg - 16] = 0; + } + else { + // input registers (in register windows) + if (gwins) + gwins->wbuf->rw_in[reg - 24] = 0; + else + rwin->rw_in[reg - 24] = 0; + } + } + + regs[SPARC_REG_PC] += 4; + regs[SPARC_REG_nPC] += 4; + return true; +} +#endif +#endif + +// Decode and skip ARM instruction +#if (defined(arm) || defined(__arm__)) +enum { +#if (defined(__linux__)) + ARM_REG_PC = 15, + ARM_REG_CPSR = 16 +#endif +}; +static bool arm_skip_instruction(unsigned long * regs) +{ + unsigned int * pc = (unsigned int *)regs[ARM_REG_PC]; + + if (pc == 0) + return false; + +#if DEBUG + printf("IP: %p [%08x]\n", pc, pc[0]); +#endif + + transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN; + transfer_size_t transfer_size = SIZE_UNKNOWN; + enum { op_sdt = 1, op_sdth = 2 }; + int op = 0; + + // Handle load/store instructions only + const unsigned int opcode = pc[0]; + switch ((opcode >> 25) & 7) { + case 0: // Halfword and Signed Data Transfer (LDRH, STRH, LDRSB, LDRSH) + op = op_sdth; + // Determine transfer size (S/H bits) + switch ((opcode >> 5) & 3) { + case 0: // SWP instruction + break; + case 1: // Unsigned halfwords + case 3: // Signed halfwords + transfer_size = SIZE_WORD; + break; + case 2: // Signed byte + transfer_size = SIZE_BYTE; + break; + } + break; + case 2: + case 3: // Single Data Transfer (LDR, STR) + op = op_sdt; + // Determine transfer size (B bit) + if (((opcode >> 22) & 1) == 1) + transfer_size = SIZE_BYTE; + else + transfer_size = SIZE_LONG; + break; + default: + // FIXME: support load/store mutliple? + return false; + } + + // Check for invalid transfer size (SWP instruction?) + if (transfer_size == SIZE_UNKNOWN) + return false; + + // Determine transfer type (L bit) + if (((opcode >> 20) & 1) == 1) + transfer_type = SIGSEGV_TRANSFER_LOAD; + else + transfer_type = SIGSEGV_TRANSFER_STORE; + + // Compute offset + int offset; + if (((opcode >> 25) & 1) == 0) { + if (op == op_sdt) + offset = opcode & 0xfff; + else if (op == op_sdth) { + int rm = opcode & 0xf; + if (((opcode >> 22) & 1) == 0) { + // register offset + offset = regs[rm]; + } + else { + // immediate offset + offset = ((opcode >> 4) & 0xf0) | (opcode & 0x0f); + } + } + } + else { + const int rm = opcode & 0xf; + const int sh = (opcode >> 7) & 0x1f; + if (((opcode >> 4) & 1) == 1) { + // we expect only legal load/store instructions + printf("FATAL: invalid shift operand\n"); + return false; + } + const unsigned int v = regs[rm]; + switch ((opcode >> 5) & 3) { + case 0: // logical shift left + offset = sh ? v << sh : v; + break; + case 1: // logical shift right + offset = sh ? v >> sh : 0; + break; + case 2: // arithmetic shift right + if (sh) + offset = ((signed int)v) >> sh; + else + offset = (v & 0x80000000) ? 0xffffffff : 0; + break; + case 3: // rotate right + if (sh) + offset = (v >> sh) | (v << (32 - sh)); + else + offset = (v >> 1) | ((regs[ARM_REG_CPSR] << 2) & 0x80000000); + break; + } + } + if (((opcode >> 23) & 1) == 0) + offset = -offset; + + int rd = (opcode >> 12) & 0xf; + int rn = (opcode >> 16) & 0xf; +#if DEBUG + static const char * reg_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r9", "r9", "sl", "fp", "ip", "sp", "lr", "pc" + }; + printf("%s %s register %s\n", + transfer_size == SIZE_BYTE ? "byte" : + transfer_size == SIZE_WORD ? "word" : + transfer_size == SIZE_LONG ? "long" : "unknown", + transfer_type == SIGSEGV_TRANSFER_LOAD ? "load to" : "store from", + reg_names[rd]); +#endif + + unsigned int base = regs[rn]; + if (((opcode >> 24) & 1) == 1) + base += offset; + + if (transfer_type == SIGSEGV_TRANSFER_LOAD) + regs[rd] = 0; + + if (((opcode >> 24) & 1) == 0) // post-index addressing + regs[rn] += offset; + else if (((opcode >> 21) & 1) == 1) // write-back address into base + regs[rn] = base; + + regs[ARM_REG_PC] += 4; + return true; +} +#endif + +#ifdef _STRUCT_ARM_THREAD_STATE64 +static bool aarch64_skip_instruction(unsigned long *regs) { + _STRUCT_ARM_THREAD_STATE64 *ts = (_STRUCT_ARM_THREAD_STATE64 *)regs; + if (!ts->__pc) return false; + ts->__pc += 4; + return true; +} +#endif + +// Fallbacks +#ifndef SIGSEGV_FAULT_ADDRESS_FAST +#define SIGSEGV_FAULT_ADDRESS_FAST SIGSEGV_FAULT_ADDRESS +#endif +#ifndef SIGSEGV_FAULT_INSTRUCTION_FAST +#define SIGSEGV_FAULT_INSTRUCTION_FAST SIGSEGV_FAULT_INSTRUCTION +#endif +#ifndef SIGSEGV_FAULT_INSTRUCTION +#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_INVALID_ADDRESS +#endif +#ifndef SIGSEGV_FAULT_HANDLER_ARGLIST_1 +#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 SIGSEGV_FAULT_HANDLER_ARGLIST +#endif +#ifndef SIGSEGV_FAULT_HANDLER_INVOKE +#define SIGSEGV_FAULT_HANDLER_INVOKE(P) sigsegv_fault_handler(P) +#endif + +// SIGSEGV recovery supported ? +#if defined(SIGSEGV_ALL_SIGNALS) && defined(SIGSEGV_FAULT_HANDLER_ARGLIST) && defined(SIGSEGV_FAULT_ADDRESS) +#define HAVE_SIGSEGV_RECOVERY +#endif + + +/* + * SIGSEGV global handler + */ + +#ifdef HAVE_MACH_EXCEPTIONS +#ifdef EMULATED_PPC +static void mach_get_exception_state(sigsegv_info_t *SIP) +{ + SIP->exc_state_count = SIGSEGV_EXCEPTION_STATE_COUNT; + kern_return_t krc = thread_get_state(SIP->thread, + SIGSEGV_EXCEPTION_STATE_FLAVOR, + (natural_t *)&SIP->exc_state, + &SIP->exc_state_count); + MACH_CHECK_ERROR(thread_get_state, krc); + SIP->has_exc_state = true; +} +#endif + +static void mach_get_thread_state(sigsegv_info_t *SIP) +{ + SIP->thr_state_count = SIGSEGV_THREAD_STATE_COUNT; + kern_return_t krc = thread_get_state(SIP->thread, + SIGSEGV_THREAD_STATE_FLAVOR, + (natural_t *)&SIP->thr_state, + &SIP->thr_state_count); + MACH_CHECK_ERROR(thread_get_state, krc); + SIP->has_thr_state = true; +} + +static void mach_set_thread_state(sigsegv_info_t *SIP) +{ + kern_return_t krc = thread_set_state(SIP->thread, + SIGSEGV_THREAD_STATE_FLAVOR, + (natural_t *)&SIP->thr_state, + SIP->thr_state_count); + MACH_CHECK_ERROR(thread_set_state, krc); +} +#endif + +// Return the address of the invalid memory reference +sigsegv_address_t sigsegv_get_fault_address(sigsegv_info_t *SIP) +{ +#ifdef HAVE_MACH_EXCEPTIONS +#ifdef EMULATED_PPC + static int use_fast_path = -1; + if (use_fast_path != 1 && !SIP->has_exc_state) { + mach_get_exception_state(SIP); + + sigsegv_address_t addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS; + if (use_fast_path < 0) { + const char *machfault = getenv("SIGSEGV_MACH_FAULT"); + if (machfault) { + if (strcmp(machfault, "fast") == 0) + use_fast_path = 1; + else if (strcmp(machfault, "slow") == 0) + use_fast_path = 0; + } + if (use_fast_path < 0) + use_fast_path = addr == SIP->addr; + } + SIP->addr = addr; + } +#endif +#endif + return SIP->addr; +} + +// Return the address of the instruction that caused the fault, or +// SIGSEGV_INVALID_ADDRESS if we could not retrieve this information +sigsegv_address_t sigsegv_get_fault_instruction_address(sigsegv_info_t *SIP) +{ +#ifdef HAVE_MACH_EXCEPTIONS +#ifdef EMULATED_PPC + if (!SIP->has_thr_state) { + mach_get_thread_state(SIP); + + SIP->pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION; + } +#endif +#endif + return SIP->pc; +} + +#if defined(__APPLE__) && defined(__x86_64__) + +#ifdef CONFIGURE_TEST_SIGSEGV_RECOVERY +#define EXTERN +#else +#define EXTERN extern +#endif + +EXTERN uint8_t gZeroPage[0x3000], gKernelData[0x2000]; +EXTERN uint32_t RAMBase, ROMBase, ROMEnd; + +template T safeLoad(uint32_t a) { + if (a < 0x3000) return *(T *)&gZeroPage[a]; + else if ((a & ~0x1fff) == 0x68ffe000 || (a & ~0x1fff) == 0x5fffe000) return *(T *)&gKernelData[a & 0x1fff]; + else if (a >= RAMBase && a < ROMEnd) return *(T *)(uint64_t)a; + return 0; +} +template void safeStore(uint32_t a, T d) { + if (a < 0x3000) *(T *)&gZeroPage[a] = d; + else if ((a & ~0x1fff) == 0x68ffe000 || (a & ~0x1fff) == 0x5fffe000) *(T *)&gKernelData[a & 0x1fff] = d; + else if (a >= RAMBase && a < ROMBase) *(T *)(uint64_t)a = d; +} + +#endif + +// This function handles the badaccess to memory. +// It is called from the signal handler or the exception handler. +static bool handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGLIST_1) +{ + sigsegv_info_t SI; + SI.addr = (sigsegv_address_t)SIGSEGV_FAULT_ADDRESS_FAST; + SI.pc = (sigsegv_address_t)SIGSEGV_FAULT_INSTRUCTION_FAST; +#ifdef HAVE_MACH_EXCEPTIONS + SI.thread = thread; + SI.has_exc_state = false; + SI.has_thr_state = false; +#endif + sigsegv_info_t * const SIP = &SI; + +#if defined(__APPLE__) && defined(__x86_64__) + if (!SIP->has_thr_state) + mach_get_thread_state(SIP); + x86_thread_state64_t *ts = &SIP->thr_state; + uint8_t *rip = (uint8_t *)ts->__rip; + switch (rip[0]) { + case 0xf: + if (rip[1] == 0xb7 && rip[2] == 0) { + ts->__rax = safeLoad(ts->__rax); + ts->__rip += 3; + mach_set_thread_state(SIP); + return true; + } + break; + case 0x44: + if (rip[1] == 0xf && rip[2] == 0xb6 && rip[3] == 0x20) { + ts->__r12 = safeLoad(ts->__rax); + ts->__rip += 4; + mach_set_thread_state(SIP); + return true; + } + break; + case 0x48: + if (rip[1] == 0xc7 && rip[2] == 0) { + safeStore(ts->__rax, rip[3] | rip[4] << 8 | rip[5] << 16 | rip[6] << 24); + ts->__rip += 7; + mach_set_thread_state(SIP); + return true; + } + else if (rip[1] == 0xc7 && rip[2] == 0x40) { + safeStore(ts->__rax + (signed char)rip[3], rip[4] | rip[5] << 8 | rip[6] << 16 | rip[7] << 24); + ts->__rip += 8; + mach_set_thread_state(SIP); + return true; + } + break; + case 0x89: + if (rip[1] == 2) { + safeStore(ts->__rdx, ts->__rax); + ts->__rip += 2; + mach_set_thread_state(SIP); + return true; + } + else if (rip[1] == 0x10) { + safeStore(ts->__rax, ts->__rdx); + ts->__rip += 2; + mach_set_thread_state(SIP); + return true; + } + break; + case 0x8b: + if (rip[1] == 0) { + ts->__rax = safeLoad(ts->__rax); + ts->__rip += 2; + mach_set_thread_state(SIP); + return true; + } + break; + } +#endif + // Call user's handler and reinstall the global handler, if required + switch (SIGSEGV_FAULT_HANDLER_INVOKE(SIP)) { + case SIGSEGV_RETURN_SUCCESS: + return true; + +#if HAVE_SIGSEGV_SKIP_INSTRUCTION + case SIGSEGV_RETURN_SKIP_INSTRUCTION: + // Call the instruction skipper with the register file + // available +#ifdef HAVE_MACH_EXCEPTIONS + if (!SIP->has_thr_state) + mach_get_thread_state(SIP); +#endif + if (SIGSEGV_SKIP_INSTRUCTION(SIGSEGV_REGISTER_FILE)) { +#ifdef HAVE_MACH_EXCEPTIONS + // Unlike UNIX signals where the thread state + // is modified off of the stack, in Mach we + // need to actually call thread_set_state to + // have the register values updated. + mach_set_thread_state(SIP); +#endif + return true; + } + break; +#endif + case SIGSEGV_RETURN_FAILURE: + // We can't do anything with the fault_address, dump state? + if (sigsegv_state_dumper != 0) + sigsegv_state_dumper(SIP); + break; + } + + return false; +} + + +/* + * There are two mechanisms for handling a bad memory access, + * Mach exceptions and UNIX signals. The implementation specific + * code appears below. Its reponsibility is to call handle_badaccess + * which is the routine that handles the fault in an implementation + * agnostic manner. The implementation specific code below is then + * reponsible for checking whether handle_badaccess was able + * to handle the memory access error and perform any implementation + * specific tasks necessary afterwards. + */ + +#ifdef HAVE_MACH_EXCEPTIONS +/* + * We need to forward all exceptions that we do not handle. + * This is important, there are many exceptions that may be + * handled by other exception handlers. For example debuggers + * use exceptions and the exception hander is in another + * process in such a case. (Timothy J. Wood states in his + * message to the list that he based this code on that from + * gdb for Darwin.) + */ +static inline kern_return_t +forward_exception(mach_port_t thread_port, + mach_port_t task_port, + exception_type_t exception_type, + mach_exception_data_t exception_data, + mach_msg_type_number_t data_count, + ExceptionPorts *oldExceptionPorts) +{ + kern_return_t kret; + unsigned int portIndex; + mach_port_t port; + exception_behavior_t behavior; + thread_state_flavor_t flavor; + thread_state_data_t thread_state; + mach_msg_type_number_t thread_state_count; + + for (portIndex = 0; portIndex < oldExceptionPorts->maskCount; portIndex++) { + if (oldExceptionPorts->masks[portIndex] & (1 << exception_type)) { + // This handler wants the exception + break; + } + } + + if (portIndex >= oldExceptionPorts->maskCount) { + fprintf(stderr, "No handler for exception_type = %d. Not fowarding\n", exception_type); + return KERN_FAILURE; + } + + port = oldExceptionPorts->handlers[portIndex]; + behavior = oldExceptionPorts->behaviors[portIndex]; + flavor = oldExceptionPorts->flavors[portIndex]; + + if (!VALID_THREAD_STATE_FLAVOR(flavor)) { + fprintf(stderr, "Invalid thread_state flavor = %d. Not forwarding\n", flavor); + return KERN_FAILURE; + } + + /* + fprintf(stderr, "forwarding exception, port = 0x%x, behaviour = %d, flavor = %d\n", port, behavior, flavor); + */ + + if (behavior != EXCEPTION_DEFAULT) { + thread_state_count = THREAD_STATE_MAX; + kret = thread_get_state (thread_port, flavor, (natural_t *)&thread_state, + &thread_state_count); + MACH_CHECK_ERROR (thread_get_state, kret); + } + + switch (behavior) { + case EXCEPTION_DEFAULT: + // fprintf(stderr, "forwarding to exception_raise\n"); + kret = mach_exception_raise(port, thread_port, task_port, exception_type, + exception_data, data_count); + MACH_CHECK_ERROR (mach_exception_raise, kret); + break; + case EXCEPTION_STATE: + // fprintf(stderr, "forwarding to exception_raise_state\n"); + kret = mach_exception_raise_state(port, exception_type, exception_data, + data_count, &flavor, + (natural_t *)&thread_state, thread_state_count, + (natural_t *)&thread_state, &thread_state_count); + MACH_CHECK_ERROR (mach_exception_raise_state, kret); + break; + case EXCEPTION_STATE_IDENTITY: + // fprintf(stderr, "forwarding to exception_raise_state_identity\n"); + kret = mach_exception_raise_state_identity(port, thread_port, task_port, + exception_type, exception_data, + data_count, &flavor, + (natural_t *)&thread_state, thread_state_count, + (natural_t *)&thread_state, &thread_state_count); + MACH_CHECK_ERROR (mach_exception_raise_state_identity, kret); + break; + default: + fprintf(stderr, "forward_exception got unknown behavior\n"); + kret = KERN_FAILURE; + break; + } + + if (behavior != EXCEPTION_DEFAULT) { + kret = thread_set_state (thread_port, flavor, (natural_t *)&thread_state, + thread_state_count); + MACH_CHECK_ERROR (thread_set_state, kret); + } + + return kret; +} + +/* + * This is the code that actually handles the exception. + * It is called by exc_server. For Darwin 5 Apple changed + * this a bit from how this family of functions worked in + * Mach. If you are familiar with that it is a little + * different. The main variation that concerns us here is + * that code is an array of exception specific codes and + * codeCount is a count of the number of codes in the code + * array. In typical Mach all exceptions have a code + * and sub-code. It happens to be the case that for a + * EXC_BAD_ACCESS exception the first entry is the type of + * bad access that occurred and the second entry is the + * faulting address so these entries correspond exactly to + * how the code and sub-code are used on Mach. + * + * This is a MIG interface. No code in Basilisk II should + * call this directley. This has to have external C + * linkage because that is what exc_server expects. + */ +kern_return_t +catch_mach_exception_raise(mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t code_count) +{ + kern_return_t krc; + + if (exception == EXC_BAD_ACCESS) { + switch (code[0]) { + case KERN_PROTECTION_FAILURE: + case KERN_INVALID_ADDRESS: + if (handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGS)) + return KERN_SUCCESS; + break; + } + } + + // In Mach we do not need to remove the exception handler. + // If we forward the exception, eventually some exception handler + // will take care of this exception. + krc = forward_exception(thread, task, exception, code, code_count, &ports); + + return krc; +} + +/* XXX: borrowed from launchd and gdb */ +kern_return_t +catch_mach_exception_raise_state(mach_port_t exception_port, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t code_count, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_state_count, + thread_state_t new_state, + mach_msg_type_number_t *new_state_count) +{ + memcpy(new_state, old_state, old_state_count * sizeof(old_state[0])); + *new_state_count = old_state_count; + return KERN_SUCCESS; +} + +/* XXX: borrowed from launchd and gdb */ +kern_return_t +catch_mach_exception_raise_state_identity(mach_port_t exception_port, + mach_port_t thread_port, + mach_port_t task_port, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t code_count, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_state_count, + thread_state_t new_state, + mach_msg_type_number_t *new_state_count) +{ + kern_return_t kret; + + memcpy(new_state, old_state, old_state_count * sizeof(old_state[0])); + *new_state_count = old_state_count; + + kret = mach_port_deallocate(mach_task_self(), task_port); + MACH_CHECK_ERROR(mach_port_deallocate, kret); + kret = mach_port_deallocate(mach_task_self(), thread_port); + MACH_CHECK_ERROR(mach_port_deallocate, kret); + + return KERN_SUCCESS; +} +#endif + +#ifdef HAVE_SIGSEGV_RECOVERY +// Handle bad memory accesses with signal handler +static void sigsegv_handler(SIGSEGV_FAULT_HANDLER_ARGLIST) +{ + // Call handler and reinstall the global handler, if required + if (handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGS)) { +#if (defined(HAVE_SIGACTION) ? defined(SIGACTION_NEED_REINSTALL) : defined(SIGNAL_NEED_REINSTALL)) + sigsegv_do_install_handler(sig); +#endif + return; + } + + // Failure: reinstall default handler for "safe" crash +#define FAULT_HANDLER(sig) signal(sig, SIG_DFL); + SIGSEGV_ALL_SIGNALS +#undef FAULT_HANDLER +} +#endif + + +/* + * SIGSEGV handler initialization + */ + +#if defined(HAVE_SIGINFO_T) +static bool sigsegv_do_install_handler(int sig) +{ + // Setup SIGSEGV handler to process writes to frame buffer +#ifdef HAVE_SIGACTION + struct sigaction sigsegv_sa; + memset(&sigsegv_sa, 0, sizeof(struct sigaction)); + sigemptyset(&sigsegv_sa.sa_mask); + sigsegv_sa.sa_sigaction = sigsegv_handler; + sigsegv_sa.sa_flags = SA_SIGINFO; + return (sigaction(sig, &sigsegv_sa, 0) == 0); +#else + return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR); +#endif +} +#endif + +#if defined(HAVE_SIGCONTEXT_SUBTERFUGE) +static bool sigsegv_do_install_handler(int sig) +{ + // Setup SIGSEGV handler to process writes to frame buffer +#ifdef HAVE_SIGACTION + struct sigaction sigsegv_sa; + memset(&sigsegv_sa, 0, sizeof(struct sigaction)); + 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); +#endif +} +#endif + +#if defined(HAVE_MACH_EXCEPTIONS) +static bool sigsegv_do_install_handler(sigsegv_fault_handler_t handler) +{ + /* + * Except for the exception port functions, this should be + * pretty much stock Mach. If later you choose to support + * other Mach's besides Darwin, just check for __MACH__ + * here and __APPLE__ where the actual differences are. + */ +#if defined(__APPLE__) && defined(__MACH__) + if (sigsegv_fault_handler != NULL) { + sigsegv_fault_handler = handler; + return true; + } + + kern_return_t krc; + + // create the the exception port + krc = mach_port_allocate(mach_task_self(), + MACH_PORT_RIGHT_RECEIVE, &_exceptionPort); + if (krc != KERN_SUCCESS) { + mach_error("mach_port_allocate", krc); + return false; + } + + // add a port send right + krc = mach_port_insert_right(mach_task_self(), + _exceptionPort, _exceptionPort, + MACH_MSG_TYPE_MAKE_SEND); + if (krc != KERN_SUCCESS) { + mach_error("mach_port_insert_right", krc); + return false; + } + + // get the old exception ports + ports.maskCount = sizeof (ports.masks) / sizeof (ports.masks[0]); + krc = thread_get_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, ports.masks, + &ports.maskCount, ports.handlers, ports.behaviors, ports.flavors); + if (krc != KERN_SUCCESS) { + mach_error("thread_get_exception_ports", krc); + return false; + } + + // set the new exception port + // + // We could have used EXCEPTION_STATE_IDENTITY instead of + // EXCEPTION_DEFAULT to get the thread state in the initial + // message, but it turns out that in the common case this is not + // neccessary. If we need it we can later ask for it from the + // suspended thread. + // + // Even with THREAD_STATE_NONE, Darwin provides the program + // counter in the thread state. The comments in the header file + // seem to imply that you can count on the GPR's on an exception + // as well but just to be safe I use MACHINE_THREAD_STATE because + // you have to ask for all of the GPR's anyway just to get the + // program counter. In any case because of update effective + // address from immediate and update address from effective + // addresses of ra and rb modes (as good an name as any for these + // addressing modes) used in PPC instructions, you will need the + // GPR state anyway. + krc = thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, _exceptionPort, + EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, SIGSEGV_THREAD_STATE_FLAVOR); + if (krc != KERN_SUCCESS) { + mach_error("thread_set_exception_ports", krc); + return false; + } + + // create the exception handler thread + if (pthread_create(&exc_thread, NULL, &handleExceptions, NULL) != 0) { + (void)fprintf(stderr, "creation of exception thread failed\n"); + return false; + } + + // do not care about the exception thread any longer, let is run standalone + (void)pthread_detach(exc_thread); + + sigsegv_fault_handler = handler; + return true; +#else + return false; +#endif +} +#endif + +#ifdef HAVE_WIN32_EXCEPTIONS +static LONG WINAPI main_exception_filter(EXCEPTION_POINTERS *ExceptionInfo) +{ + if (sigsegv_fault_handler != NULL + && ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION + && ExceptionInfo->ExceptionRecord->NumberParameters >= 2 + && handle_badaccess(ExceptionInfo)) + return EXCEPTION_CONTINUE_EXECUTION; + + return EXCEPTION_CONTINUE_SEARCH; +} + +#if defined __CYGWIN__ && defined __i386__ +/* In Cygwin programs, SetUnhandledExceptionFilter has no effect because Cygwin + installs a global exception handler. We have to dig deep in order to install + our main_exception_filter. */ + +/* Data structures for the current thread's exception handler chain. + On the x86 Windows uses register fs, offset 0 to point to the current + exception handler; Cygwin mucks with it, so we must do the same... :-/ */ + +/* Magic taken from winsup/cygwin/include/exceptions.h. */ + +struct exception_list { + struct exception_list *prev; + int (*handler) (EXCEPTION_RECORD *, void *, CONTEXT *, void *); +}; +typedef struct exception_list exception_list; + +/* Magic taken from winsup/cygwin/exceptions.cc. */ + +__asm__ (".equ __except_list,0"); + +extern exception_list *_except_list __asm__ ("%fs:__except_list"); + +/* For debugging. _except_list is not otherwise accessible from gdb. */ +static exception_list * +debug_get_except_list () +{ + return _except_list; +} + +/* Cygwin's original exception handler. */ +static int (*cygwin_exception_handler) (EXCEPTION_RECORD *, void *, CONTEXT *, void *); + +/* Our exception handler. */ +static int +libsigsegv_exception_handler (EXCEPTION_RECORD *exception, void *frame, CONTEXT *context, void *dispatch) +{ + EXCEPTION_POINTERS ExceptionInfo; + ExceptionInfo.ExceptionRecord = exception; + ExceptionInfo.ContextRecord = context; + if (main_exception_filter (&ExceptionInfo) == EXCEPTION_CONTINUE_SEARCH) + return cygwin_exception_handler (exception, frame, context, dispatch); + else + return 0; +} + +static void +do_install_main_exception_filter () +{ + /* We cannot insert any handler into the chain, because such handlers + must lie on the stack (?). Instead, we have to replace(!) Cygwin's + global exception handler. */ + cygwin_exception_handler = _except_list->handler; + _except_list->handler = libsigsegv_exception_handler; +} + +#else + +static void +do_install_main_exception_filter () +{ + SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) &main_exception_filter); +} +#endif + +static bool sigsegv_do_install_handler(sigsegv_fault_handler_t handler) +{ + static bool main_exception_filter_installed = false; + if (!main_exception_filter_installed) { + do_install_main_exception_filter(); + main_exception_filter_installed = true; + } + sigsegv_fault_handler = handler; + return true; +} +#endif + +bool sigsegv_install_handler(sigsegv_fault_handler_t handler) +{ +#if defined(HAVE_SIGSEGV_RECOVERY) + bool success = true; +#define FAULT_HANDLER(sig) success = success && sigsegv_do_install_handler(sig); + SIGSEGV_ALL_SIGNALS +#undef FAULT_HANDLER + if (success) + sigsegv_fault_handler = handler; + return success; +#elif defined(HAVE_MACH_EXCEPTIONS) || defined(HAVE_WIN32_EXCEPTIONS) + return sigsegv_do_install_handler(handler); +#else + // FAIL: no siginfo_t nor sigcontext subterfuge is available + return false; +#endif +} + + +/* + * SIGSEGV handler deinitialization + */ + +void sigsegv_deinstall_handler(void) +{ + // We do nothing for Mach exceptions, the thread would need to be + // suspended if not already so, and we might mess with other + // exception handlers that came after we registered ours. There is + // no need to remove the exception handler, in fact this function is + // not called anywhere in Basilisk II. +#ifdef HAVE_SIGSEGV_RECOVERY + sigsegv_fault_handler = 0; +#define FAULT_HANDLER(sig) signal(sig, SIG_DFL); + SIGSEGV_ALL_SIGNALS +#undef FAULT_HANDLER +#endif +#ifdef HAVE_WIN32_EXCEPTIONS + sigsegv_fault_handler = NULL; +#endif +} + + +/* + * Set callback function when we cannot handle the fault + */ + +void sigsegv_set_dump_state(sigsegv_state_dumper_t handler) +{ + sigsegv_state_dumper = handler; +} + + +/* + * Test program used for configure/test + */ + +#ifdef CONFIGURE_TEST_SIGSEGV_RECOVERY +#include +#include +#include +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include "vm_alloc.h" + +const int REF_INDEX = 123; +const int REF_VALUE = 45; + +static sigsegv_uintptr_t page_size; +static volatile char * page = 0; +static volatile int handler_called = 0; + +/* Barriers */ +#ifdef __GNUC__ +#define BARRIER() asm volatile ("" : : : "memory") +#else +#define BARRIER() /* nothing */ +#endif + +#ifdef __GNUC__ +// Code range where we expect the fault to come from +static void *b_region, *e_region; +#endif + +static sigsegv_return_t sigsegv_test_handler(sigsegv_info_t *sip) +{ + const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip); + const sigsegv_address_t instruction_address = sigsegv_get_fault_instruction_address(sip); +#if DEBUG + printf("sigsegv_test_handler(%p, %p)\n", fault_address, instruction_address); + printf("expected fault at %p\n", page + REF_INDEX); +#ifdef __GNUC__ + printf("expected instruction address range: %p-%p\n", b_region, e_region); +#endif +#endif + handler_called++; + if ((fault_address - REF_INDEX) != page) + exit(10); +#ifdef __GNUC__ + // Make sure reported fault instruction address falls into + // expected code range + if (instruction_address != SIGSEGV_INVALID_ADDRESS + && ((instruction_address < (sigsegv_address_t)b_region) || + (instruction_address >= (sigsegv_address_t)e_region))) + exit(11); +#endif + if (vm_protect((char *)((sigsegv_uintptr_t)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0) + exit(12); + return SIGSEGV_RETURN_SUCCESS; +} + +#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION +static sigsegv_return_t sigsegv_insn_handler(sigsegv_info_t *sip) +{ + const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip); + const sigsegv_address_t instruction_address = sigsegv_get_fault_instruction_address(sip); +#if DEBUG + printf("sigsegv_insn_handler(%p, %p)\n", fault_address, instruction_address); + printf("expected instruction address range: %p-%p\n", b_region, e_region); +#endif + if (((sigsegv_uintptr_t)fault_address - (sigsegv_uintptr_t)page) < page_size) { +#ifdef __GNUC__ + // Make sure reported fault instruction address falls into + // expected code range + if (instruction_address != SIGSEGV_INVALID_ADDRESS + && ((instruction_address < (sigsegv_address_t)b_region) || + (instruction_address >= (sigsegv_address_t)e_region))) + return SIGSEGV_RETURN_FAILURE; +#endif + return SIGSEGV_RETURN_SKIP_INSTRUCTION; + } + + return SIGSEGV_RETURN_FAILURE; +} + +// More sophisticated tests for instruction skipper +static bool arch_insn_skipper_tests() +{ +#if (defined(i386) || defined(__i386__)) || (defined(__x86_64__) || defined(_M_X64)) + static const unsigned char code[] = { + 0x8a, 0x00, // mov (%eax),%al + 0x8a, 0x2c, 0x18, // mov (%eax,%ebx,1),%ch + 0x88, 0x20, // mov %ah,(%eax) + 0x88, 0x08, // mov %cl,(%eax) + 0x66, 0x8b, 0x00, // mov (%eax),%ax + 0x66, 0x8b, 0x0c, 0x18, // mov (%eax,%ebx,1),%cx + 0x66, 0x89, 0x00, // mov %ax,(%eax) + 0x66, 0x89, 0x0c, 0x18, // mov %cx,(%eax,%ebx,1) + 0x8b, 0x00, // mov (%eax),%eax + 0x8b, 0x0c, 0x18, // mov (%eax,%ebx,1),%ecx + 0x89, 0x00, // mov %eax,(%eax) + 0x89, 0x0c, 0x18, // mov %ecx,(%eax,%ebx,1) +#if defined(__x86_64__) || defined(_M_X64) + 0x44, 0x8a, 0x00, // mov (%rax),%r8b + 0x44, 0x8a, 0x20, // mov (%rax),%r12b + 0x42, 0x8a, 0x3c, 0x10, // mov (%rax,%r10,1),%dil + 0x44, 0x88, 0x00, // mov %r8b,(%rax) + 0x44, 0x88, 0x20, // mov %r12b,(%rax) + 0x42, 0x88, 0x3c, 0x10, // mov %dil,(%rax,%r10,1) + 0x66, 0x44, 0x8b, 0x00, // mov (%rax),%r8w + 0x66, 0x42, 0x8b, 0x0c, 0x10, // mov (%rax,%r10,1),%cx + 0x66, 0x44, 0x89, 0x00, // mov %r8w,(%rax) + 0x66, 0x42, 0x89, 0x0c, 0x10, // mov %cx,(%rax,%r10,1) + 0x44, 0x8b, 0x00, // mov (%rax),%r8d + 0x42, 0x8b, 0x0c, 0x10, // mov (%rax,%r10,1),%ecx + 0x44, 0x89, 0x00, // mov %r8d,(%rax) + 0x42, 0x89, 0x0c, 0x10, // mov %ecx,(%rax,%r10,1) + 0x48, 0x8b, 0x08, // mov (%rax),%rcx + 0x4c, 0x8b, 0x18, // mov (%rax),%r11 + 0x4a, 0x8b, 0x0c, 0x10, // mov (%rax,%r10,1),%rcx + 0x4e, 0x8b, 0x1c, 0x10, // mov (%rax,%r10,1),%r11 + 0x48, 0x89, 0x08, // mov %rcx,(%rax) + 0x4c, 0x89, 0x18, // mov %r11,(%rax) + 0x4a, 0x89, 0x0c, 0x10, // mov %rcx,(%rax,%r10,1) + 0x4e, 0x89, 0x1c, 0x10, // mov %r11,(%rax,%r10,1) + 0x63, 0x47, 0x04, // movslq 4(%rdi),%eax + 0x48, 0x63, 0x47, 0x04, // movslq 4(%rdi),%rax +#endif + 0 // end + }; + const int N_REGS = 20; + SIGSEGV_REGISTER_TYPE regs[N_REGS]; + for (int i = 0; i < N_REGS; i++) + regs[i] = i; + const sigsegv_uintptr_t start_code = (sigsegv_uintptr_t)&code; + regs[X86_REG_EIP] = start_code; + while ((regs[X86_REG_EIP] - start_code) < (sizeof(code) - 1) + && ix86_skip_instruction(regs)) + ; /* simply iterate */ + return (regs[X86_REG_EIP] - start_code) == (sizeof(code) - 1); +#endif + return true; +} +#endif + +int main(void) +{ + if (vm_init() < 0) + return 1; + + page_size = vm_get_page_size(); + if ((page = (char *)vm_acquire(page_size)) == VM_MAP_FAILED) + return 2; + + memset((void *)page, 0, page_size); + if (vm_protect((char *)page, page_size, VM_PAGE_READ) < 0) + return 3; + + if (!sigsegv_install_handler(sigsegv_test_handler)) + return 4; + +#ifdef __GNUC__ + b_region = &&L_b_region1; + e_region = &&L_e_region1; +#endif + /* This is a really awful hack but otherwise gcc is smart enough + * (or bug'ous enough?) to optimize the labels and place them + * e.g. at the "main" entry point, which is wrong. + */ + volatile int label_hack = 3; + switch (label_hack) { + case 3: + L_b_region1: + page[REF_INDEX] = REF_VALUE; + if (page[REF_INDEX] != REF_VALUE) + exit(20); + page[REF_INDEX] = REF_VALUE; + BARRIER(); + // fall-through + case 2: + L_e_region1: + BARRIER(); + break; + } + + if (handler_called != 1) + return 5; + +#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION + if (!sigsegv_install_handler(sigsegv_insn_handler)) + return 6; + + if (vm_protect((char *)page, page_size, VM_PAGE_READ | VM_PAGE_WRITE) < 0) + return 7; + + for (int i = 0; i < page_size; i++) + page[i] = (i + 1) % page_size; + + if (vm_protect((char *)page, page_size, VM_PAGE_NOACCESS) < 0) + return 8; + +#define TEST_SKIP_INSTRUCTION(TYPE) do { \ + const unsigned long TAG = 0x12345678 | \ + (sizeof(long) == 8 ? 0x9abcdef0UL << 31 : 0); \ + TYPE data = *((TYPE *)(page + sizeof(TYPE))); \ + volatile unsigned long effect = data + TAG; \ + if (effect != TAG) \ + return 9; \ + } while (0) + +#ifdef __GNUC__ + b_region = &&L_b_region2; + e_region = &&L_e_region2; +#ifdef DEBUG + printf("switch footage : \n"); + printf(" 4 : %p\n", &&L_b_4_region2); + printf(" 5 : %p\n", &&L_b_5_region2); + printf(" 8 : %p\n", &&L_b_8_region2); + printf(" 6 : %p\n", &&L_b_6_region2); + printf(" 7 : %p\n", &&L_b_7_region2); + printf(" 9 : %p\n", &&L_b_9_region2); + printf(" 1 : %p\n", &&L_b_1_region2); +#endif +#endif + switch (label_hack) { + case 3: + L_b_region2: + TEST_SKIP_INSTRUCTION(unsigned char); + BARRIER(); + case 4: + L_b_4_region2: + TEST_SKIP_INSTRUCTION(unsigned short); + BARRIER(); + case 5: + L_b_5_region2: + TEST_SKIP_INSTRUCTION(unsigned int); + BARRIER(); + case 8: + L_b_8_region2: + TEST_SKIP_INSTRUCTION(unsigned long); + BARRIER(); + case 6: + L_b_6_region2: + TEST_SKIP_INSTRUCTION(signed char); + BARRIER(); + case 7: + L_b_7_region2: + TEST_SKIP_INSTRUCTION(signed short); + BARRIER(); + case 9: + L_b_9_region2: + TEST_SKIP_INSTRUCTION(signed int); + BARRIER(); + case 1: + L_b_1_region2: + TEST_SKIP_INSTRUCTION(signed long); + BARRIER(); + // fall-through + case 2: + L_e_region2: + BARRIER(); + break; + } + if (!arch_insn_skipper_tests()) + return 20; +#endif + + vm_exit(); + return 0; +} +#endif 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/MacOSX/Info.plist.in b/SheepShaver/src/MacOSX/Info.plist.in index 1324ba8b6..a70e1ec95 100644 --- a/SheepShaver/src/MacOSX/Info.plist.in +++ b/SheepShaver/src/MacOSX/Info.plist.in @@ -1,25 +1,9 @@ - + CFBundleDevelopmentRegion English - CFBundleExecutable - SheepShaver - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - @PACKAGE_VERSION@ - CFBundleShortVersionString - @PACKAGE_VERSION@ - CFBundleIconFile - SheepShaver.icns - CSResourcesFileMapped - CFBundleDocumentTypes @@ -28,7 +12,7 @@ sheepvm CFBundleTypeIconFile - SheepShaver.icns + SheepVM.icns CFBundleTypeName SheepShaver VM CFBundleTypeRole @@ -37,20 +21,27 @@ - LSArchitecturePriority - - i386 - x86_64 - ppc - - LSMinimumSystemVersionByArchitecture - - i386 - 10.4.0 - x86_64 - 10.6.0 - ppc - 10.4.0 - + CFBundleExecutable + SheepShaver + CFBundleIconFile + SheepShaver.icns + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + @PACKAGE_VERSION@ + CFBundleSignature + ???? + CFBundleVersion + @PACKAGE_VERSION@ + CSResourcesFileMapped + + LSMinimumSystemVersion + 10.7.0 + NSHighResolutionCapable + diff --git a/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/designable.nib b/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/designable.nib old mode 100755 new mode 100644 index d2ec997be..5257f5ba1 --- a/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/designable.nib +++ b/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/designable.nib @@ -1,4438 +1,766 @@ - - - 1050 - 10K549 - 851 - 1038.36 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 851 - - - YES - - - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - VMSettingsController - - - FirstResponder - - - NSApplication - - - - 256 - - YES - - - 256 - {{145, 20}, {43, 22}} - - YES - - -1804468671 - 71304192 - 40 - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - - - - 256 - {{193, 17}, {19, 27}} - - 1 - YES - - 917024 - 0 - - 1 - 40 - 1 - 10000 - 1 - YES - YES - - - - - 256 - {{17, 22}, {114, 17}} - - YES - - 67239424 - 272629760 - Volume Size (MB) - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - - - - - {229, 62} - - NSView - NSResponder - - - 13 - 2 - {{217, 242}, {580, 460}} - 1886912512 - Virtual Machine Settings - - NSWindow - - - View - - {1.79769e+308, 1.79769e+308} - {580, 460} - - - 256 - - YES - - - 274 - {{13, 59}, {554, 395}} - - - YES - - 1 - - - 256 - - YES - - - 258 - {{95, 50}, {327, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 258 - {{95, 78}, {327, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 256 - {{14, 52}, {77, 17}} - - YES - - 67239424 - 71303168 - Unix Root: - - - - - - - - - 256 - {{20, 80}, {71, 17}} - - YES - - 67239424 - 71303168 - ROM File: - - - - - - - - - 274 - - YES - - - 256 - - YES - - - 292 - {{10, 5}, {82, 32}} - - YES - - 67239424 - 134217728 - Add... - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 293 - {{211, 5}, {94, 32}} - - YES - - 67239424 - 134217728 - Create... - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 289 - {{417, 5}, {90, 32}} - - YES - - 67239424 - 134217728 - Remove - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 274 - - YES - - - 2304 - - YES - - - 256 - {468, 136} - - YES - - - 256 - {468, 17} - - - - - - 256 - {{469, 0}, {16, 17}} - - - - YES - - pathCol - 371 - 40 - 1000 - - 75628096 - 2048 - File - - LucidaGrande - 11 - 3100 - - - 3 - MC4zMzMzMzI5OQA - - - 6 - System - headerTextColor - - - - - 337772096 - 2048 - - - - 6 - System - controlBackgroundColor - - - - - - - - isCDROMcol - 64 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - CDROM - - - 6 - System - headerColor - - - - - - 67239424 - 0 - - - - 1215058431 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - 3 - YES - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 17 - 312475648 - - - 2 - 4 - 15 - 0 - YES - 0 - - - {{1, 17}, {468, 136}} - - - - - 4 - - - - 256 - {{469, 17}, {15, 136}} - - - _doScroller: - 0.99350649350649356 - - - - -2147483392 - {{-100, -100}, {374, 15}} - - 1 - - _doScroller: - 0.99047620000000003 - - - - 2304 - - YES - - - {{1, 0}, {468, 17}} - - - - - 4 - - - - {{16, 42}, {485, 154}} - - - 18 - - - - - - QSAAAEEgAABBmAAAQZgAAA - - - {{2, 2}, {518, 209}} - - - - {{6, 123}, {522, 226}} - - {0, 0} - - 67239424 - 0 - Volumes - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 2 - NO - - - - 256 - {{14, 22}, {77, 17}} - - YES - - 67239424 - 71303168 - Boot From: - - - - - - - - - 256 - {{95, 18}, {94, 26}} - - YES - - 343014976 - 272630784 - Any - - - YES - - - 5 - YES - - YES - Any - CD-ROM - - - - - 274 - {13, 42} - - - YES - - YES - - - 10 - 10 - 1000 - - 75628032 - 0 - - - - - LucidaGrande - 12 - 16 - - - 3 - MC4zMzMzMzI5OQA - - - - - 338820672 - 1024 - CD-ROM - - - YES - - - - 3 - YES - - - - 3 - 2 - - - 19 - tableViewAction: - -765427712 - - - - 1 - 15 - 0 - YES - 0 - - - - - - 256 - {{390, 22}, {129, 18}} - - YES - - 67239424 - 0 - Disable CD-ROM - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{355, 17}, {22, 28}} - - YES - - -2146566624 - 0 - - 19 - 4 - 1024 - 1 - YES - - - - - 256 - {{309, 20}, {41, 22}} - - YES - - -1804468671 - 71304192 - 64 - - - YES - - - - - - - 256 - {{200, 20}, {104, 19}} - - YES - - 67239424 - 71303168 - RAM Size (MB): - - - - - - - - - 289 - {{425, 72}, {98, 32}} - - YES - - 67239424 - 134217728 - Browse... - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - - 289 - {{425, 44}, {98, 32}} - - YES - - 67239424 - 134217728 - Browse... - - - -2038284033 - 1 - - - - - - 200 - 25 - - - - {{10, 33}, {534, 349}} - - - Setup - - - - - 2 - - - 256 - - YES - - - 266 - - YES - - - 256 - - YES - - - 270 - {{125, 20}, {218, 18}} - - YES - - -2080244224 - 0 - Enable QuickDraw Acceleration - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 266 - {{206, 132}, {143, 26}} - - YES - - -2076049856 - 2048 - - - 109199615 - 1 - - LucidaGrande - 13 - 16 - - - - - - 400 - 75 - - - Window - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - 1 - - - YES - - - OtherViews - - - YES - - - - Fullscreen - - 1048576 - 2147483647 - - - _popUpItemAction: - 2 - - - - - 3 - YES - YES - 1 - - - - - 266 - {{206, 104}, {143, 26}} - - YES - - -2076049856 - 2048 - - - 109199615 - 1 - - - - - - 400 - 75 - - - 30 Hz - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - YES - - - 5 Hz - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 7.5 Hz - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 10 Hz - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 15 Hz - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - - 60 Hz - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - Dynamic - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 4 - 3 - YES - YES - 1 - - - - - 268 - {{118, 80}, {86, 17}} - - YES - - 67239424 - 71303168 - Width: - - - - - - - - - 268 - {{118, 52}, {86, 17}} - - YES - - 67239424 - 71303168 - Height: - - - - - - - - - 266 - {{209, 76}, {140, 26}} - - YES - - 343014976 - 272630784 - 800 - - - YES - - - 5 - YES - - YES - 512 - 640 - 800 - 1024 - Maximum - - - - - 274 - {13, 105} - - - YES - - YES - - - 10 - 10 - 1000 - - 75628032 - 0 - - - - - - 3 - MC4zMzMzMzI5OQA - - - - - 1412562496 - 1024 - 800 - - - YES - - - - 3 - YES - - - - 3 - 2 - - - 19 - tableViewAction: - -765427712 - - - - 1 - 15 - 0 - YES - 0 - - - - - - 266 - {{209, 48}, {140, 26}} - - YES - - 343014976 - 272630784 - 600 - - - YES - - - 5 - YES - - YES - 384 - 480 - 600 - 768 - Maximum - - - - - 274 - {13, 105} - - - YES - - YES - - - 10 - 10 - 1000 - - 75628032 - 0 - - - - - - 3 - MC4zMzMzMzI5OQA - - - - - 1412562496 - 1024 - 600 - - - YES - - - - 3 - YES - - - - 3 - 2 - - - 19 - tableViewAction: - -765427712 - - - - 1 - 15 - 0 - YES - 0 - - - - - - 268 - {{118, 136}, {86, 19}} - - YES - - 67239424 - 71303168 - Video Type: - - - - - - - - - 268 - {{112, 108}, {92, 19}} - - YES - - 67239424 - 71303168 - Refresh Rate: - - - - - - - - {{2, 2}, {518, 177}} - - - - {{6, 155}, {522, 194}} - - {0, 0} - - 67239424 - 0 - Video Settings - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 2 - NO - - - - 266 - - YES - - - 256 - - YES - - - 264 - {{15, 96}, {172, 18}} - - YES - - 67239424 - 0 - Disable Audio Output - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 266 - {{118, 59}, {379, 22}} - - YES - - -1804468671 - 272630784 - /dev/dsp - - - YES - - - - - - - 266 - {{118, 29}, {379, 22}} - - YES - - -1804468671 - 272630784 - /dev/mixer - - - YES - - - - - - - 264 - {{14, 61}, {99, 17}} - - YES - - 67239424 - 71303168 - Output Device: - - - - - - - - - 264 - {{14, 31}, {99, 17}} - - YES - - 67239424 - 71303168 - Mixer Device: - - - - - - - - {{2, 2}, {518, 134}} - - - - {{6, 0}, {522, 151}} - - {0, 0} - - 67239424 - 0 - Audio Settings - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 2 - NO - - - {{10, 33}, {534, 349}} - - Audio / Video - - - - - Item 4 - - - 256 - - YES - - - 266 - - YES - - - 256 - - YES - - - 256 - {{13, 75}, {130, 17}} - - YES - - 70385217 - 71304192 - Modem Port Device: - - - - - - - - - 256 - {{18, 43}, {125, 17}} - - YES - - 70385217 - 71304192 - Printer Port Device: - - - - - - - - - 256 - {{18, 13}, {126, 17}} - - YES - - 70385217 - 71304192 - Ethernet Interface: - - - - - - - - - 266 - {{146, 73}, {351, 22}} - - YES - - -1804468671 - 4195328 - - - - YES - - - - - - - 266 - {{146, 41}, {351, 22}} - - YES - - -1804468671 - 4195328 - - - - YES - - - - - - - 266 - {{146, 10}, {351, 22}} - - YES - - -1804468671 - 4195328 - slirp - - - YES - - - - - - {{2, 2}, {518, 106}} - - - - {{6, 4}, {522, 123}} - - {0, 0} - - 67239424 - 0 - Serial/Network - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 2 - NO - - - - 266 - - YES - - - 256 - - YES - - - 256 - {{15, 51}, {150, 18}} - - YES - - -2080244224 - 0 - Enable JIT Compiler - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{15, 11}, {333, 18}} - - YES - - 67239424 - 0 - Enable built-in 68k DR Emulator (EXPERIMENTAL) - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 256 - {{15, 31}, {236, 18}} - - YES - - 67239424 - 0 - Allow Emulated CPU to Idle - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 265 - {{269, 51}, {220, 18}} - - YES - - 67239424 - 0 - Ignore Illegal Instructions - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 265 - {{269, 31}, {220, 18}} - - YES - - 67239424 - 0 - Ignore Illegal Memory Accesses - - - 1211912703 - 2 - - - - - 200 - 25 - - - - {{2, 2}, {518, 77}} - - - - {{6, 255}, {522, 94}} - - {0, 0} - - 67239424 - 0 - CPU Options - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 2 - NO - - - - 266 - - YES - - - 256 - - YES - - - 256 - {{22, 70}, {142, 18}} - - YES - - 67239424 - 0 - Use Raw Keycodes: - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 266 - {{170, 69}, {239, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 256 - {{14, 43}, {151, 17}} - - YES - - 67239424 - 71303168 - Mouse Wheel Function: - - - - - - - - - 256 - {{66, 15}, {99, 17}} - - YES - - 67239424 - 71303168 - Lines to Scroll: - - - - - - - - - 256 - {{170, 13}, {29, 22}} - - YES - - -1804468671 - 272630784 - 3 - - - YES - - - - - - - 256 - {{167, 37}, {163, 26}} - - YES - - -2076049856 - 2048 - - - 109199615 - 1 - - - - - - 400 - 75 - - - Page Up/Down - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - - OtherViews - - - YES - - - - Cursor Up/Down - - 1048576 - 2147483647 - - - _popUpItemAction: - - - - - 3 - YES - YES - 1 - - - - - 256 - {{204, 10}, {19, 27}} - - YES - - 917024 - 0 - - 59 - 1 - YES - YES - - - - - 289 - {{411, 63}, {96, 32}} - - YES - - 67239424 - 134217728 - Browse... - - - -2038284033 - 129 - - - 200 - 25 - - - - {{2, 2}, {518, 103}} - - - - {{6, 131}, {522, 120}} - - {0, 0} - - 67239424 - 0 - Mouse/Keyboard - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 3 - 0 - 2 - NO - - - {{10, 33}, {534, 349}} - - Miscellaneous - - - - - - - 0 - YES - YES - - YES - - - - - - 289 - {{374, 20}, {96, 32}} - - YES - - 67239424 - 134217728 - Cancel - - - -2038284033 - 129 - - - 200 - 25 - - - - - 289 - {{470, 20}, {96, 32}} - - YES - - 67239424 - 134217728 - Save - - - -2038284033 - 129 - - - 200 - 25 - - - - {580, 460} - - - {{0, 0}, {1440, 878}} - {580, 482} - {1.79769e+308, 1.79769e+308} - - - - 268 - - YES - - - 268 - {{18, 18}, {85, 18}} - - YES - - 67239424 - 0 - Is CDROM - - - 1211912703 - 2 - - - - - 200 - 25 - - - - {121, 54} - - NSView - - - - - YES - - - takeIntValueFrom: - - - - 282 - - - - initialFirstResponder - - - - 283 - - - - takeIntValueFrom: - - - - 291 - - - - takeIntValueFrom: - - - - 310 - - - - takeIntValueFrom: - - - - 311 - - - - takeIntValueFrom: - - - - 313 - - - - takeIntValueFrom: - - - - 314 - - - - window - - - - 318 - - - - bootFrom - - - - 319 - - - - disableCdrom - - - - 320 - - - - disableSound - - - - 321 - - - - dontUseCPUWhenIdle - - - - 322 - - - - enable68kDREmulator - - - - 323 - - - - enableJIT - - - - 324 - - - - unixRoot - - - - 325 - - - - romFile - - - - 326 - - - - browseForROMFileClicked: - - - - 327 - - - - addDisk: - - - - 328 - - - - createDisk: - - - - 329 - - - - removeDisk: - - - - 330 - - - - useRawKeyCodesClicked: - - - - 331 - - - - rawKeyCodes - - - - 332 - - - - useRawKeyCodes - - - - 333 - - - - modemPort - - - - 334 - - - - mouseWheel - - - - 335 - - - - printerPort - - - - 336 - - - - ramSize - - - - 337 - - - - ramSizeStepper - - - - 338 - - - - mixDevice - - - - 339 - - - - outDevice - - - - 340 - - - - qdAccel - - - - 341 - - - - height - - - - 342 - - - - width - - - - 343 - - - - videoType - - - - 344 - - - - refreshRate - - - - 345 - - - - scrollLines - - - - 346 - - - - scrollLinesStepper - - - - 347 - - - - ignoreIllegalMemoryAccesses - - - - 348 - - - - ethernetInterface - - - - 349 - - - - diskSaveSizeField - - - - 351 - - - - diskSaveSize - - - - 353 - - - - delegate - - - - 355 - - - - disks - - - - 368 - - - - browseForUnixRootClicked: - - - - 369 - - - - ignoreIllegalInstructions - - - - 372 - - - - saveChanges: - - - - 373 - - - - cancelEdit: - - - - 374 - - - - browseForKeyCodesFileClicked: - - - - 378 - - - - browseRawKeyCodesButton - - - - 379 - - - - isCDROM - - - - 383 - - - - isCDROMcheckbox - - - - 384 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 141 - - - YES - - - - - - DiskSize - - - 142 - - - YES - - - - PrefsWindow - - - 143 - - - YES - - - - - - - - 144 - - - YES - - - - - - - - 145 - - - YES - - - - - - 147 - - - YES - - - - - - 148 - - - YES - - - - - - - 157 - - - YES - - - - - - - - - - - - - - 230 - - - YES - - - - - - - - - - - - - - - - - - 231 - - - YES - - - - - - 232 - - - YES - - - - - - 233 - - - YES - - - - - - 234 - - - YES - - - - - - 235 - - - YES - - - - - - 236 - - - YES - - - - - - 237 - - - YES - - - - - - 238 - - - YES - - - - - - 239 - - - YES - - - - - - 240 - - - YES - - - - - - - - - 241 - - - YES - - - - - - 242 - - - YES - - - - - - 243 - - - - - 244 - - - - - 245 - - - YES - - - - - - 246 - - - YES - - - - - - 247 - - - YES - - - - - - 248 - - - YES - - - - - - - - - 249 - - - - - 250 - - - - - 251 - - - YES - - - - - - - 252 - - - YES - - - - - - 253 - - - - - 254 - - - - - 255 - - - - - 256 - - - - - 257 - - - - - 258 - - - - - 259 - - - - - 260 - - - - - 261 - - - - - 262 - - - - - 263 - - - - - 264 - - - - - 265 - - - - - 266 - - - YES - - - - - - 267 - - - YES - - - - - - 268 - - - YES - - - - - - 269 - - - - - 270 - - - - - 271 - - - - - 358 - - - YES - - - - - - 359 - - - YES - - - - - - - - 360 - - - YES - - - - - - 361 - - - - - 362 - - - YES - - - - - - 363 - - - - - 364 - - - YES - - - - - - 365 - - - - - 195 - - - YES - - - - - - - - - - 192 - - - YES - - - - - - 370 - - - YES - - - - - - 190 - - - YES - - - - - - 193 - - - YES - - - - - - 191 - - - YES - - - - - - 228 - - - - - 226 - - - - - 229 - - - - - 371 - - - - - 227 - - - - - 194 - - - YES - - - - - - - - - - - 214 - - - YES - - - - - - 225 - - - - - 215 - - - YES - - - - - - 224 - - - - - 216 - - - YES - - - - - - 223 - - - - - 217 - - - YES - - - - - - 222 - - - - - 218 - - - YES - - - - - - 221 - - - - - 219 - - - YES - - - - - - 220 - - - - - 203 - - - YES - - - - - - - - - - - - - 196 - - - YES - - - - - - 197 - - - YES - - - - - - 198 - - - YES - - - - - - 199 - - - YES - - - - - - 200 - - - YES - - - - - - 201 - - - YES - - - - - - 202 - - - YES - - - - - - 204 - - - - - 205 - - - YES - - - - - - 206 - - - YES - - - - - - - 207 - - - - - 208 - - - - - 209 - - - - - 210 - - - - - 211 - - - - - 212 - - - - - 213 - - - - - 150 - - - YES - - - - - - - - - - 158 - - - YES - - - - - - 161 - - - YES - - - - - - 164 - - - YES - - - - - - 159 - - - YES - - - - - - 160 - - - YES - - - - - - 169 - - - - - 170 - - - - - 165 - - - - - 168 - - - - - 171 - - - - - 153 - - - YES - - - - - - 182 - - - - - 151 - - - YES - - - - - - 184 - - - YES - - - - - - 185 - - - YES - - - - - - - 187 - - - - - 186 - - - - - 156 - - - YES - - - - - - 172 - - - YES - - - - - - 173 - - - YES - - - - - - - - - - - - 179 - - - - - 178 - - - - - 177 - - - - - 176 - - - - - 175 - - - - - 174 - - - - - 152 - - - YES - - - - - - 183 - - - - - 162 - - - YES - - - - - - 167 - - - - - 154 - - - YES - - - - - - 181 - - - - - 149 - - - YES - - - - - - 188 - - - - - 155 - - - YES - - - - - - 180 - - - - - 163 - - - YES - - - - - - 166 - - - - - 375 - - - - - 376 - - - YES - - - - - - 377 - - - - - 380 - - - YES - - - - IsCDROM - - - 381 - - - YES - - - - - - 382 - - - - - 388 - - - YES - - - - - - 390 - - - - - 391 - - - - - - - YES - - YES - -3.IBPluginDependency - 141.IBEditorWindowLastContentRect - 141.IBPluginDependency - 141.ImportedFromIB2 - 142.IBEditorWindowLastContentRect - 142.IBPluginDependency - 142.IBWindowTemplateEditedContentRect - 142.ImportedFromIB2 - 142.NSWindowTemplate.visibleAtLaunch - 142.windowTemplate.hasMinSize - 142.windowTemplate.minSize - 143.IBPluginDependency - 143.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 147.IBPluginDependency - 147.ImportedFromIB2 - 148.IBPluginDependency - 148.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 151.IBPluginDependency - 151.ImportedFromIB2 - 152.IBPluginDependency - 152.ImportedFromIB2 - 153.IBPluginDependency - 153.ImportedFromIB2 - 154.IBPluginDependency - 154.ImportedFromIB2 - 155.IBPluginDependency - 155.ImportedFromIB2 - 156.IBPluginDependency - 156.ImportedFromIB2 - 157.IBPluginDependency - 157.ImportedFromIB2 - 158.IBPluginDependency - 158.ImportedFromIB2 - 159.IBPluginDependency - 159.ImportedFromIB2 - 160.IBPluginDependency - 160.ImportedFromIB2 - 161.IBPluginDependency - 161.ImportedFromIB2 - 162.IBPluginDependency - 162.ImportedFromIB2 - 163.IBPluginDependency - 163.ImportedFromIB2 - 164.IBPluginDependency - 164.ImportedFromIB2 - 165.IBPluginDependency - 166.IBPluginDependency - 167.IBPluginDependency - 168.IBPluginDependency - 169.IBPluginDependency - 170.IBPluginDependency - 171.IBPluginDependency - 172.IBPluginDependency - 173.IBEditorWindowLastContentRect - 173.IBPluginDependency - 173.ImportedFromIB2 - 174.IBPluginDependency - 174.ImportedFromIB2 - 175.IBPluginDependency - 175.ImportedFromIB2 - 176.IBPluginDependency - 176.ImportedFromIB2 - 177.IBPluginDependency - 177.ImportedFromIB2 - 178.IBPluginDependency - 178.ImportedFromIB2 - 179.IBPluginDependency - 179.ImportedFromIB2 - 180.IBPluginDependency - 181.IBPluginDependency - 182.IBPluginDependency - 183.IBPluginDependency - 184.IBPluginDependency - 185.IBEditorWindowLastContentRect - 185.IBPluginDependency - 185.ImportedFromIB2 - 186.IBPluginDependency - 186.ImportedFromIB2 - 187.IBPluginDependency - 187.ImportedFromIB2 - 188.IBPluginDependency - 190.IBPluginDependency - 190.ImportedFromIB2 - 191.IBPluginDependency - 191.ImportedFromIB2 - 192.IBPluginDependency - 192.ImportedFromIB2 - 193.IBPluginDependency - 193.ImportedFromIB2 - 194.IBPluginDependency - 194.ImportedFromIB2 - 195.IBPluginDependency - 195.ImportedFromIB2 - 196.IBPluginDependency - 196.ImportedFromIB2 - 197.IBPluginDependency - 197.ImportedFromIB2 - 198.IBPluginDependency - 198.ImportedFromIB2 - 199.IBPluginDependency - 199.ImportedFromIB2 - 200.IBPluginDependency - 200.ImportedFromIB2 - 201.IBPluginDependency - 201.ImportedFromIB2 - 202.IBPluginDependency - 202.ImportedFromIB2 - 203.IBPluginDependency - 203.ImportedFromIB2 - 204.IBPluginDependency - 205.IBPluginDependency - 206.IBPluginDependency - 206.ImportedFromIB2 - 207.IBPluginDependency - 207.ImportedFromIB2 - 208.IBPluginDependency - 208.ImportedFromIB2 - 209.IBPluginDependency - 210.IBPluginDependency - 211.IBPluginDependency - 212.IBPluginDependency - 213.IBPluginDependency - 214.IBPluginDependency - 214.ImportedFromIB2 - 215.IBPluginDependency - 215.ImportedFromIB2 - 216.IBPluginDependency - 216.ImportedFromIB2 - 217.IBPluginDependency - 217.ImportedFromIB2 - 218.IBPluginDependency - 218.ImportedFromIB2 - 219.IBPluginDependency - 219.ImportedFromIB2 - 220.IBPluginDependency - 221.IBPluginDependency - 222.IBPluginDependency - 223.IBPluginDependency - 224.IBPluginDependency - 225.IBPluginDependency - 226.IBPluginDependency - 227.IBPluginDependency - 228.IBPluginDependency - 229.IBPluginDependency - 230.IBPluginDependency - 230.ImportedFromIB2 - 231.IBPluginDependency - 231.ImportedFromIB2 - 232.IBPluginDependency - 232.ImportedFromIB2 - 233.IBPluginDependency - 233.ImportedFromIB2 - 234.IBPluginDependency - 234.ImportedFromIB2 - 235.IBPluginDependency - 235.ImportedFromIB2 - 236.IBPluginDependency - 236.ImportedFromIB2 - 237.IBPluginDependency - 237.ImportedFromIB2 - 238.IBPluginDependency - 238.ImportedFromIB2 - 239.IBPluginDependency - 239.ImportedFromIB2 - 240.IBPluginDependency - 240.ImportedFromIB2 - 241.IBPluginDependency - 241.ImportedFromIB2 - 242.IBPluginDependency - 242.ImportedFromIB2 - 243.IBPluginDependency - 244.IBPluginDependency - 245.IBPluginDependency - 245.ImportedFromIB2 - 246.IBPluginDependency - 246.ImportedFromIB2 - 247.IBPluginDependency - 247.ImportedFromIB2 - 248.IBPluginDependency - 248.ImportedFromIB2 - 249.IBPluginDependency - 249.IBShouldRemoveOnLegacySave - 250.IBPluginDependency - 250.IBShouldRemoveOnLegacySave - 251.IBPluginDependency - 251.ImportedFromIB2 - 252.IBPluginDependency - 252.ImportedFromIB2 - 253.IBPluginDependency - 253.IBShouldRemoveOnLegacySave - 254.IBPluginDependency - 255.IBPluginDependency - 256.IBPluginDependency - 257.IBPluginDependency - 258.IBPluginDependency - 259.IBPluginDependency - 260.IBPluginDependency - 261.IBPluginDependency - 262.IBPluginDependency - 263.IBPluginDependency - 264.IBPluginDependency - 265.IBPluginDependency - 266.IBPluginDependency - 266.ImportedFromIB2 - 267.IBPluginDependency - 267.ImportedFromIB2 - 268.IBPluginDependency - 268.ImportedFromIB2 - 269.IBPluginDependency - 270.IBPluginDependency - 271.IBPluginDependency - 358.IBPluginDependency - 359.IBPluginDependency - 360.IBPluginDependency - 361.IBPluginDependency - 362.IBPluginDependency - 363.IBPluginDependency - 364.IBPluginDependency - 364.ImportedFromIB2 - 365.IBPluginDependency - 370.IBPluginDependency - 370.ImportedFromIB2 - 371.IBPluginDependency - 375.IBPluginDependency - 375.ImportedFromIB2 - 376.IBPluginDependency - 377.IBPluginDependency - 380.IBEditorWindowLastContentRect - 380.IBPluginDependency - 381.IBPluginDependency - 382.IBPluginDependency - 388.IBPluginDependency - 390.IBPluginDependency - 391.IBPluginDependency - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - {{899, 941}, {229, 62}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{739, 322}, {580, 460}} - com.apple.InterfaceBuilder.CocoaPlugin - {{739, 322}, {580, 460}} - - - - {580, 460} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{601, 517}, {143, 143}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{196, 720}, {138, 43}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{705, 948}, {121, 54}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 391 - - - - YES - - VMSettingsController - NSWindowController - - YES - - YES - addDisk: - browseForKeyCodesFileClicked: - browseForROMFileClicked: - browseForUnixRootClicked: - cancelEdit: - createDisk: - removeDisk: - saveChanges: - useRawKeyCodesClicked: - - - YES - id - id - id - id - id - id - id - id - id - - - - YES - - YES - addDisk: - browseForKeyCodesFileClicked: - browseForROMFileClicked: - browseForUnixRootClicked: - cancelEdit: - createDisk: - removeDisk: - saveChanges: - useRawKeyCodesClicked: - - - YES - - addDisk: - id - - - browseForKeyCodesFileClicked: - id - - - browseForROMFileClicked: - id - - - browseForUnixRootClicked: - id - - - cancelEdit: - id - - - createDisk: - id - - - removeDisk: - id - - - saveChanges: - id - - - useRawKeyCodesClicked: - id - - - - - YES - - YES - bootFrom - browseRawKeyCodesButton - disableCdrom - disableSound - diskSaveSize - diskSaveSizeField - disks - dontUseCPUWhenIdle - enable68kDREmulator - enableJIT - ethernetInterface - height - ignoreIllegalInstructions - ignoreIllegalMemoryAccesses - isCDROM - isCDROMcheckbox - mixDevice - modemPort - mouseWheel - outDevice - printerPort - qdAccel - ramSize - ramSizeStepper - rawKeyCodes - refreshRate - romFile - scrollLines - scrollLinesStepper - unixRoot - useRawKeyCodes - videoType - width - - - YES - NSComboBox - NSButton - NSButton - NSButton - NSView - NSTextField - NSTableView - NSButton - NSButton - NSButton - NSTextField - NSComboBox - NSButton - NSButton - NSView - NSButton - NSTextField - NSTextField - NSPopUpButton - NSTextField - NSTextField - NSButton - NSTextField - NSStepper - NSTextField - NSPopUpButton - NSTextField - NSTextField - NSStepper - NSTextField - NSButton - NSPopUpButton - NSComboBox - - - - YES - - YES - bootFrom - browseRawKeyCodesButton - disableCdrom - disableSound - diskSaveSize - diskSaveSizeField - disks - dontUseCPUWhenIdle - enable68kDREmulator - enableJIT - ethernetInterface - height - ignoreIllegalInstructions - ignoreIllegalMemoryAccesses - isCDROM - isCDROMcheckbox - mixDevice - modemPort - mouseWheel - outDevice - printerPort - qdAccel - ramSize - ramSizeStepper - rawKeyCodes - refreshRate - romFile - scrollLines - scrollLinesStepper - unixRoot - useRawKeyCodes - videoType - width - - - YES - - bootFrom - NSComboBox - - - browseRawKeyCodesButton - NSButton - - - disableCdrom - NSButton - - - disableSound - NSButton - - - diskSaveSize - NSView - - - diskSaveSizeField - NSTextField - - - disks - NSTableView - - - dontUseCPUWhenIdle - NSButton - - - enable68kDREmulator - NSButton - - - enableJIT - NSButton - - - ethernetInterface - NSTextField - - - height - NSComboBox - - - ignoreIllegalInstructions - NSButton - - - ignoreIllegalMemoryAccesses - NSButton - - - isCDROM - NSView - - - isCDROMcheckbox - NSButton - - - mixDevice - NSTextField - - - modemPort - NSTextField - - - mouseWheel - NSPopUpButton - - - outDevice - NSTextField - - - printerPort - NSTextField - - - qdAccel - NSButton - - - ramSize - NSTextField - - - ramSizeStepper - NSStepper - - - rawKeyCodes - NSTextField - - - refreshRate - NSPopUpButton - - - romFile - NSTextField - - - scrollLines - NSTextField - - - scrollLinesStepper - NSStepper - - - unixRoot - NSTextField - - - useRawKeyCodes - NSButton - - - videoType - NSPopUpButton - - - width - NSComboBox - - - - - IBProjectSource - Launcher/VMSettingsController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../../SheepShaver.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - NSSwitch - - - YES - {9, 8} - {7, 2} - {15, 15} - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Any + CD-ROM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 512 + 640 + 800 + 1024 + Maximum + + + + + + + + + + + + 384 + 480 + 600 + 768 + Maximum + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/keyedobjects.nib b/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/keyedobjects.nib old mode 100755 new mode 100644 index b27171c4a..6da6267c4 Binary files a/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/keyedobjects.nib and b/SheepShaver/src/MacOSX/Launcher/English.lproj/VMSettingsWindow.nib/keyedobjects.nib differ diff --git a/SheepShaver/src/MacOSX/Launcher/Info.plist b/SheepShaver/src/MacOSX/Launcher/Info.plist index 54bcb8dda..7c2c94bf0 100644 --- a/SheepShaver/src/MacOSX/Launcher/Info.plist +++ b/SheepShaver/src/MacOSX/Launcher/Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile SheepShaver.icns CFBundleIdentifier - net.sourceforge.SheepShaverLauncher + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SheepShaver/src/MacOSX/Launcher/SheepShaverLauncher.xcodeproj/project.pbxproj b/SheepShaver/src/MacOSX/Launcher/SheepShaverLauncher.xcodeproj/project.pbxproj index fe382f61e..abfe0315f 100644 --- a/SheepShaver/src/MacOSX/Launcher/SheepShaverLauncher.xcodeproj/project.pbxproj +++ b/SheepShaver/src/MacOSX/Launcher/SheepShaverLauncher.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 084186B10B3A0515004B1F63 /* VMSettingsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 084186B00B3A0515004B1F63 /* VMSettingsController.mm */; }; 088EBBB61B41AEBB0066D352 /* DiskType.m in Sources */ = {isa = PBXBuildFile; fileRef = 088EBBB51B41AEBB0066D352 /* DiskType.m */; }; 08AAB16D102614D5007E1230 /* SheepShaver.icns in Resources */ = {isa = PBXBuildFile; fileRef = 08AAB16C102614D5007E1230 /* SheepShaver.icns */; }; - 08AAB1B310261691007E1230 /* SheepShaver in Copy SheepShaver */ = {isa = PBXBuildFile; fileRef = 08AAB1B11026168B007E1230 /* SheepShaver */; }; + 08AAB1B310261691007E1230 /* SheepShaver in Copy SheepShaver */ = {isa = PBXBuildFile; fileRef = 08AAB1B11026168B007E1230 /* SheepShaver */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 08B5FAFD102497FA0047FD1B /* VMSettingsWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 08B5FAFB102497FA0047FD1B /* VMSettingsWindow.nib */; }; 08B5FB01102498B00047FD1B /* VMListWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 08B5FAFF102498B00047FD1B /* VMListWindow.nib */; }; 08B5FB221024FE320047FD1B /* AppController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 08B5FB211024FE320047FD1B /* AppController.mm */; }; @@ -209,6 +209,9 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0900; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SheepShaverLauncher" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -310,11 +313,13 @@ PREFS_EDITOR, STANDALONE_PREFS, ); - GCC_VERSION = 4.0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; OTHER_CFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.SheepShaverLauncher; PRODUCT_NAME = SheepShaverLauncher; + SDKROOT = macosx; WRAPPER_EXTENSION = app; ZERO_LINK = YES; }; @@ -324,11 +329,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - ppc, - i386, - x86_64, - ); COPY_PHASE_STRIP = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; @@ -337,15 +337,17 @@ PREFS_EDITOR, STANDALONE_PREFS, ); - GCC_VERSION = 4.0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; "GCC_VERSION[arch=x86_64]" = 4.2; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; OTHER_CFLAGS = "$(inherited)"; PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.SheepShaverLauncher; PRODUCT_NAME = SheepShaverLauncher; - "SDKROOT[arch=x86_64]" = macosx10.6; + SDKROOT = macosx; + "SDKROOT[arch=x86_64]" = macosx10.13; WRAPPER_EXTENSION = app; }; name = Release; @@ -353,8 +355,33 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; }; @@ -363,10 +390,33 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = LauncherPrefix.h; GCC_VERSION = 4.0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; PREBINDING = NO; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; }; diff --git a/SheepShaver/src/MacOSX/Launcher/VMSettingsController.mm b/SheepShaver/src/MacOSX/Launcher/VMSettingsController.mm index a53191758..7575152d7 100755 --- a/SheepShaver/src/MacOSX/Launcher/VMSettingsController.mm +++ b/SheepShaver/src/MacOSX/Launcher/VMSettingsController.mm @@ -30,6 +30,8 @@ #include +#include "SDL.h" + // NSInteger was added in 10.5 SDK. #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 #if __LP64__ || NS_BUILD_32_LIKE_64 @@ -143,8 +145,10 @@ - (void) setupGUI [romFile setStringValue: getStringFromPrefs("rom") ]; [unixRoot setStringValue: getStringFromPrefs("extfs") ]; [disableCdrom setIntValue: PrefsFindBool("nocdrom") ]; - [ramSize setIntValue: PrefsFindInt32("ramsize") / (1024*1024) ]; - [ramSizeStepper setIntValue: PrefsFindInt32("ramsize") / (1024*1024) ]; + int ramsize = PrefsFindInt32("ramsize"); + if (ramsize > 1000) ramsize >>= 20; + [ramSize setIntValue: ramsize ]; + [ramSizeStepper setIntValue: ramsize ]; int display_type = 0; int dis_width = 640; @@ -159,8 +163,8 @@ - (void) setupGUI } [videoType selectItemAtIndex: display_type ]; - [width setIntValue: dis_width ]; - [height setIntValue: dis_height ]; + [width setStringValue:[NSString stringWithFormat:@"%d", dis_width]]; + [height setStringValue:[NSString stringWithFormat:@"%d", dis_height]]; int frameskip = PrefsFindInt32("frameskip"); int item = -1; @@ -476,6 +480,10 @@ - (void) saveChanges: (id) sender [[self window] close]; [NSApp stopModal]; cancelWasClicked = NO; + + // quit + SDL_Event event = { .type = SDL_QUIT }; + SDL_PushEvent(&event); } - (BOOL) cancelWasClicked diff --git a/SheepShaver/src/MacOSX/PrefsEditor/Info.plist b/SheepShaver/src/MacOSX/PrefsEditor/Info.plist index 682154862..dfaec90d9 100644 --- a/SheepShaver/src/MacOSX/PrefsEditor/Info.plist +++ b/SheepShaver/src/MacOSX/PrefsEditor/Info.plist @@ -1,5 +1,5 @@ - + CFBundleDevelopmentRegion @@ -9,7 +9,7 @@ CFBundleIconFile CFBundleIdentifier - net.sourceforge.SheepShaverPrefs + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SheepShaver/src/MacOSX/PrefsEditor/PrefsEditor.mm b/SheepShaver/src/MacOSX/PrefsEditor/PrefsEditor.mm index 29b48305f..ca833b45f 100644 --- a/SheepShaver/src/MacOSX/PrefsEditor/PrefsEditor.mm +++ b/SheepShaver/src/MacOSX/PrefsEditor/PrefsEditor.mm @@ -54,12 +54,12 @@ - (id) init return self; } -- (int)numberOfRowsInTableView:(NSTableView *)aTable +- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTable { return [diskArray count]; } -- (id)tableView:(NSTableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(int)aRow +- (id)tableView:(NSTableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow { return [diskArray objectAtIndex: aRow]; } diff --git a/SheepShaver/src/MacOSX/PrefsEditor/SheepShaverPrefs.xcodeproj/project.pbxproj b/SheepShaver/src/MacOSX/PrefsEditor/SheepShaverPrefs.xcodeproj/project.pbxproj index 92ed7a0ef..38729eced 100644 --- a/SheepShaver/src/MacOSX/PrefsEditor/SheepShaverPrefs.xcodeproj/project.pbxproj +++ b/SheepShaver/src/MacOSX/PrefsEditor/SheepShaverPrefs.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 42; + objectVersion = 45; objects = { /* Begin PBXBuildFile section */ @@ -161,10 +161,19 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0900; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SheepShaverPrefs" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = en; hasScannedForEncodings = 1; + knownRegions = ( + en, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* SheepShaverPrefs */; projectDirPath = ""; + projectRoot = ""; targets = ( 8D1107260486CEB800E47090 /* SheepShaverPrefs */, ); @@ -234,7 +243,9 @@ INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; OTHER_CFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.SheepShaverPrefs; PRODUCT_NAME = SheepShaverPrefs; + SDKROOT = macosx; WRAPPER_EXTENSION = app; ZERO_LINK = YES; }; @@ -243,10 +254,6 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc, - i386, - ); GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; GCC_MODEL_TUNING = G5; @@ -257,7 +264,9 @@ INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; OTHER_CFLAGS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.SheepShaverPrefs; PRODUCT_NAME = SheepShaverPrefs; + SDKROOT = macosx; WRAPPER_EXTENSION = app; }; name = Release; @@ -265,20 +274,66 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; }; name = Release; }; diff --git a/SheepShaver/src/MacOSX/SheepShaver.entitlements b/SheepShaver/src/MacOSX/SheepShaver.entitlements new file mode 100644 index 000000000..a1c430a57 --- /dev/null +++ b/SheepShaver/src/MacOSX/SheepShaver.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + + diff --git a/SheepShaver/src/MacOSX/SheepShaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SheepShaver/src/MacOSX/SheepShaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/SheepShaver/src/MacOSX/SheepShaver.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj b/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 44bdb27db..2e90ac44d --- a/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj +++ b/SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj @@ -3,20 +3,17 @@ archiveVersion = 1; classes = { }; - objectVersion = 44; + objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 08003F8C1E0624D100A3ADAB /* basic-dyngen-ops-x86_32.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 08003F851E0624D100A3ADAB /* basic-dyngen-ops-x86_32.hpp */; }; - 08003F8D1E0624D100A3ADAB /* basic-dyngen-ops-x86_64.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 08003F861E0624D100A3ADAB /* basic-dyngen-ops-x86_64.hpp */; }; 08003F8E1E0624D100A3ADAB /* basic-dyngen-ops.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 08003F871E0624D100A3ADAB /* basic-dyngen-ops.hpp */; }; 08003F8F1E0624D100A3ADAB /* ppc-dyngen-ops-x86_32.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 08003F881E0624D100A3ADAB /* ppc-dyngen-ops-x86_32.hpp */; }; - 08003F901E0624D100A3ADAB /* ppc-dyngen-ops-x86_64.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 08003F891E0624D100A3ADAB /* ppc-dyngen-ops-x86_64.hpp */; }; 08003F911E0624D100A3ADAB /* ppc-dyngen-ops.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 08003F8A1E0624D100A3ADAB /* ppc-dyngen-ops.hpp */; }; 08163339158C121000C449F9 /* dis-asm.h in Headers */ = {isa = PBXBuildFile; fileRef = 08163337158C121000C449F9 /* dis-asm.h */; }; 08163340158C125800C449F9 /* ppc-dis.c in Sources */ = {isa = PBXBuildFile; fileRef = 08163338158C121000C449F9 /* ppc-dis.c */; }; 082AC22D14AA52E900071F5E /* prefs_editor_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 082AC22C14AA52E900071F5E /* prefs_editor_dummy.cpp */; }; - 082AC26214AA59F000071F5E /* lowmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 082AC26114AA59F000071F5E /* lowmem.c */; }; 083E370C16EFE85000CCCA59 /* disk_sparsebundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083E370A16EFE85000CCCA59 /* disk_sparsebundle.cpp */; }; 083E372216EFE87200CCCA59 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083E372016EFE87200CCCA59 /* tinyxml2.cpp */; }; 0846E4B114B1264700574779 /* ieeefp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CDF714A99EEF000B1711 /* ieeefp.cpp */; }; @@ -31,10 +28,6 @@ 0846E4C114B1268B00574779 /* jit-cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CDCD14A99EEF000B1711 /* jit-cache.cpp */; }; 0846E4C214B1269600574779 /* basic-dyngen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CDC514A99EEF000B1711 /* basic-dyngen.cpp */; }; 0846E51314B128ED00574779 /* sheepshaver_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CDBB14A99EEF000B1711 /* sheepshaver_glue.cpp */; }; - 0846E65414B513CE00574779 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 0856D17414A9A1A2000B1711 /* SDL.framework */; }; - 0856CFC114A99EF0000B1711 /* adb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CD4B14A99EEF000B1711 /* adb.cpp */; }; - 0856CFC214A99EF0000B1711 /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CD4C14A99EEF000B1711 /* audio.cpp */; }; - 0856CFE214A99EF0000B1711 /* cdrom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CD7814A99EEF000B1711 /* cdrom.cpp */; }; 0856CFE614A99EF0000B1711 /* disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CD7D14A99EEF000B1711 /* disk.cpp */; }; 0856CFEC14A99EF0000B1711 /* scsi_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CD8414A99EEF000B1711 /* scsi_dummy.cpp */; }; 0856CFEE14A99EF0000B1711 /* emul_op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CD8614A99EEF000B1711 /* emul_op.cpp */; }; @@ -54,32 +47,11 @@ 0856D06014A99EF1000B1711 /* rsrc_patches.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE8D14A99EF0000B1711 /* rsrc_patches.cpp */; }; 0856D06114A99EF1000B1711 /* scsi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE8E14A99EF0000B1711 /* scsi.cpp */; }; 0856D06214A99EF1000B1711 /* audio_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9014A99EF0000B1711 /* audio_sdl.cpp */; }; - 0856D06414A99EF1000B1711 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9314A99EF0000B1711 /* SDLMain.m */; }; - 0856D06514A99EF1000B1711 /* video_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9414A99EF0000B1711 /* video_sdl.cpp */; }; 0856D06614A99EF1000B1711 /* serial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9514A99EF0000B1711 /* serial.cpp */; }; - 0856D06714A99EF1000B1711 /* bootp.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9714A99EF0000B1711 /* bootp.c */; }; - 0856D06814A99EF1000B1711 /* cksum.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9914A99EF0000B1711 /* cksum.c */; }; - 0856D06A14A99EF1000B1711 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9C14A99EF0000B1711 /* debug.c */; }; - 0856D06B14A99EF1000B1711 /* if.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE9F14A99EF0000B1711 /* if.c */; }; - 0856D06C14A99EF1000B1711 /* ip_icmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEA214A99EF0000B1711 /* ip_icmp.c */; }; - 0856D06D14A99EF1000B1711 /* ip_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEA414A99EF0000B1711 /* ip_input.c */; }; - 0856D06E14A99EF1000B1711 /* ip_output.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEA514A99EF0000B1711 /* ip_output.c */; }; - 0856D06F14A99EF1000B1711 /* mbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEA814A99EF0000B1711 /* mbuf.c */; }; - 0856D07014A99EF1000B1711 /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEAA14A99EF0000B1711 /* misc.c */; }; - 0856D07114A99EF1000B1711 /* sbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEAC14A99EF0000B1711 /* sbuf.c */; }; - 0856D07214A99EF1000B1711 /* slirp.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEAE14A99EF0000B1711 /* slirp.c */; }; - 0856D07314A99EF1000B1711 /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEB114A99EF0000B1711 /* socket.c */; }; - 0856D07414A99EF1000B1711 /* tcp_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEB414A99EF0000B1711 /* tcp_input.c */; settings = {COMPILER_FLAGS = "-O1"; }; }; - 0856D07514A99EF1000B1711 /* tcp_output.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEB514A99EF0000B1711 /* tcp_output.c */; }; - 0856D07614A99EF1000B1711 /* tcp_subr.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEB614A99EF0000B1711 /* tcp_subr.c */; }; - 0856D07714A99EF1000B1711 /* tcp_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEB714A99EF0000B1711 /* tcp_timer.c */; }; - 0856D07814A99EF1000B1711 /* tftp.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEBB14A99EF0000B1711 /* tftp.c */; }; - 0856D07914A99EF1000B1711 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEBD14A99EF0000B1711 /* udp.c */; }; 0856D07B14A99EF1000B1711 /* sony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEC014A99EF0000B1711 /* sony.cpp */; }; 0856D07C14A99EF1000B1711 /* thunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEC114A99EF0000B1711 /* thunks.cpp */; }; 0856D07D14A99EF1000B1711 /* timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEC214A99EF0000B1711 /* timer.cpp */; }; 0856D07E14A99EF1000B1711 /* about_window_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEC414A99EF0000B1711 /* about_window_unix.cpp */; }; - 0856D08714A99EF1000B1711 /* bincue_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CECF14A99EF0000B1711 /* bincue_unix.cpp */; }; 0856D09814A99EF1000B1711 /* ether_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEE314A99EF0000B1711 /* ether_unix.cpp */; }; 0856D0AA14A99EF1000B1711 /* main_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CEFB14A99EF0000B1711 /* main_unix.cpp */; }; 0856D10614A99EF1000B1711 /* prefs_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CF5A14A99EF0000B1711 /* prefs_unix.cpp */; }; @@ -94,7 +66,6 @@ 0856D11714A99EF1000B1711 /* user_strings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CF7714A99EF0000B1711 /* user_strings.cpp */; }; 0856D11814A99EF1000B1711 /* video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CF7814A99EF0000B1711 /* video.cpp */; }; 0856D13F14A99EF1000B1711 /* xpram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CFC014A99EF0000B1711 /* xpram.cpp */; }; - 0856D17514A9A1A2000B1711 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0856D17414A9A1A2000B1711 /* SDL.framework */; }; 0856D21514A9A6C6000B1711 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0856D21414A9A6C6000B1711 /* IOKit.framework */; }; 0856D33514A9A704000B1711 /* VMSettingsWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 0856D30714A9A704000B1711 /* VMSettingsWindow.nib */; }; 0856D33914A9A704000B1711 /* VMSettingsController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0856D31214A9A704000B1711 /* VMSettingsController.mm */; }; @@ -104,18 +75,49 @@ 087B91C01B780FFC00825F7F /* vm_alloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 087B91BC1B780FFC00825F7F /* vm_alloc.cpp */; }; 08CD42DC14B7B85B009CA2A2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08CD42DB14B7B85B009CA2A2 /* Cocoa.framework */; }; 08CD42E814B7B8AA009CA2A2 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08CD42E714B7B8AA009CA2A2 /* Carbon.framework */; }; - 08E877521E0640E800A90A2C /* clip_macosx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0856CE2C14A99EF0000B1711 /* clip_macosx.cpp */; }; + 3D2C25B5221092BA00B635DE /* SheepVM.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3D2C25B4221092BA00B635DE /* SheepVM.icns */; }; + 5D2143D524B2DD90008BB372 /* bincue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D2143D424B2DD90008BB372 /* bincue.h */; }; + 5D35961124B8F5FB0081EC8A /* bincue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D35961024B8F5FA0081EC8A /* bincue.cpp */; }; + 5D55CB40225584D000FF8E81 /* cdrom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D55CB3F225584D000FF8E81 /* cdrom.cpp */; }; + 5DE93B46247C71F200B2C821 /* adb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D3967BF2328D315003925D6 /* adb.cpp */; }; + 5DF4CB7F22B5BD5D00512A86 /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DF4CB7E22B5BD5D00512A86 /* audio.cpp */; }; A7B1921418C35D4700791D8D /* DiskType.m in Sources */ = {isa = PBXBuildFile; fileRef = A7B1921318C35D4700791D8D /* DiskType.m */; }; + E413A40320CF7E6D00FBE967 /* video_sdl2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E413A40220CF7E6D00FBE967 /* video_sdl2.cpp */; }; + E4150D1220D557820077C51A /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E4150D1120D557820077C51A /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E41936C420CFE64D003A7654 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = E41936C320CFE64D003A7654 /* SDLMain.m */; }; + E4202603241250EE000508DF /* runtool.c in Sources */ = {isa = PBXBuildFile; fileRef = E4202602241250EE000508DF /* runtool.c */; }; + E420260524125182000508DF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E420260424125182000508DF /* Security.framework */; }; + E420260B24125442000508DF /* etherhelpertool in Resources */ = {isa = PBXBuildFile; fileRef = E420260A2412540D000508DF /* etherhelpertool */; }; + E420910120D0C4FA0094654F /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E420910020D0C4FA0094654F /* SDL2.framework */; }; + E444DC1520C8F06700DD29C9 /* pict.c in Sources */ = {isa = PBXBuildFile; fileRef = E444DC1420C8F06700DD29C9 /* pict.c */; }; + E447067025D904D500EA2C14 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E447066F25D904D500EA2C14 /* Metal.framework */; }; + E44C460520D262B0000583AE /* tftp.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45DC20D262AD000583AE /* tftp.c */; }; + E44C460620D262B0000583AE /* mbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45DD20D262AD000583AE /* mbuf.c */; }; + E44C460720D262B0000583AE /* ip_icmp.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45DF20D262AD000583AE /* ip_icmp.c */; }; + E44C460820D262B0000583AE /* VERSION_ in Resources */ = {isa = PBXBuildFile; fileRef = E44C45E220D262AE000583AE /* VERSION_ */; }; + E44C460920D262B0000583AE /* tcp_input.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45E520D262AE000583AE /* tcp_input.c */; }; + E44C460A20D262B0000583AE /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45E620D262AE000583AE /* misc.c */; }; + E44C460B20D262B0000583AE /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45E920D262AE000583AE /* debug.c */; }; + E44C460C20D262B0000583AE /* tcp_subr.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45EA20D262AE000583AE /* tcp_subr.c */; }; + E44C460D20D262B0000583AE /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45EB20D262AE000583AE /* udp.c */; }; + E44C460E20D262B0000583AE /* sbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45ED20D262AE000583AE /* sbuf.c */; }; + E44C460F20D262B0000583AE /* COPYRIGHT in Resources */ = {isa = PBXBuildFile; fileRef = E44C45F020D262AE000583AE /* COPYRIGHT */; }; + E44C461020D262B0000583AE /* slirp.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45F120D262AE000583AE /* slirp.c */; }; + E44C461120D262B0000583AE /* tcp_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45F520D262AF000583AE /* tcp_timer.c */; }; + E44C461220D262B0000583AE /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45FC20D262AF000583AE /* socket.c */; }; + E44C461320D262B0000583AE /* bootp.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C45FF20D262AF000583AE /* bootp.c */; }; + E44C461420D262B0000583AE /* ip_input.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C460020D262AF000583AE /* ip_input.c */; }; + E44C461520D262B0000583AE /* ip_output.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C460120D262AF000583AE /* ip_output.c */; }; + E44C461620D262B0000583AE /* if.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C460220D262AF000583AE /* if.c */; }; + E44C461720D262B0000583AE /* cksum.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C460320D262AF000583AE /* cksum.c */; }; + E44C461820D262B0000583AE /* tcp_output.c in Sources */ = {isa = PBXBuildFile; fileRef = E44C460420D262AF000583AE /* tcp_output.c */; }; + 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 */ - 082AC26714AA5A4800071F5E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0856CCAE14A99DE0000B1711 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 082AC25114AA59B600071F5E; - remoteInfo = lowmem; - }; 0846E4A614B1253500574779 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 0856CCAE14A99DE0000B1711 /* Project object */; @@ -126,32 +128,28 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 0846E65E14B513DF00574779 /* Copy Frameworks */ = { + E413A40820CF7EF800FBE967 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 0846E65414B513CE00574779 /* SDL.framework in Copy Frameworks */, + E4150D1220D557820077C51A /* SDL2.framework in Embed Frameworks */, ); - name = "Copy Frameworks"; + name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 08003F851E0624D100A3ADAB /* basic-dyngen-ops-x86_32.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "basic-dyngen-ops-x86_32.hpp"; path = "dyngen_precompiled/basic-dyngen-ops-x86_32.hpp"; sourceTree = ""; }; - 08003F861E0624D100A3ADAB /* basic-dyngen-ops-x86_64.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "basic-dyngen-ops-x86_64.hpp"; path = "dyngen_precompiled/basic-dyngen-ops-x86_64.hpp"; sourceTree = ""; }; 08003F871E0624D100A3ADAB /* basic-dyngen-ops.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "basic-dyngen-ops.hpp"; path = "dyngen_precompiled/basic-dyngen-ops.hpp"; sourceTree = ""; }; 08003F881E0624D100A3ADAB /* ppc-dyngen-ops-x86_32.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "ppc-dyngen-ops-x86_32.hpp"; path = "dyngen_precompiled/ppc-dyngen-ops-x86_32.hpp"; sourceTree = ""; }; - 08003F891E0624D100A3ADAB /* ppc-dyngen-ops-x86_64.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "ppc-dyngen-ops-x86_64.hpp"; path = "dyngen_precompiled/ppc-dyngen-ops-x86_64.hpp"; sourceTree = ""; }; 08003F8A1E0624D100A3ADAB /* ppc-dyngen-ops.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = "ppc-dyngen-ops.hpp"; path = "dyngen_precompiled/ppc-dyngen-ops.hpp"; sourceTree = ""; }; 08003F8B1E0624D100A3ADAB /* ppc-execute-impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ppc-execute-impl.cpp"; path = "dyngen_precompiled/ppc-execute-impl.cpp"; sourceTree = ""; }; 08163337158C121000C449F9 /* dis-asm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "dis-asm.h"; sourceTree = ""; }; 08163338158C121000C449F9 /* ppc-dis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ppc-dis.c"; sourceTree = ""; }; 082AC22C14AA52E900071F5E /* prefs_editor_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prefs_editor_dummy.cpp; sourceTree = ""; }; - 082AC25214AA59B600071F5E /* lowmem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lowmem; sourceTree = BUILT_PRODUCTS_DIR; }; - 082AC26114AA59F000071F5E /* lowmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lowmem.c; path = ../../../BasiliskII/src/Unix/Darwin/lowmem.c; sourceTree = SOURCE_ROOT; }; 083E370A16EFE85000CCCA59 /* disk_sparsebundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = disk_sparsebundle.cpp; path = ../Unix/disk_sparsebundle.cpp; sourceTree = SOURCE_ROOT; }; 083E370B16EFE85000CCCA59 /* disk_unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = disk_unix.h; path = ../Unix/disk_unix.h; sourceTree = SOURCE_ROOT; }; 083E372016EFE87200CCCA59 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml2.cpp; path = ../Unix/tinyxml2.cpp; sourceTree = SOURCE_ROOT; }; @@ -160,9 +158,6 @@ 0846E52314B129DA00574779 /* ppc_asm.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = ppc_asm.S; sourceTree = ""; }; 0846E55214B12B0D00574779 /* paranoia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = paranoia.cpp; sourceTree = ""; }; 0856CCC114A99E1C000B1711 /* SheepShaver.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SheepShaver.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 0856CD4B14A99EEF000B1711 /* adb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adb.cpp; path = ../adb.cpp; sourceTree = SOURCE_ROOT; }; - 0856CD4C14A99EEF000B1711 /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio.cpp; path = ../audio.cpp; sourceTree = SOURCE_ROOT; }; - 0856CD7814A99EEF000B1711 /* cdrom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cdrom.cpp; path = ../cdrom.cpp; sourceTree = SOURCE_ROOT; }; 0856CD7D14A99EEF000B1711 /* disk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = disk.cpp; path = ../disk.cpp; sourceTree = SOURCE_ROOT; }; 0856CD8414A99EEF000B1711 /* scsi_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scsi_dummy.cpp; sourceTree = ""; }; 0856CD8614A99EEF000B1711 /* emul_op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = emul_op.cpp; path = ../emul_op.cpp; sourceTree = SOURCE_ROOT; }; @@ -261,7 +256,6 @@ 0856CE0314A99EEF000B1711 /* utils-cpuinfo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = "utils-cpuinfo.hpp"; sourceTree = ""; }; 0856CE0414A99EEF000B1711 /* utils-sentinel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = "utils-sentinel.hpp"; sourceTree = ""; }; 0856CE0514A99EEF000B1711 /* macos_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = macos_util.cpp; path = ../macos_util.cpp; sourceTree = SOURCE_ROOT; }; - 0856CE2C14A99EF0000B1711 /* clip_macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clip_macosx.cpp; sourceTree = ""; }; 0856CE2D14A99EF0000B1711 /* extfs_macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = extfs_macosx.cpp; sourceTree = ""; }; 0856CE6D14A99EF0000B1711 /* macos_util_macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macos_util_macosx.h; sourceTree = ""; }; 0856CE7014A99EF0000B1711 /* prefs_macosx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = prefs_macosx.mm; sourceTree = ""; }; @@ -276,57 +270,11 @@ 0856CE8E14A99EF0000B1711 /* scsi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = scsi.cpp; path = ../scsi.cpp; sourceTree = SOURCE_ROOT; }; 0856CE9014A99EF0000B1711 /* audio_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio_sdl.cpp; sourceTree = ""; }; 0856CE9114A99EF0000B1711 /* keycodes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = keycodes; sourceTree = ""; }; - 0856CE9214A99EF0000B1711 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = ""; }; - 0856CE9314A99EF0000B1711 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = ""; }; - 0856CE9414A99EF0000B1711 /* video_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_sdl.cpp; sourceTree = ""; }; 0856CE9514A99EF0000B1711 /* serial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = serial.cpp; path = ../serial.cpp; sourceTree = SOURCE_ROOT; }; - 0856CE9714A99EF0000B1711 /* bootp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bootp.c; sourceTree = ""; }; - 0856CE9814A99EF0000B1711 /* bootp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootp.h; sourceTree = ""; }; - 0856CE9914A99EF0000B1711 /* cksum.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cksum.c; sourceTree = ""; }; - 0856CE9A14A99EF0000B1711 /* COPYRIGHT */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYRIGHT; sourceTree = ""; }; - 0856CE9B14A99EF0000B1711 /* ctl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ctl.h; sourceTree = ""; }; - 0856CE9C14A99EF0000B1711 /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = debug.c; sourceTree = ""; }; - 0856CE9D14A99EF0000B1711 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; - 0856CE9E14A99EF0000B1711 /* icmp_var.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icmp_var.h; sourceTree = ""; }; - 0856CE9F14A99EF0000B1711 /* if.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = if.c; sourceTree = ""; }; - 0856CEA014A99EF0000B1711 /* if.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = if.h; sourceTree = ""; }; - 0856CEA114A99EF0000B1711 /* ip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ip.h; sourceTree = ""; }; - 0856CEA214A99EF0000B1711 /* ip_icmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ip_icmp.c; sourceTree = ""; }; - 0856CEA314A99EF0000B1711 /* ip_icmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ip_icmp.h; sourceTree = ""; }; - 0856CEA414A99EF0000B1711 /* ip_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ip_input.c; sourceTree = ""; }; - 0856CEA514A99EF0000B1711 /* ip_output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ip_output.c; sourceTree = ""; }; - 0856CEA614A99EF0000B1711 /* libslirp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libslirp.h; sourceTree = ""; }; - 0856CEA714A99EF0000B1711 /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = ""; }; - 0856CEA814A99EF0000B1711 /* mbuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mbuf.c; sourceTree = ""; }; - 0856CEA914A99EF0000B1711 /* mbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mbuf.h; sourceTree = ""; }; - 0856CEAA14A99EF0000B1711 /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = misc.c; sourceTree = ""; }; - 0856CEAB14A99EF0000B1711 /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = misc.h; sourceTree = ""; }; - 0856CEAC14A99EF0000B1711 /* sbuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbuf.c; sourceTree = ""; }; - 0856CEAD14A99EF0000B1711 /* sbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sbuf.h; sourceTree = ""; }; - 0856CEAE14A99EF0000B1711 /* slirp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = slirp.c; sourceTree = ""; }; - 0856CEAF14A99EF0000B1711 /* slirp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slirp.h; sourceTree = ""; }; - 0856CEB014A99EF0000B1711 /* slirp_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slirp_config.h; sourceTree = ""; }; - 0856CEB114A99EF0000B1711 /* socket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = socket.c; sourceTree = ""; }; - 0856CEB214A99EF0000B1711 /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.h; sourceTree = ""; }; - 0856CEB314A99EF0000B1711 /* tcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcp.h; sourceTree = ""; }; - 0856CEB414A99EF0000B1711 /* tcp_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp_input.c; sourceTree = ""; }; - 0856CEB514A99EF0000B1711 /* tcp_output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp_output.c; sourceTree = ""; }; - 0856CEB614A99EF0000B1711 /* tcp_subr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp_subr.c; sourceTree = ""; }; - 0856CEB714A99EF0000B1711 /* tcp_timer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp_timer.c; sourceTree = ""; }; - 0856CEB814A99EF0000B1711 /* tcp_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcp_timer.h; sourceTree = ""; }; - 0856CEB914A99EF0000B1711 /* tcp_var.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcp_var.h; sourceTree = ""; }; - 0856CEBA14A99EF0000B1711 /* tcpip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcpip.h; sourceTree = ""; }; - 0856CEBB14A99EF0000B1711 /* tftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tftp.c; sourceTree = ""; }; - 0856CEBC14A99EF0000B1711 /* tftp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tftp.h; sourceTree = ""; }; - 0856CEBD14A99EF0000B1711 /* udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udp.c; sourceTree = ""; }; - 0856CEBE14A99EF0000B1711 /* udp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udp.h; sourceTree = ""; }; - 0856CEBF14A99EF0000B1711 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = ""; }; 0856CEC014A99EF0000B1711 /* sony.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sony.cpp; path = ../sony.cpp; sourceTree = SOURCE_ROOT; }; 0856CEC114A99EF0000B1711 /* thunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = thunks.cpp; path = ../thunks.cpp; sourceTree = SOURCE_ROOT; }; 0856CEC214A99EF0000B1711 /* timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timer.cpp; path = ../timer.cpp; sourceTree = SOURCE_ROOT; }; 0856CEC414A99EF0000B1711 /* about_window_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = about_window_unix.cpp; sourceTree = ""; }; - 0856CECF14A99EF0000B1711 /* bincue_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bincue_unix.cpp; sourceTree = ""; }; - 0856CED014A99EF0000B1711 /* bincue_unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bincue_unix.h; sourceTree = ""; }; 0856CEE314A99EF0000B1711 /* ether_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ether_unix.cpp; sourceTree = ""; }; 0856CEFB14A99EF0000B1711 /* main_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main_unix.cpp; sourceTree = ""; }; 0856CF5A14A99EF0000B1711 /* prefs_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = prefs_unix.cpp; sourceTree = ""; }; @@ -348,7 +296,6 @@ 0856CF7714A99EF0000B1711 /* user_strings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = user_strings.cpp; path = ../user_strings.cpp; sourceTree = SOURCE_ROOT; }; 0856CF7814A99EF0000B1711 /* video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = video.cpp; path = ../video.cpp; sourceTree = SOURCE_ROOT; }; 0856CFC014A99EF0000B1711 /* xpram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xpram.cpp; path = ../xpram.cpp; sourceTree = SOURCE_ROOT; }; - 0856D17414A9A1A2000B1711 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; }; 0856D21414A9A6C6000B1711 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 0856D30814A9A704000B1711 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/VMSettingsWindow.nib; sourceTree = ""; }; 0856D31114A9A704000B1711 /* VMSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMSettingsController.h; sourceTree = ""; }; @@ -363,7 +310,6 @@ 0873A80014AC515D004F12B7 /* utils_macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils_macosx.h; sourceTree = ""; }; 0873A80114AC515D004F12B7 /* utils_macosx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = utils_macosx.mm; sourceTree = ""; }; 0879BD5B15A88F6300DC277D /* pict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pict.h; sourceTree = ""; }; - 0879BD5D15A88F7600DC277D /* pict.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pict.c; path = ../pict.c; sourceTree = SOURCE_ROOT; }; 0879BD8515A891EC00DC277D /* config-macosx-ppc_32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "config-macosx-ppc_32.h"; sourceTree = ""; }; 0879BD8615A891EC00DC277D /* config-macosx-x86_32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "config-macosx-x86_32.h"; sourceTree = ""; }; 0879BDAF15A8B1AA00DC277D /* Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist.in; sourceTree = ""; }; @@ -376,19 +322,83 @@ 087B91BD1B780FFC00825F7F /* vm_alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vm_alloc.h; path = ../CrossPlatform/vm_alloc.h; sourceTree = SOURCE_ROOT; }; 08CD42DB14B7B85B009CA2A2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 08CD42E714B7B8AA009CA2A2 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; - 08D93A15159FE174003B04EC /* clip_macosx64.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = clip_macosx64.mm; sourceTree = ""; }; + 3D2C25B4221092BA00B635DE /* SheepVM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = SheepVM.icns; sourceTree = ""; }; + 5D2143D424B2DD90008BB372 /* bincue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bincue.h; sourceTree = ""; }; + 5D35961024B8F5FA0081EC8A /* bincue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bincue.cpp; path = ../../../BasiliskII/src/bincue.cpp; sourceTree = ""; }; + 5D3967BF2328D315003925D6 /* adb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adb.cpp; path = ../../../BasiliskII/src/adb.cpp; sourceTree = ""; }; + 5D55CB3F225584D000FF8E81 /* cdrom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cdrom.cpp; path = ../../../BasiliskII/src/cdrom.cpp; sourceTree = ""; }; + 5DDE94F82255C70C004D0E79 /* MacOSX_sound_if.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MacOSX_sound_if.h; path = ../../../BasiliskII/src/MacOSX/MacOSX_sound_if.h; sourceTree = ""; }; + 5DDE94FA2255C712004D0E79 /* MacOSX_sound_if.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MacOSX_sound_if.cpp; path = ../../../BasiliskII/src/MacOSX/MacOSX_sound_if.cpp; sourceTree = ""; }; + 5DDE94FD2255C740004D0E79 /* AudioBackEnd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioBackEnd.h; path = ../../../BasiliskII/src/MacOSX/AudioBackEnd.h; sourceTree = ""; }; + 5DDE94FF2255C74C004D0E79 /* AudioBackEnd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioBackEnd.cpp; path = ../../../BasiliskII/src/MacOSX/AudioBackEnd.cpp; sourceTree = ""; }; + 5DDE95082255C88E004D0E79 /* AudioDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDevice.cpp; path = ../../../BasiliskII/src/MacOSX/AudioDevice.cpp; sourceTree = ""; }; + 5DDE950B2255C895004D0E79 /* AudioBackEnd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioBackEnd.h; path = ../../../BasiliskII/src/MacOSX/AudioBackEnd.h; sourceTree = ""; }; + 5DDE950D2255C8B3004D0E79 /* audio_defs_macosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = audio_defs_macosx.h; path = ../../../BasiliskII/src/MacOSX/audio_defs_macosx.h; sourceTree = ""; }; + 5DDE950E2255C8B3004D0E79 /* audio_macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio_macosx.cpp; path = ../../../BasiliskII/src/MacOSX/audio_macosx.cpp; sourceTree = ""; }; + 5DF4CB7E22B5BD5D00512A86 /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = audio.cpp; path = ../../../BasiliskII/src/audio.cpp; sourceTree = ""; }; A7B1921218C35D4700791D8D /* DiskType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiskType.h; sourceTree = ""; }; A7B1921318C35D4700791D8D /* DiskType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiskType.m; sourceTree = ""; }; + E413A40220CF7E6D00FBE967 /* video_sdl2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = video_sdl2.cpp; path = ../../../BasiliskII/src/SDL/video_sdl2.cpp; sourceTree = ""; }; + E4150D1120D557820077C51A /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; + E41936C220CFE64D003A7654 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLMain.h; path = ../../../BasiliskII/src/SDL/SDLMain.h; sourceTree = ""; }; + E41936C320CFE64D003A7654 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLMain.m; path = ../../../BasiliskII/src/SDL/SDLMain.m; sourceTree = ""; }; + E4202600241250E2000508DF /* etherhelpertool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = etherhelpertool.c; sourceTree = ""; }; + E4202602241250EE000508DF /* runtool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = runtool.c; sourceTree = ""; }; + E420260424125182000508DF /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + E420260A2412540D000508DF /* etherhelpertool */ = {isa = PBXFileReference; lastKnownFileType = text; path = etherhelpertool; sourceTree = BUILT_PRODUCTS_DIR; }; + E420910020D0C4FA0094654F /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; + E4302EE21FBFE7FA00A5B500 /* lowmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lowmem.c; path = Darwin/lowmem.c; sourceTree = ""; }; + E444DC1420C8F06700DD29C9 /* pict.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pict.c; path = ../pict.c; sourceTree = ""; }; + E447066F25D904D500EA2C14 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + E44C45DC20D262AD000583AE /* tftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tftp.c; path = ../../../BasiliskII/src/slirp/tftp.c; sourceTree = ""; }; + E44C45DD20D262AD000583AE /* mbuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mbuf.c; path = ../../../BasiliskII/src/slirp/mbuf.c; sourceTree = ""; }; + E44C45DE20D262AD000583AE /* tftp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tftp.h; path = ../../../BasiliskII/src/slirp/tftp.h; sourceTree = ""; }; + E44C45DF20D262AD000583AE /* ip_icmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ip_icmp.c; path = ../../../BasiliskII/src/slirp/ip_icmp.c; sourceTree = ""; }; + E44C45E020D262AE000583AE /* bootp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bootp.h; path = ../../../BasiliskII/src/slirp/bootp.h; sourceTree = ""; }; + E44C45E120D262AE000583AE /* tcpip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tcpip.h; path = ../../../BasiliskII/src/slirp/tcpip.h; sourceTree = ""; }; + E44C45E220D262AE000583AE /* VERSION_ */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = VERSION_; path = ../../../BasiliskII/src/slirp/VERSION_; sourceTree = ""; }; + E44C45E320D262AE000583AE /* ip_icmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ip_icmp.h; path = ../../../BasiliskII/src/slirp/ip_icmp.h; sourceTree = ""; }; + E44C45E420D262AE000583AE /* slirp_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = slirp_config.h; path = ../../../BasiliskII/src/slirp/slirp_config.h; sourceTree = ""; }; + E44C45E520D262AE000583AE /* tcp_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tcp_input.c; path = ../../../BasiliskII/src/slirp/tcp_input.c; sourceTree = ""; }; + E44C45E620D262AE000583AE /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = misc.c; path = ../../../BasiliskII/src/slirp/misc.c; sourceTree = ""; }; + E44C45E720D262AE000583AE /* udp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = udp.h; path = ../../../BasiliskII/src/slirp/udp.h; sourceTree = ""; }; + E44C45E820D262AE000583AE /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main.h; path = ../../../BasiliskII/src/slirp/main.h; sourceTree = ""; }; + E44C45E920D262AE000583AE /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug.c; path = ../../../BasiliskII/src/slirp/debug.c; sourceTree = ""; }; + E44C45EA20D262AE000583AE /* tcp_subr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tcp_subr.c; path = ../../../BasiliskII/src/slirp/tcp_subr.c; sourceTree = ""; }; + E44C45EB20D262AE000583AE /* udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udp.c; path = ../../../BasiliskII/src/slirp/udp.c; sourceTree = ""; }; + E44C45EC20D262AE000583AE /* mbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mbuf.h; path = ../../../BasiliskII/src/slirp/mbuf.h; sourceTree = ""; }; + E44C45ED20D262AE000583AE /* sbuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sbuf.c; path = ../../../BasiliskII/src/slirp/sbuf.c; sourceTree = ""; }; + E44C45EE20D262AE000583AE /* ctl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ctl.h; path = ../../../BasiliskII/src/slirp/ctl.h; sourceTree = ""; }; + E44C45EF20D262AE000583AE /* slirp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = slirp.h; path = ../../../BasiliskII/src/slirp/slirp.h; sourceTree = ""; }; + E44C45F020D262AE000583AE /* COPYRIGHT */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYRIGHT; path = ../../../BasiliskII/src/slirp/COPYRIGHT; sourceTree = ""; }; + E44C45F120D262AE000583AE /* slirp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = slirp.c; path = ../../../BasiliskII/src/slirp/slirp.c; sourceTree = ""; }; + E44C45F220D262AE000583AE /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = socket.h; path = ../../../BasiliskII/src/slirp/socket.h; sourceTree = ""; }; + E44C45F320D262AF000583AE /* if.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = if.h; path = ../../../BasiliskII/src/slirp/if.h; sourceTree = ""; }; + E44C45F420D262AF000583AE /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../../../BasiliskII/src/slirp/misc.h; sourceTree = ""; }; + E44C45F520D262AF000583AE /* tcp_timer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tcp_timer.c; path = ../../../BasiliskII/src/slirp/tcp_timer.c; sourceTree = ""; }; + E44C45F620D262AF000583AE /* sbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sbuf.h; path = ../../../BasiliskII/src/slirp/sbuf.h; sourceTree = ""; }; + E44C45F720D262AF000583AE /* tcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tcp.h; path = ../../../BasiliskII/src/slirp/tcp.h; sourceTree = ""; }; + E44C45F820D262AF000583AE /* ip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ip.h; path = ../../../BasiliskII/src/slirp/ip.h; sourceTree = ""; }; + E44C45F920D262AF000583AE /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debug.h; path = ../../../BasiliskII/src/slirp/debug.h; sourceTree = ""; }; + E44C45FA20D262AF000583AE /* tcp_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tcp_timer.h; path = ../../../BasiliskII/src/slirp/tcp_timer.h; sourceTree = ""; }; + E44C45FB20D262AF000583AE /* tcp_var.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tcp_var.h; path = ../../../BasiliskII/src/slirp/tcp_var.h; sourceTree = ""; }; + E44C45FC20D262AF000583AE /* socket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = socket.c; path = ../../../BasiliskII/src/slirp/socket.c; sourceTree = ""; }; + E44C45FD20D262AF000583AE /* libslirp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libslirp.h; path = ../../../BasiliskII/src/slirp/libslirp.h; sourceTree = ""; }; + E44C45FE20D262AF000583AE /* icmp_var.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = icmp_var.h; path = ../../../BasiliskII/src/slirp/icmp_var.h; sourceTree = ""; }; + E44C45FF20D262AF000583AE /* bootp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bootp.c; path = ../../../BasiliskII/src/slirp/bootp.c; sourceTree = ""; }; + E44C460020D262AF000583AE /* ip_input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ip_input.c; path = ../../../BasiliskII/src/slirp/ip_input.c; sourceTree = ""; }; + E44C460120D262AF000583AE /* ip_output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ip_output.c; path = ../../../BasiliskII/src/slirp/ip_output.c; sourceTree = ""; }; + E44C460220D262AF000583AE /* if.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = if.c; path = ../../../BasiliskII/src/slirp/if.c; sourceTree = ""; }; + E44C460320D262AF000583AE /* cksum.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cksum.c; path = ../../../BasiliskII/src/slirp/cksum.c; sourceTree = ""; }; + E44C460420D262AF000583AE /* tcp_output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tcp_output.c; path = ../../../BasiliskII/src/slirp/tcp_output.c; sourceTree = ""; }; + E456E2AC20C82B60006C8DC2 /* clip_macosx64.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = clip_macosx64.mm; sourceTree = ""; }; + 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 */ - 082AC25014AA59B600071F5E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 0846E49814B124DE00574779 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -400,9 +410,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0856D17514A9A1A2000B1711 /* SDL.framework in Frameworks */, + E420910120D0C4FA0094654F /* SDL2.framework in Frameworks */, + E420260524125182000508DF /* Security.framework in Frameworks */, 0856D21514A9A6C6000B1711 /* IOKit.framework in Frameworks */, 08CD42DC14B7B85B009CA2A2 /* Cocoa.framework in Frameworks */, + E447067025D904D500EA2C14 /* Metal.framework in Frameworks */, 08CD42E814B7B8AA009CA2A2 /* Carbon.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -414,10 +426,10 @@ isa = PBXGroup; children = ( 08003F851E0624D100A3ADAB /* basic-dyngen-ops-x86_32.hpp */, - 08003F861E0624D100A3ADAB /* basic-dyngen-ops-x86_64.hpp */, + E4C9A03D1FD55CDC00CABBF9 /* basic-dyngen-ops-x86_64_macos.hpp */, 08003F871E0624D100A3ADAB /* basic-dyngen-ops.hpp */, 08003F881E0624D100A3ADAB /* ppc-dyngen-ops-x86_32.hpp */, - 08003F891E0624D100A3ADAB /* ppc-dyngen-ops-x86_64.hpp */, + E4C9A03F1FD55CE700CABBF9 /* ppc-dyngen-ops-x86_64_macos.hpp */, 08003F8A1E0624D100A3ADAB /* ppc-dyngen-ops.hpp */, 08003F8B1E0624D100A3ADAB /* ppc-execute-impl.cpp */, ); @@ -427,7 +439,7 @@ 082AC25614AA59DA00071F5E /* Darwin */ = { isa = PBXGroup; children = ( - 082AC26114AA59F000071F5E /* lowmem.c */, + E4302EE21FBFE7FA00A5B500 /* lowmem.c */, ); name = Darwin; sourceTree = ""; @@ -435,9 +447,11 @@ 0856CCAC14A99DE0000B1711 = { isa = PBXGroup; children = ( + E4150D1120D557820077C51A /* SDL2.framework */, 0856CCC814A99E30000B1711 /* Sources */, 08CD42DF14B7B865009CA2A2 /* Frameworks */, 0856CCC214A99E1C000B1711 /* Products */, + E420260924125403000508DF /* Generated */, ); sourceTree = ""; }; @@ -445,7 +459,6 @@ isa = PBXGroup; children = ( 0856CCC114A99E1C000B1711 /* SheepShaver.app */, - 082AC25214AA59B600071F5E /* lowmem */, 0846E49A14B124DE00574779 /* libkpx_cpu.a */, ); name = Products; @@ -455,9 +468,10 @@ isa = PBXGroup; children = ( 087B91B11B780EC900825F7F /* CrossPlatform */, - 0856CD4B14A99EEF000B1711 /* adb.cpp */, - 0856CD4C14A99EEF000B1711 /* audio.cpp */, - 0856CD7814A99EEF000B1711 /* cdrom.cpp */, + 5D3967BF2328D315003925D6 /* adb.cpp */, + 5DF4CB7E22B5BD5D00512A86 /* audio.cpp */, + 5D35961024B8F5FA0081EC8A /* bincue.cpp */, + 5D55CB3F225584D000FF8E81 /* cdrom.cpp */, 0856CD7D14A99EEF000B1711 /* disk.cpp */, 0856CD7E14A99EEF000B1711 /* dummy */, 0856CD8614A99EEF000B1711 /* emul_op.cpp */, @@ -470,7 +484,7 @@ 0856CE0614A99EEF000B1711 /* MacOSX */, 0856CE8814A99EF0000B1711 /* main.cpp */, 0856CE8914A99EF0000B1711 /* name_registry.cpp */, - 0879BD5D15A88F7600DC277D /* pict.c */, + E444DC1420C8F06700DD29C9 /* pict.c */, 0856CE8A14A99EF0000B1711 /* prefs_items.cpp */, 0856CE8B14A99EF0000B1711 /* prefs.cpp */, 0856CE8C14A99EF0000B1711 /* rom_patches.cpp */, @@ -508,6 +522,7 @@ 0856CD9014A99EEF000B1711 /* adb.h */, 0856CD9114A99EEF000B1711 /* audio.h */, 0856CD9214A99EEF000B1711 /* audio_defs.h */, + 5D2143D424B2DD90008BB372 /* bincue.h */, 0856CD9314A99EEF000B1711 /* cdrom.h */, 0856CD9414A99EEF000B1711 /* clip.h */, 0856CD9514A99EEF000B1711 /* cpu_emulation.h */, @@ -715,18 +730,28 @@ 0856CE0614A99EEF000B1711 /* MacOSX */ = { isa = PBXGroup; children = ( + E4202600241250E2000508DF /* etherhelpertool.c */, + E4202602241250EE000508DF /* runtool.c */, 0873A76514ABD151004F12B7 /* config */, 0856D2D614A9A704000B1711 /* Launcher */, - 0856CE2C14A99EF0000B1711 /* clip_macosx.cpp */, - 08D93A15159FE174003B04EC /* clip_macosx64.mm */, + 5DDE950D2255C8B3004D0E79 /* audio_defs_macosx.h */, + 5DDE950E2255C8B3004D0E79 /* audio_macosx.cpp */, + 5DDE94FD2255C740004D0E79 /* AudioBackEnd.h */, + 5DDE94FF2255C74C004D0E79 /* AudioBackEnd.cpp */, + 5DDE95082255C88E004D0E79 /* AudioDevice.cpp */, + 5DDE950B2255C895004D0E79 /* AudioBackEnd.h */, + E456E2AC20C82B60006C8DC2 /* clip_macosx64.mm */, 0856CE2D14A99EF0000B1711 /* extfs_macosx.cpp */, 0879BDAF15A8B1AA00DC277D /* Info.plist.in */, 0856CE6D14A99EF0000B1711 /* macos_util_macosx.h */, 0856CE7014A99EF0000B1711 /* prefs_macosx.mm */, 0856CE8314A99EF0000B1711 /* SheepShaver.icns */, + 3D2C25B4221092BA00B635DE /* SheepVM.icns */, 0856CE8714A99EF0000B1711 /* sys_darwin.cpp */, 0873A80014AC515D004F12B7 /* utils_macosx.h */, 0873A80114AC515D004F12B7 /* utils_macosx.mm */, + 5DDE94F82255C70C004D0E79 /* MacOSX_sound_if.h */, + 5DDE94FA2255C712004D0E79 /* MacOSX_sound_if.cpp */, ); name = MacOSX; sourceTree = ""; @@ -736,9 +761,10 @@ children = ( 0856CE9014A99EF0000B1711 /* audio_sdl.cpp */, 0856CE9114A99EF0000B1711 /* keycodes */, - 0856CE9214A99EF0000B1711 /* SDLMain.h */, - 0856CE9314A99EF0000B1711 /* SDLMain.m */, - 0856CE9414A99EF0000B1711 /* video_sdl.cpp */, + E41936C220CFE64D003A7654 /* SDLMain.h */, + E41936C320CFE64D003A7654 /* SDLMain.m */, + E4CBF46020CFC451009F40CC /* video_sdl.cpp */, + E413A40220CF7E6D00FBE967 /* video_sdl2.cpp */, ); name = SDL; path = ../SDL; @@ -747,47 +773,47 @@ 0856CE9614A99EF0000B1711 /* slirp */ = { isa = PBXGroup; children = ( - 0856CE9714A99EF0000B1711 /* bootp.c */, - 0856CE9814A99EF0000B1711 /* bootp.h */, - 0856CE9914A99EF0000B1711 /* cksum.c */, - 0856CE9A14A99EF0000B1711 /* COPYRIGHT */, - 0856CE9B14A99EF0000B1711 /* ctl.h */, - 0856CE9C14A99EF0000B1711 /* debug.c */, - 0856CE9D14A99EF0000B1711 /* debug.h */, - 0856CE9E14A99EF0000B1711 /* icmp_var.h */, - 0856CE9F14A99EF0000B1711 /* if.c */, - 0856CEA014A99EF0000B1711 /* if.h */, - 0856CEA114A99EF0000B1711 /* ip.h */, - 0856CEA214A99EF0000B1711 /* ip_icmp.c */, - 0856CEA314A99EF0000B1711 /* ip_icmp.h */, - 0856CEA414A99EF0000B1711 /* ip_input.c */, - 0856CEA514A99EF0000B1711 /* ip_output.c */, - 0856CEA614A99EF0000B1711 /* libslirp.h */, - 0856CEA714A99EF0000B1711 /* main.h */, - 0856CEA814A99EF0000B1711 /* mbuf.c */, - 0856CEA914A99EF0000B1711 /* mbuf.h */, - 0856CEAA14A99EF0000B1711 /* misc.c */, - 0856CEAB14A99EF0000B1711 /* misc.h */, - 0856CEAC14A99EF0000B1711 /* sbuf.c */, - 0856CEAD14A99EF0000B1711 /* sbuf.h */, - 0856CEAE14A99EF0000B1711 /* slirp.c */, - 0856CEAF14A99EF0000B1711 /* slirp.h */, - 0856CEB014A99EF0000B1711 /* slirp_config.h */, - 0856CEB114A99EF0000B1711 /* socket.c */, - 0856CEB214A99EF0000B1711 /* socket.h */, - 0856CEB314A99EF0000B1711 /* tcp.h */, - 0856CEB414A99EF0000B1711 /* tcp_input.c */, - 0856CEB514A99EF0000B1711 /* tcp_output.c */, - 0856CEB614A99EF0000B1711 /* tcp_subr.c */, - 0856CEB714A99EF0000B1711 /* tcp_timer.c */, - 0856CEB814A99EF0000B1711 /* tcp_timer.h */, - 0856CEB914A99EF0000B1711 /* tcp_var.h */, - 0856CEBA14A99EF0000B1711 /* tcpip.h */, - 0856CEBB14A99EF0000B1711 /* tftp.c */, - 0856CEBC14A99EF0000B1711 /* tftp.h */, - 0856CEBD14A99EF0000B1711 /* udp.c */, - 0856CEBE14A99EF0000B1711 /* udp.h */, - 0856CEBF14A99EF0000B1711 /* VERSION */, + E44C45FF20D262AF000583AE /* bootp.c */, + E44C45E020D262AE000583AE /* bootp.h */, + E44C460320D262AF000583AE /* cksum.c */, + E44C45F020D262AE000583AE /* COPYRIGHT */, + E44C45EE20D262AE000583AE /* ctl.h */, + E44C45E920D262AE000583AE /* debug.c */, + E44C45F920D262AF000583AE /* debug.h */, + E44C45FE20D262AF000583AE /* icmp_var.h */, + E44C460220D262AF000583AE /* if.c */, + E44C45F320D262AF000583AE /* if.h */, + E44C45DF20D262AD000583AE /* ip_icmp.c */, + E44C45E320D262AE000583AE /* ip_icmp.h */, + E44C460020D262AF000583AE /* ip_input.c */, + E44C460120D262AF000583AE /* ip_output.c */, + E44C45F820D262AF000583AE /* ip.h */, + E44C45FD20D262AF000583AE /* libslirp.h */, + E44C45E820D262AE000583AE /* main.h */, + E44C45DD20D262AD000583AE /* mbuf.c */, + E44C45EC20D262AE000583AE /* mbuf.h */, + E44C45E620D262AE000583AE /* misc.c */, + E44C45F420D262AF000583AE /* misc.h */, + E44C45ED20D262AE000583AE /* sbuf.c */, + E44C45F620D262AF000583AE /* sbuf.h */, + E44C45E420D262AE000583AE /* slirp_config.h */, + E44C45F120D262AE000583AE /* slirp.c */, + E44C45EF20D262AE000583AE /* slirp.h */, + E44C45FC20D262AF000583AE /* socket.c */, + E44C45F220D262AE000583AE /* socket.h */, + E44C45E520D262AE000583AE /* tcp_input.c */, + E44C460420D262AF000583AE /* tcp_output.c */, + E44C45EA20D262AE000583AE /* tcp_subr.c */, + E44C45F520D262AF000583AE /* tcp_timer.c */, + E44C45FA20D262AF000583AE /* tcp_timer.h */, + E44C45FB20D262AF000583AE /* tcp_var.h */, + E44C45F720D262AF000583AE /* tcp.h */, + E44C45E120D262AE000583AE /* tcpip.h */, + E44C45DC20D262AD000583AE /* tftp.c */, + E44C45DE20D262AD000583AE /* tftp.h */, + E44C45EB20D262AE000583AE /* udp.c */, + E44C45E720D262AE000583AE /* udp.h */, + E44C45E220D262AE000583AE /* VERSION_ */, ); name = slirp; path = ../slirp; @@ -799,8 +825,6 @@ 08003F841E0624BD00A3ADAB /* dyngen_precompiled */, 082AC25614AA59DA00071F5E /* Darwin */, 0856CEC414A99EF0000B1711 /* about_window_unix.cpp */, - 0856CECF14A99EF0000B1711 /* bincue_unix.cpp */, - 0856CED014A99EF0000B1711 /* bincue_unix.h */, 083E370A16EFE85000CCCA59 /* disk_sparsebundle.cpp */, 083E370B16EFE85000CCCA59 /* disk_unix.h */, 0856CEE314A99EF0000B1711 /* ether_unix.cpp */, @@ -845,6 +869,7 @@ 0873A76514ABD151004F12B7 /* config */ = { isa = PBXGroup; children = ( + E4989F3224DE4438004D43E2 /* config-macosx-aarch64.h */, 0879BD8515A891EC00DC277D /* config-macosx-ppc_32.h */, 0879BD8615A891EC00DC277D /* config-macosx-x86_32.h */, 0873A76614ABD151004F12B7 /* config-macosx-x86_64.h */, @@ -870,14 +895,24 @@ 08CD42DF14B7B865009CA2A2 /* Frameworks */ = { isa = PBXGroup; children = ( + E447066F25D904D500EA2C14 /* Metal.framework */, + E420260424125182000508DF /* Security.framework */, + E420910020D0C4FA0094654F /* SDL2.framework */, 08CD42E714B7B8AA009CA2A2 /* Carbon.framework */, 08CD42DB14B7B85B009CA2A2 /* Cocoa.framework */, 0856D21414A9A6C6000B1711 /* IOKit.framework */, - 0856D17414A9A1A2000B1711 /* SDL.framework */, ); name = Frameworks; sourceTree = ""; }; + E420260924125403000508DF /* Generated */ = { + isa = PBXGroup; + children = ( + E420260A2412540D000508DF /* etherhelpertool */, + ); + name = Generated; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -886,9 +921,10 @@ buildActionMask = 2147483647; files = ( 08003F8F1E0624D100A3ADAB /* ppc-dyngen-ops-x86_32.hpp in Headers */, - 08003F901E0624D100A3ADAB /* ppc-dyngen-ops-x86_64.hpp in Headers */, - 08003F8D1E0624D100A3ADAB /* basic-dyngen-ops-x86_64.hpp in Headers */, 08003F8E1E0624D100A3ADAB /* basic-dyngen-ops.hpp in Headers */, + E4C9A03E1FD55CDC00CABBF9 /* basic-dyngen-ops-x86_64_macos.hpp in Headers */, + 5D2143D524B2DD90008BB372 /* bincue.h in Headers */, + E4C9A0401FD55CE700CABBF9 /* ppc-dyngen-ops-x86_64_macos.hpp in Headers */, 08163339158C121000C449F9 /* dis-asm.h in Headers */, 08003F8C1E0624D100A3ADAB /* basic-dyngen-ops-x86_32.hpp in Headers */, 08003F911E0624D100A3ADAB /* ppc-dyngen-ops.hpp in Headers */, @@ -898,22 +934,6 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 082AC25114AA59B600071F5E /* lowmem */ = { - isa = PBXNativeTarget; - buildConfigurationList = 082AC25714AA59DB00071F5E /* Build configuration list for PBXNativeTarget "lowmem" */; - buildPhases = ( - 082AC24F14AA59B600071F5E /* Sources */, - 082AC25014AA59B600071F5E /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = lowmem; - productName = lowmem; - productReference = 082AC25214AA59B600071F5E /* lowmem */; - productType = "com.apple.product-type.tool"; - }; 0846E49914B124DE00574779 /* kpx_cpu */ = { isa = PBXNativeTarget; buildConfigurationList = 0846E4A114B1251400574779 /* Build configuration list for PBXNativeTarget "kpx_cpu" */; @@ -935,19 +955,17 @@ isa = PBXNativeTarget; buildConfigurationList = 0856CCC714A99E1D000B1711 /* Build configuration list for PBXNativeTarget "SheepShaver" */; buildPhases = ( - 0846E65E14B513DF00574779 /* Copy Frameworks */, + E4202606241251C6000508DF /* ShellScript */, 0856CCBD14A99E1C000B1711 /* Resources */, 0856CCBE14A99E1C000B1711 /* Sources */, 0856CCBF14A99E1C000B1711 /* Frameworks */, - 082AC26A14AA5A5A00071F5E /* Run lowmem */, - 08CD43CF14B7BD01009CA2A2 /* Change SDL load path */, 08CD3F3214B665E1009CA2A2 /* Preprocess Info.plist */, + E413A40820CF7EF800FBE967 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( 0846E4A714B1253500574779 /* PBXTargetDependency */, - 082AC26814AA5A4800071F5E /* PBXTargetDependency */, ); name = SheepShaver; productName = SheepShaver; @@ -978,7 +996,6 @@ projectRoot = ""; targets = ( 0856CCC014A99E1C000B1711 /* SheepShaver */, - 082AC25114AA59B600071F5E /* lowmem */, 0846E49914B124DE00574779 /* kpx_cpu */, ); }; @@ -989,7 +1006,11 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + E420260B24125442000508DF /* etherhelpertool in Resources */, + E44C460820D262B0000583AE /* VERSION_ in Resources */, 0856D05914A99EF1000B1711 /* SheepShaver.icns in Resources */, + E44C460F20D262B0000583AE /* COPYRIGHT in Resources */, + 3D2C25B5221092BA00B635DE /* SheepVM.icns in Resources */, 0856D33514A9A704000B1711 /* VMSettingsWindow.nib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -997,21 +1018,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 082AC26A14AA5A5A00071F5E /* Run lowmem */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(BUILT_PRODUCTS_DIR)/$(EXECUTABLE_PATH)", - ); - name = "Run lowmem"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${BUILT_PRODUCTS_DIR}/lowmem\" \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\""; - }; 08CD3F3214B665E1009CA2A2 /* Preprocess Info.plist */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1024,33 +1030,28 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "sed -i '' 's/@PACKAGE_VERSION@/2.4/g' \"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\""; + shellScript = "sed -i '' 's/@PACKAGE_VERSION@/2.5/g' \"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n"; }; - 08CD43CF14B7BD01009CA2A2 /* Change SDL load path */ = { + E4202606241251C6000508DF /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( ); - name = "Change SDL load path"; + outputFileListPaths = ( + ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL \"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}\"\n"; + shellScript = "cc etherhelpertool.c -framework Security -o $BUILT_PRODUCTS_DIR/etherhelpertool\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 082AC24F14AA59B600071F5E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 082AC26214AA59F000071F5E /* lowmem.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 0846E49714B124DE00574779 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1075,69 +1076,72 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 08E877521E0640E800A90A2C /* clip_macosx.cpp in Sources */, - 0856CFC114A99EF0000B1711 /* adb.cpp in Sources */, - 0856CFC214A99EF0000B1711 /* audio.cpp in Sources */, - 0856CFE214A99EF0000B1711 /* cdrom.cpp in Sources */, + 5DE93B46247C71F200B2C821 /* adb.cpp in Sources */, + E44C460B20D262B0000583AE /* debug.c in Sources */, + E44C460C20D262B0000583AE /* tcp_subr.c in Sources */, + E44C461520D262B0000583AE /* ip_output.c in Sources */, + E44C461820D262B0000583AE /* tcp_output.c in Sources */, 0856CFE614A99EF0000B1711 /* disk.cpp in Sources */, 0856CFEC14A99EF0000B1711 /* scsi_dummy.cpp in Sources */, + E44C460E20D262B0000583AE /* sbuf.c in Sources */, 0856CFEE14A99EF0000B1711 /* emul_op.cpp in Sources */, 0856CFF014A99EF0000B1711 /* ether.cpp in Sources */, + 5DF4CB7F22B5BD5D00512A86 /* audio.cpp in Sources */, 0856CFF314A99EF0000B1711 /* extfs.cpp in Sources */, 0856CFF414A99EF0000B1711 /* gfxaccel.cpp in Sources */, 0856D00914A99EF0000B1711 /* macos_util.cpp in Sources */, 0856D02514A99EF0000B1711 /* extfs_macosx.cpp in Sources */, 0856D05014A99EF1000B1711 /* prefs_macosx.mm in Sources */, + E44C461620D262B0000583AE /* if.c in Sources */, 0856D05A14A99EF1000B1711 /* sys_darwin.cpp in Sources */, + E44C460520D262B0000583AE /* tftp.c in Sources */, 0856D05B14A99EF1000B1711 /* main.cpp in Sources */, + E44C460A20D262B0000583AE /* misc.c in Sources */, + E44C461120D262B0000583AE /* tcp_timer.c in Sources */, 0856D05C14A99EF1000B1711 /* name_registry.cpp in Sources */, + E444DC1520C8F06700DD29C9 /* pict.c in Sources */, 0856D05D14A99EF1000B1711 /* prefs_items.cpp in Sources */, + E44C460D20D262B0000583AE /* udp.c in Sources */, + E44C461420D262B0000583AE /* ip_input.c in Sources */, + E44C461320D262B0000583AE /* bootp.c in Sources */, 0856D05E14A99EF1000B1711 /* prefs.cpp in Sources */, + 5D55CB40225584D000FF8E81 /* cdrom.cpp in Sources */, 0856D05F14A99EF1000B1711 /* rom_patches.cpp in Sources */, 0856D06014A99EF1000B1711 /* rsrc_patches.cpp in Sources */, 0856D06114A99EF1000B1711 /* scsi.cpp in Sources */, 0856D06214A99EF1000B1711 /* audio_sdl.cpp in Sources */, - 0856D06414A99EF1000B1711 /* SDLMain.m in Sources */, - 0856D06514A99EF1000B1711 /* video_sdl.cpp in Sources */, 0856D06614A99EF1000B1711 /* serial.cpp in Sources */, - 0856D06714A99EF1000B1711 /* bootp.c in Sources */, - 0856D06814A99EF1000B1711 /* cksum.c in Sources */, - 0856D06A14A99EF1000B1711 /* debug.c in Sources */, - 0856D06B14A99EF1000B1711 /* if.c in Sources */, - 0856D06C14A99EF1000B1711 /* ip_icmp.c in Sources */, - 0856D06D14A99EF1000B1711 /* ip_input.c in Sources */, - 0856D06E14A99EF1000B1711 /* ip_output.c in Sources */, - 0856D06F14A99EF1000B1711 /* mbuf.c in Sources */, - 0856D07014A99EF1000B1711 /* misc.c in Sources */, - 0856D07114A99EF1000B1711 /* sbuf.c in Sources */, - 0856D07214A99EF1000B1711 /* slirp.c in Sources */, - 0856D07314A99EF1000B1711 /* socket.c in Sources */, - 0856D07414A99EF1000B1711 /* tcp_input.c in Sources */, - 0856D07514A99EF1000B1711 /* tcp_output.c in Sources */, - 0856D07614A99EF1000B1711 /* tcp_subr.c in Sources */, - 0856D07714A99EF1000B1711 /* tcp_timer.c in Sources */, - 0856D07814A99EF1000B1711 /* tftp.c in Sources */, - 0856D07914A99EF1000B1711 /* udp.c in Sources */, + E456E2AD20C82B61006C8DC2 /* clip_macosx64.mm in Sources */, + E4202603241250EE000508DF /* runtool.c in Sources */, 0856D07B14A99EF1000B1711 /* sony.cpp in Sources */, 0856D07C14A99EF1000B1711 /* thunks.cpp in Sources */, 0856D07D14A99EF1000B1711 /* timer.cpp in Sources */, 0856D07E14A99EF1000B1711 /* about_window_unix.cpp in Sources */, - 0856D08714A99EF1000B1711 /* bincue_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 */, 0856D10614A99EF1000B1711 /* prefs_unix.cpp in Sources */, 0856D10714A99EF1000B1711 /* rpc_unix.cpp in Sources */, 0856D10814A99EF1000B1711 /* serial_unix.cpp in Sources */, 0856D10C14A99EF1000B1711 /* sshpty.c in Sources */, 0856D10D14A99EF1000B1711 /* strlcpy.c in Sources */, 0856D10E14A99EF1000B1711 /* sys_unix.cpp in Sources */, + E44C461720D262B0000583AE /* cksum.c in Sources */, 0856D10F14A99EF1000B1711 /* timer_unix.cpp in Sources */, + 5D35961124B8F5FB0081EC8A /* bincue.cpp in Sources */, 0856D11114A99EF1000B1711 /* user_strings_unix.cpp in Sources */, + E44C461020D262B0000583AE /* slirp.c in Sources */, 0856D11614A99EF1000B1711 /* xpram_unix.cpp in Sources */, 0856D11714A99EF1000B1711 /* user_strings.cpp in Sources */, + E44C460920D262B0000583AE /* tcp_input.c in Sources */, 0856D11814A99EF1000B1711 /* video.cpp in Sources */, + E41936C420CFE64D003A7654 /* SDLMain.m in Sources */, + E44C461220D262B0000583AE /* socket.c in Sources */, 0856D13F14A99EF1000B1711 /* xpram.cpp in Sources */, 0856D33914A9A704000B1711 /* VMSettingsController.mm in Sources */, + E44C460620D262B0000583AE /* mbuf.c in Sources */, 082AC22D14AA52E900071F5E /* prefs_editor_dummy.cpp in Sources */, 0873A80214AC515D004F12B7 /* utils_macosx.mm in Sources */, 083E370C16EFE85000CCCA59 /* disk_sparsebundle.cpp in Sources */, @@ -1152,11 +1156,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 082AC26814AA5A4800071F5E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 082AC25114AA59B600071F5E /* lowmem */; - targetProxy = 082AC26714AA5A4800071F5E /* PBXContainerItemProxy */; - }; 0846E4A714B1253500574779 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 0846E49914B124DE00574779 /* kpx_cpu */; @@ -1176,66 +1175,27 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 082AC25414AA59B700071F5E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_ENABLE_PASCAL_STRINGS = NO; - GCC_ENABLE_SYMBOL_SEPARATION = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; - PRODUCT_NAME = lowmem; - }; - name = Debug; - }; - 082AC25514AA59B700071F5E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_ENABLE_PASCAL_STRINGS = NO; - GCC_ENABLE_SYMBOL_SEPARATION = NO; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; - PRODUCT_NAME = lowmem; - ZERO_LINK = NO; - }; - name = Release; - }; 0846E49B14B124DF00574779 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULE_DEBUGGING = YES; COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_OPTIMIZATION_LEVEL = 0; + GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = ( "DATADIR=", HAVE_CONFIG_H, - USE_JIT, "_GNU_SOURCE=1", _THREAD_SAFE, _REENTRANT, ); HEADER_SEARCH_PATHS = ( - /Library/Frameworks/SDL.framework/Versions/A/Headers/, + /Library/Frameworks/SDL2.framework/Headers/, ./config/, ../Unix, ../MacOSX/Launcher, @@ -1246,8 +1206,10 @@ ../Unix/dyngen_precompiled, ); INSTALL_PATH = /usr/local/lib; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; PRODUCT_NAME = kpx_cpu; + VALID_ARCHS = "x86_64 arm64"; }; name = Debug; }; @@ -1255,8 +1217,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - COPY_PHASE_STRIP = YES; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULE_DEBUGGING = YES; + COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_DYNAMIC_NO_PIC = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -1264,13 +1228,12 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "DATADIR=", HAVE_CONFIG_H, - USE_JIT, "_GNU_SOURCE=1", _THREAD_SAFE, _REENTRANT, ); HEADER_SEARCH_PATHS = ( - /Library/Frameworks/SDL.framework/Versions/A/Headers/, + /Library/Frameworks/SDL2.framework/Headers/, ./config/, ../Unix, ../MacOSX/Launcher, @@ -1281,8 +1244,10 @@ ../Unix/dyngen_precompiled, ); INSTALL_PATH = /usr/local/lib; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; PRODUCT_NAME = kpx_cpu; + VALID_ARCHS = "x86_64 arm64"; }; name = Release; }; @@ -1314,7 +1279,9 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_ENTITLEMENTS = SheepShaver.entitlements; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; GCC_CW_ASM_SYNTAX = NO; @@ -1327,18 +1294,20 @@ GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = ( + ENABLE_MACOSX_ETHERHELPER, "DATADIR=", HAVE_CONFIG_H, - USE_JIT, "_GNU_SOURCE=1", _THREAD_SAFE, _REENTRANT, + "BINCUE=1", + "USE_SDL_AUDIO=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( - /Library/Frameworks/SDL.framework/Versions/A/Headers/, + /Library/Frameworks/SDL2.framework/Headers, ./config/, ../Unix, ../MacOSX/Launcher, @@ -1346,22 +1315,27 @@ ../kpx_cpu/src, ../kpx_cpu/include, ../include, + ../CrossPlatform, ); INFOPLIST_FILE = Info.plist.in; INFOPLIST_PREFIX_HEADER = ""; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; - MACOSX_DEPLOYMENT_TARGET = 10.6; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.7; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( + OTHER_LDFLAGS = ""; + "OTHER_LDFLAGS[arch=arm64]" = "-lkpx_cpu"; + "OTHER_LDFLAGS[arch=x86_64]" = ( + "-lkpx_cpu", "-pagezero_size", 0x3000, - "-Wl,-seg1addr,0x78048000", - "-lkpx_cpu", ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_BUNDLE_IDENTIFIER = net.cebix.sheepshaver; PRODUCT_NAME = SheepShaver; + VALID_ARCHS = "x86_64 arm64"; WARNING_LDFLAGS = ""; }; name = Debug; @@ -1370,7 +1344,9 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_ENTITLEMENTS = SheepShaver.entitlements; COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; @@ -1384,18 +1360,20 @@ GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = ( + ENABLE_MACOSX_ETHERHELPER, "DATADIR=", HAVE_CONFIG_H, - USE_JIT, "_GNU_SOURCE=1", _THREAD_SAFE, _REENTRANT, + "BINCUE=1", + "USE_SDL_AUDIO=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( - /Library/Frameworks/SDL.framework/Versions/A/Headers/, + /Library/Frameworks/SDL2.framework/Headers, ./config/, ../Unix, ../MacOSX/Launcher, @@ -1403,38 +1381,34 @@ ../kpx_cpu/src, ../kpx_cpu/include, ../include, + ../CrossPlatform, ); INFOPLIST_EXPAND_BUILD_SETTINGS = NO; INFOPLIST_FILE = Info.plist.in; INFOPLIST_PREFIX_HEADER = ""; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; - MACOSX_DEPLOYMENT_TARGET = 10.6; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.7; OTHER_CFLAGS = ""; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = ( + OTHER_LDFLAGS = ""; + "OTHER_LDFLAGS[arch=arm64]" = "-lkpx_cpu"; + "OTHER_LDFLAGS[arch=x86_64]" = ( + "-lkpx_cpu", "-pagezero_size", 0x3000, - "-Wl,-seg1addr,0x78048000", - "-lkpx_cpu", ); PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_BUNDLE_IDENTIFIER = net.cebix.sheepshaver; PRODUCT_NAME = SheepShaver; + VALID_ARCHS = "x86_64 arm64"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 082AC25714AA59DB00071F5E /* Build configuration list for PBXNativeTarget "lowmem" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 082AC25414AA59B700071F5E /* Debug */, - 082AC25514AA59B700071F5E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 0846E4A114B1251400574779 /* Build configuration list for PBXNativeTarget "kpx_cpu" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SheepShaver/src/MacOSX/SheepVM.icns b/SheepShaver/src/MacOSX/SheepVM.icns new file mode 100644 index 000000000..0d6552464 Binary files /dev/null and b/SheepShaver/src/MacOSX/SheepVM.icns differ diff --git a/SheepShaver/src/MacOSX/config/config-macosx-aarch64.h b/SheepShaver/src/MacOSX/config/config-macosx-aarch64.h new file mode 100644 index 000000000..c904f6718 --- /dev/null +++ b/SheepShaver/src/MacOSX/config/config-macosx-aarch64.h @@ -0,0 +1,527 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +#ifndef CONFIG_H +#define CONFIG_H + + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define if using a PowerPC CPU emulator. */ +#define EMULATED_PPC 1 + +/* Define to enable dyngen engine */ +#define ENABLE_DYNGEN 0 + +/* Define is using ESD. */ +/* #undef ENABLE_ESD */ + +/* Define if using Linux fbdev extension. */ +/* #undef ENABLE_FBDEV_DGA */ + +/* Define if using GTK. */ +/* #undef ENABLE_GTK */ + +/* Define if using "mon". */ +/* #undef ENABLE_MON */ + +/* Define if your system supports TUN/TAP devices. */ +/* #undef ENABLE_TUNTAP */ + +/* Define if using video enabled on SEGV signals. */ +/* #undef ENABLE_VOSF */ + +/* Define if using XFree86 DGA extension. */ +/* #undef ENABLE_XF86_DGA */ + +/* Define if using XFree86 DGA extension. */ +/* #undef ENABLE_XF86_VIDMODE */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_AVAILABILITYMACROS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BYTESWAP_H */ + +/* Define to 1 if you have the `ceil' function. */ +#define HAVE_CEIL 1 + +/* Define to 1 if you have the `ceilf' function. */ +#define HAVE_CEILF 1 + +/* Define to 1 if you have the `cfmakeraw' function. */ +#define HAVE_CFMAKERAW 1 + +/* Define to 1 if you have the `clock_gettime' function. */ +/* #undef HAVE_CLOCK_GETTIME */ + +/* Define to 1 if you have the `clock_nanosleep' function. */ +/* #undef HAVE_CLOCK_NANOSLEEP */ + +/* Define if you have /dev/ptmx. */ +/* #undef HAVE_DEV_PTMX */ + +/* Define if you have /dev/ptc. */ +/* #undef HAVE_DEV_PTS_AND_PTC */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the `exp2' function. */ +#define HAVE_EXP2 1 + +/* Define to 1 if you have the `exp2f' function. */ +#define HAVE_EXP2F 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FENV_H 1 + +/* Define to 1 if you have the `floor' function. */ +#define HAVE_FLOOR 1 + +/* Define to 1 if you have the `floorf' function. */ +#define HAVE_FLOORF 1 + +/* Define if framework AppKit is available. */ +#define HAVE_FRAMEWORK_APPKIT 1 + +/* Define if framework AudioToolbox is available. */ +#define HAVE_FRAMEWORK_AUDIOTOOLBOX 1 + +/* Define if framework AudioUnit is available. */ +#define HAVE_FRAMEWORK_AUDIOUNIT 1 + +/* Define if framework Carbon is available. */ +#define HAVE_FRAMEWORK_CARBON 1 + +/* Define if framework CoreAudio is available. */ +#define HAVE_FRAMEWORK_COREAUDIO 1 + +/* Define if framework CoreFoundation is available. */ +#define HAVE_FRAMEWORK_COREFOUNDATION 1 + +/* Define if framework IOKit is available. */ +#define HAVE_FRAMEWORK_IOKIT 1 + +/* Define if framework SDL is available. */ +/* #undef HAVE_FRAMEWORK_SDL */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_HISTORY_H */ + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the header + file. */ +#define HAVE_IOKIT_STORAGE_IOBLOCKSTORAGEDEVICE_H 1 + +/* Define to 1 if you have the `curses' library (-lcurses). */ +/* #undef HAVE_LIBCURSES */ + +/* Define to 1 if you have the `c_r' library (-lc_r). */ +/* #undef HAVE_LIBC_R */ + +/* Define to 1 if you have the `Hcurses' library (-lHcurses). */ +/* #undef HAVE_LIBHCURSES */ + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the `ncurses' library (-lncurses). */ +/* #undef HAVE_LIBNCURSES */ + +/* Define to 1 if you have the `posix4' library (-lposix4). */ +/* #undef HAVE_LIBPOSIX4 */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `PTL' library (-lPTL). */ +/* #undef HAVE_LIBPTL */ + +/* Define to 1 if you have the `readline' library (-lreadline). */ +/* #undef HAVE_LIBREADLINE */ + +/* Define to 1 if you have the `termcap' library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define to 1 if you have the `terminfo' library (-lterminfo). */ +/* #undef HAVE_LIBTERMINFO */ + +/* Define to 1 if you have the `termlib' library (-ltermlib). */ +/* #undef HAVE_LIBTERMLIB */ + +/* Define to 1 if you have the `vhd' library (-lvhd). */ +/* #undef HAVE_LIBVHD */ + +/* Define if there is a linker script to relocate the executable above + 0x70000000. */ +#define HAVE_LINKER_SCRIPT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_IF_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LINUX_IF_TUN_H */ + +/* Define to 1 if you have the `log2' function. */ +#define HAVE_LOG2 1 + +/* Define to 1 if you have the `log2f' function. */ +#define HAVE_LOG2F 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LOGIN_H */ + +/* Define if your system supports Mach exceptions. */ +#define HAVE_MACH_EXCEPTIONS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MACH_MACH_INIT_H 1 + +/* Define to 1 if you have the `mach_task_self' function. */ +#define HAVE_MACH_TASK_SELF 1 + +/* Define if your system has a working vm_allocate()-based memory allocator. + */ +#define HAVE_MACH_VM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MACH_VM_MAP_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MALLOC_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define to 1 if you have the `mmap' function. */ +#define HAVE_MMAP 1 + +/* Define if defines MAP_ANON and mmap()'ing with MAP_ANON works. + */ +/* #undef HAVE_MMAP_ANON */ + +/* Define if defines MAP_ANONYMOUS and mmap()'ing with + MAP_ANONYMOUS works. */ +/* #undef HAVE_MMAP_ANONYMOUS */ + +/* Define if your system has a working mmap()-based memory allocator. */ +/* #undef HAVE_MMAP_VM */ + +/* Define to 1 if you have the `mprotect' function. */ +#define HAVE_MPROTECT 1 + +/* Define to 1 if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define to 1 if you have the `nanosleep' function. */ +#define HAVE_NANOSLEEP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NET_IF_TUN_H */ + +/* Define if you are on NEWS-OS (additions from openssh-3.2.2p1, for + sshpty.c). */ +/* #undef HAVE_NEWS4 */ + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define if pthreads are available. */ +#define HAVE_PTHREADS 1 + +/* Define to 1 if you have the `pthread_cancel' function. */ +#define HAVE_PTHREAD_CANCEL 1 + +/* Define to 1 if you have the `pthread_cond_init' function. */ +#define HAVE_PTHREAD_COND_INIT 1 + +/* Define to 1 if you have the `pthread_mutexattr_setprotocol' function. */ +#define HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL 1 + +/* Define to 1 if you have the `pthread_mutexattr_setpshared' function. */ +#define HAVE_PTHREAD_MUTEXATTR_SETPSHARED 1 + +/* Define to 1 if you have the `pthread_mutexattr_settype' function. */ +#define HAVE_PTHREAD_MUTEXATTR_SETTYPE 1 + +/* Define to 1 if you have the `pthread_testcancel' function. */ +#define HAVE_PTHREAD_TESTCANCEL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PTY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_HISTORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_READLINE_READLINE_H */ + +/* Define to 1 if you have the `round' function. */ +#define HAVE_ROUND 1 + +/* Define to 1 if you have the `roundf' function. */ +#define HAVE_ROUNDF 1 + +/* Define to 1 if you have the `sem_init' function. */ +#define HAVE_SEM_INIT 1 + +/* Define to 1 if you have the `sigaction' function. */ +#define HAVE_SIGACTION 1 + +/* Define if we know a hack to replace siginfo_t->si_addr member. */ +/* #undef HAVE_SIGCONTEXT_SUBTERFUGE */ + +/* Define if your system support extended signals. */ +/* #undef HAVE_SIGINFO_T */ + +/* Define to 1 if you have the `signal' function. */ +#define HAVE_SIGNAL 1 + +/* Define if sa_restorer is available in struct sigaction. */ +/* #undef HAVE_SIGNAL_SA_RESTORER */ + +/* Define if we can ignore the fault (instruction skipping in SIGSEGV + handler). */ +#define HAVE_SIGSEGV_SKIP_INSTRUCTION 1 + +/* Define if slirp library is supported */ +#define HAVE_SLIRP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDLIB_H */ + +/* 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. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BITYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BSDTTY_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_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_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the `task_self' function. */ +/* #undef HAVE_TASK_SELF */ + +/* Define to 1 if you have the `trunc' function. */ +#define HAVE_TRUNC 1 + +/* Define to 1 if you have the `truncf' function. */ +#define HAVE_TRUNCF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIL_H 1 + +/* Define to 1 if you have the `vhangup' function. */ +/* #undef HAVE_VHANGUP */ + +/* Define to 1 if you have the `vm_allocate' function. */ +#define HAVE_VM_ALLOCATE 1 + +/* Define to 1 if you have the `vm_deallocate' function. */ +#define HAVE_VM_DEALLOCATE 1 + +/* Define to 1 if you have the `vm_protect' function. */ +#define HAVE_VM_PROTECT 1 + +/* Define if your system supports Windows exceptions. */ +/* #undef HAVE_WIN32_EXCEPTIONS */ + +/* Define to 1 if you have the `_getpty' function. */ +/* #undef HAVE__GETPTY */ + +/* 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 constant offset for Mac address translation: macosx-aarch64 is always 64bit */ +#define NATMEM_OFFSET 0x400000000000 + +/* 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 "SheepShaver" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "SheepShaver 2.5" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "SheepShaver" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.5" + +/* Define if the __PAGEZERO Mach-O Low Memory Globals hack works on this + system. */ +/* #define PAGEZERO_HACK 1 */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define if your system requires sigactions to be reinstalled. */ +/* #undef SIGACTION_NEED_REINSTALL */ + +/* Define if your system requires signals to be reinstalled. */ +/* #undef SIGNAL_NEED_REINSTALL */ + +/* 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 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 8 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define if BSD-style non-blocking I/O is to be used */ +/* #undef USE_FIONBIO */ + +/* 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 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 + +/* Define to 1 if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* 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 `off_t' if does not define. */ +#define loff_t off_t + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to 'int' if doesn't define. */ +/* #undef socklen_t */ + +#endif /* CONFIG_H */ + diff --git a/SheepShaver/src/MacOSX/config/config-macosx-x86_64.h b/SheepShaver/src/MacOSX/config/config-macosx-x86_64.h index 760e64503..600466b5e 100644 --- a/SheepShaver/src/MacOSX/config/config-macosx-x86_64.h +++ b/SheepShaver/src/MacOSX/config/config-macosx-x86_64.h @@ -415,7 +415,7 @@ #define PACKAGE_NAME "SheepShaver" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "SheepShaver 2.4" +#define PACKAGE_STRING "SheepShaver 2.5" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "SheepShaver" @@ -424,7 +424,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2.4" +#define PACKAGE_VERSION "2.5" /* Define if the __PAGEZERO Mach-O Low Memory Globals hack works on this system. */ @@ -523,5 +523,7 @@ /* Define to 'int' if doesn't define. */ /* #undef socklen_t */ +#define USE_JIT 1 + #endif /* CONFIG_H */ diff --git a/SheepShaver/src/MacOSX/config/config.h b/SheepShaver/src/MacOSX/config/config.h index bb5a07813..a615bca30 100644 --- a/SheepShaver/src/MacOSX/config/config.h +++ b/SheepShaver/src/MacOSX/config/config.h @@ -4,6 +4,8 @@ #include "config-macosx-x86_32.h" #elif defined(__ppc__) #include "config-macosx-ppc_32.h" +#elif defined(__aarch64__) + #include "config-macosx-aarch64.h" #else #error Unknown platform -#endif \ No newline at end of file +#endif diff --git a/SheepShaver/src/MacOSX/etherhelpertool.c b/SheepShaver/src/MacOSX/etherhelpertool.c new file mode 120000 index 000000000..f8c140033 --- /dev/null +++ b/SheepShaver/src/MacOSX/etherhelpertool.c @@ -0,0 +1 @@ +../../../BasiliskII/src/MacOSX/etherhelpertool.c \ No newline at end of file diff --git a/SheepShaver/src/MacOSX/prefs_macosx.mm b/SheepShaver/src/MacOSX/prefs_macosx.mm index e8b779242..4f91cdbb7 100644 --- a/SheepShaver/src/MacOSX/prefs_macosx.mm +++ b/SheepShaver/src/MacOSX/prefs_macosx.mm @@ -30,6 +30,7 @@ #include #include "VMSettingsController.h" +#include @interface SheepShaverMain : NSObject { @@ -96,6 +97,11 @@ - (void) openPreferences:(id)sender [pool release]; } +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + return YES; +} + @end /* @@ -104,12 +110,19 @@ - (void) openPreferences:(id)sender void prefs_init(void) { - NSAutoreleasePool *pool; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; +#if SDL_VERSION_ATLEAST(2,0,0) + for (NSMenuItem *sub_item in [NSApp mainMenu].itemArray[0].submenu.itemArray) { + if ([sub_item.title isEqualToString:@"Preferences…"]) { + sub_item.target = [[SheepShaverMain alloc] init]; + sub_item.action = @selector(openPreferences:); + break; + } + } +#else NSMenu *appMenu; NSMenuItem *menuItem; - pool = [[NSAutoreleasePool alloc] init]; - appMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu]; menuItem = [[NSMenuItem alloc] initWithTitle:@"Preferences..." action:@selector(openPreferences:) keyEquivalent:@","]; [appMenu insertItem:menuItem atIndex:2]; @@ -117,11 +130,10 @@ void prefs_init(void) [menuItem release]; [NSApp setDelegate:[[SheepShaverMain alloc] init]]; - +#endif [pool release]; } - /* * Deinitialization */ diff --git a/SheepShaver/src/MacOSX/runtool.c b/SheepShaver/src/MacOSX/runtool.c new file mode 120000 index 000000000..592a24957 --- /dev/null +++ b/SheepShaver/src/MacOSX/runtool.c @@ -0,0 +1 @@ +../../../BasiliskII/src/MacOSX/runtool.c \ No newline at end of file diff --git a/SheepShaver/src/Unix/.gitignore b/SheepShaver/src/Unix/.gitignore index 0461f22ec..8c6ac66f7 100644 --- a/SheepShaver/src/Unix/.gitignore +++ b/SheepShaver/src/Unix/.gitignore @@ -21,5 +21,7 @@ dyngen # Generated files from the Xcode build basic-dyngen-ops-x86_32.hpp basic-dyngen-ops-x86_64.hpp +basic-dyngen-ops-x86_64_macos.hpp ppc-dyngen-ops-x86_32.hpp ppc-dyngen-ops-x86_64.hpp +ppc-dyngen-ops-x86_64_macos.hpp diff --git a/SheepShaver/src/Unix/Darwin/lowmem.c b/SheepShaver/src/Unix/Darwin/lowmem.c deleted file mode 120000 index 7e0a359c7..000000000 --- a/SheepShaver/src/Unix/Darwin/lowmem.c +++ /dev/null @@ -1 +0,0 @@ -../../../../BasiliskII/src/Unix/Darwin/lowmem.c \ No newline at end of file diff --git a/SheepShaver/src/Unix/Darwin/lowmem.c b/SheepShaver/src/Unix/Darwin/lowmem.c new file mode 100755 index 000000000..a40a36613 --- /dev/null +++ b/SheepShaver/src/Unix/Darwin/lowmem.c @@ -0,0 +1,254 @@ +/* + * lowmem.c - enable access to low memory globals on Darwin + * + * Copyright (c) 2003 Michael Z. Sliczniak + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char progname[] = "lowmem"; +static const char *filename; + +static int do_swap = 0; + +static uint32_t target_uint32(uint32_t value) +{ + if (do_swap) + value = OSSwapInt32(value); + return value; +} + +void pagezero_32(struct mach_header *machhead) +{ + struct segment_command *sc_cmd; + + if (target_uint32(machhead->filetype) != MH_EXECUTE) { + (void)fprintf(stderr, "%s: %s does not appear to be an executable file\n", + progname, filename); + exit(1); + } + if (machhead->ncmds == 0) { + (void)fprintf(stderr, "%s: %s does not contain any load commands\n", + progname, filename); + exit(1); + } + sc_cmd = (void *)&machhead[1]; + if (target_uint32(sc_cmd->cmd) != LC_SEGMENT){ + (void)fprintf(stderr, "%s: load segment not first command in %s\n", + progname, filename); + exit(1); + } + if (strncmp(sc_cmd->segname, "__PAGEZERO", sizeof (*sc_cmd->segname))) { + (void)fprintf(stderr, "%s: zero page not first segment in %s\n", + progname, filename); + exit(1); + } + /* change the permissions */ + sc_cmd->maxprot = target_uint32(VM_PROT_ALL); + sc_cmd->initprot = target_uint32(VM_PROT_ALL); + +#ifdef MH_PIE + /* disable pie in header */ + machhead->flags = target_uint32(target_uint32(machhead->flags) & ~MH_PIE); +#endif +} + +#if defined(MH_MAGIC_64) +void pagezero_64(struct mach_header_64 *machhead) +{ + struct segment_command_64 *sc_cmd; + + if (target_uint32(machhead->filetype) != MH_EXECUTE) { + (void)fprintf(stderr, "%s: %s does not appear to be an executable file\n", + progname, filename); + exit(1); + } + if (machhead->ncmds == 0) { + (void)fprintf(stderr, "%s: %s does not contain any load commands\n", + progname, filename); + exit(1); + } + sc_cmd = (void *)&machhead[1]; + if (target_uint32(sc_cmd->cmd) != LC_SEGMENT_64) { + (void)fprintf(stderr, "%s: load segment not first command in %s\n", + progname, filename); + exit(1); + } + if (strncmp(sc_cmd->segname, "__PAGEZERO", sizeof(*sc_cmd->segname))) { + (void)fprintf(stderr, "%s: zero page not first segment in %s\n", + progname, filename); + exit(1); + } + /* change the permissions */ +// sc_cmd->maxprot = target_uint32(VM_PROT_ALL); +// sc_cmd->initprot = target_uint32(VM_PROT_ALL); +} +#endif + +/* + * Under Mach there is very little assumed about the memory map of object + * files. It is the job of the loader to create the initial memory map of an + * executable. In a Mach-O executable there will be numerous loader commands + * that the loader must process. Some of these will create the initial memory + * map used by the executable. Under Darwin the static object file linker, + * ld, automatically adds the __PAGEZERO segment to all executables. The + * default size of this segment is the page size of the target system and + * the initial and maximum permissions are set to allow no access. This is so + * that all programs fault on a NULL pointer dereference. Arguably this is + * incorrect and the maximum permissions shoould be rwx so that programs can + * change this default behavior. Then programs could be written that assume + * a null string at the null address, which was the convention on some + * systems. In our case we need to have 8K mapped at zero for the low memory + * globals and this program modifies the segment load command in the + * basiliskII executable so that it can be used for data. + */ + +int +main(int argc, const char *argv[]) +{ + int fd; + char *addr; + size_t file_size; + struct mach_header *machhead; +#if defined(MH_MAGIC_64) + struct mach_header_64 *machhead64; +#endif + struct fat_header *fathead; + struct stat f; + + if (argc != 2) { + (void)fprintf(stderr, "Usage: %s executable\n", progname); + exit(1); + } + + filename = argv[1]; + + if (stat(filename, &f)) { + (void)fprintf(stderr, "%s: could not stat %s: %s\n", + progname, filename, strerror(errno)); + exit(1); + } + file_size = (size_t) f.st_size; + + fd = open(filename, O_RDWR, 0); + if (fd == -1) { + (void)fprintf(stderr, "%s: could not open %s: %s\n", + progname, filename, strerror(errno)); + exit(1); + } + + /* + * Size does not really matter, it will be rounded-up to a multiple + * of the page size automatically. + */ + addr = mmap(NULL, file_size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + if (addr == NULL || addr == MAP_FAILED) { + (void)fprintf(stderr, "%s: could not mmap %s: %s\n", + progname, filename, strerror(errno)); + exit(1); + } + + /* + * Check to see if the Mach-O magic bytes are in the header. + */ + machhead = (void *)addr; +#if defined(MH_MAGIC_64) + machhead64 = (void *)addr; +#endif + fathead = (void *)addr; + +#if defined(MH_MAGIC_64) + do_swap = machhead->magic == MH_CIGAM || fathead->magic == FAT_CIGAM || machhead64->magic == MH_CIGAM_64; +#else + do_swap = machhead->magic == MH_CIGAM || fathead->magic == FAT_CIGAM; +#endif + + if (target_uint32(machhead->magic) == MH_MAGIC) { + pagezero_32(machhead); +#if defined(MH_MAGIC_64) + } else if (target_uint32(machhead64->magic) == MH_MAGIC_64) { + pagezero_64(machhead64); +#endif + } else if (target_uint32(fathead->magic) == FAT_MAGIC) { + struct fat_arch *arch = (void *)&fathead[1]; + int saved_swap = do_swap; + int i; + for (i = 0; i < target_uint32(fathead->nfat_arch); ++i, ++arch) { + machhead = (void *)(addr + target_uint32(arch->offset)); +#if defined(MH_MAGIC_64) + machhead64 = (void *)(addr + target_uint32(arch->offset)); +#endif +#if defined(MH_MAGIC_64) + do_swap = machhead->magic == MH_CIGAM || machhead64->magic == MH_CIGAM_64; +#else + do_swap = machhead->magic == MH_CIGAM; +#endif + if (target_uint32(machhead->magic) == MH_MAGIC) { + pagezero_32(machhead); +#if defined(MH_MAGIC_64) + } else if (target_uint32(machhead64->magic) == MH_MAGIC_64) { + pagezero_64(machhead64); +#endif + } else { + (void)fprintf(stderr, "%s: %s does not appear to be a Mach-O object file\n", + progname, filename); + exit(1); + } + do_swap = saved_swap; + } + } else { + (void)fprintf(stderr, "%s: %s does not appear to be a Mach-O object file\n", + progname, filename); + exit(1); + } + + /* + * We do not make __PAGEZERO 8K in this program because then + * all of the offsets would be wrong in the object file after + * this segment. Instead we use the -pagezero_size option + * to link the executable. + */ + if (msync(addr, file_size, MS_SYNC) == -1) { + (void)fprintf(stderr, "%s: could not sync %s: %s\n", + progname, filename, strerror(errno)); + exit(1); + } + + if (munmap(addr, file_size) == -1) { + (void)fprintf(stderr, "%s: could not unmap %s: %s\n", + progname, filename, strerror(errno)); + exit(1); + } + + (void)close(fd); + + exit(0); +} 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/Makefile.in b/SheepShaver/src/Unix/Makefile.in index 350ec4b0b..88ef33944 100644 --- a/SheepShaver/src/Unix/Makefile.in +++ b/SheepShaver/src/Unix/Makefile.in @@ -105,9 +105,6 @@ define GUI_SRCS_LIST_TO_OBJS $(basename $(notdir $(file)))))) endef GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS) -ifeq ($(USE_BINCUE),yes) -GUI_OBJS += bincue_unix.o -endif define DYNGENSRCS_LIST_TO_OBJS $(addprefix $(OBJ_DIR)/, $(addsuffix .dgo, $(foreach file, $(DYNGENSRCS), \ @@ -176,7 +173,7 @@ uninstall: clean: rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak ppc-execute-impl.cpp - rm -f dyngen basic-dyngen-ops.hpp ppc-dyngen-ops.hpp ppc_asm.out.s + rm -f dyngen {basic,ppc}-dyngen-ops*.hpp ppc_asm.out.s rm -rf $(APP_APP) $(GUI_APP_APP) distclean: clean @@ -216,18 +213,22 @@ ifeq ($(USE_DYNGEN),yes) DYNGENDEPS = basic-dyngen-ops.hpp ppc-dyngen-ops.hpp ifeq ($(USE_DYNGEN_PRECOMPILED),yes) -basic-dyngen-ops.hpp: dyngen_precompiled/basic-dyngen-ops.hpp basic-dyngen-ops-x86_32.hpp basic-dyngen-ops-x86_64.hpp +basic-dyngen-ops.hpp: dyngen_precompiled/basic-dyngen-ops.hpp basic-dyngen-ops-x86_32.hpp basic-dyngen-ops-x86_64.hpp basic-dyngen-ops-x86_64_macos.hpp cp -f $< $@ basic-dyngen-ops-x86_32.hpp: dyngen_precompiled/basic-dyngen-ops-x86_32.hpp cp -f $< $@ basic-dyngen-ops-x86_64.hpp: dyngen_precompiled/basic-dyngen-ops-x86_64.hpp cp -f $< $@ -ppc-dyngen-ops.hpp: dyngen_precompiled/ppc-dyngen-ops.hpp ppc-dyngen-ops-x86_32.hpp ppc-dyngen-ops-x86_64.hpp +basic-dyngen-ops-x86_64_macos.hpp: dyngen_precompiled/basic-dyngen-ops-x86_64_macos.hpp + cp -f $< $@ +ppc-dyngen-ops.hpp: dyngen_precompiled/ppc-dyngen-ops.hpp ppc-dyngen-ops-x86_32.hpp ppc-dyngen-ops-x86_64.hpp ppc-dyngen-ops-x86_64_macos.hpp cp -f $< $@ ppc-dyngen-ops-x86_32.hpp: dyngen_precompiled/ppc-dyngen-ops-x86_32.hpp cp -f $< $@ ppc-dyngen-ops-x86_64.hpp: dyngen_precompiled/ppc-dyngen-ops-x86_64.hpp cp -f $< $@ +ppc-dyngen-ops-x86_64_macos.hpp: dyngen_precompiled/ppc-dyngen-ops-x86_64_macos.hpp + cp -f $< $@ else # Only GCC is supported for generating synthetic opcodes $(DYNGEN): $(DYNGENOBJS) 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/bincue_unix.cpp b/SheepShaver/src/Unix/bincue_unix.cpp deleted file mode 120000 index f9ed574d0..000000000 --- a/SheepShaver/src/Unix/bincue_unix.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/Unix/bincue_unix.cpp \ No newline at end of file diff --git a/SheepShaver/src/Unix/bincue_unix.h b/SheepShaver/src/Unix/bincue_unix.h deleted file mode 120000 index 9c7e8c5c0..000000000 --- a/SheepShaver/src/Unix/bincue_unix.h +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/Unix/bincue_unix.h \ No newline at end of file diff --git a/SheepShaver/src/Unix/configure.ac b/SheepShaver/src/Unix/configure.ac old mode 100644 new mode 100755 index 4c23d14f9..33dc2666c --- 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) @@ -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=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=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";; @@ -45,7 +41,7 @@ AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [d *) WANT_GTK="no";; esac], [WANT_GTK="gtk2 gtk"]) -AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes]) +AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=no]) AC_ARG_WITH(dgcc, [ --with-dgcc=COMPILER use C++ COMPILER to compile synthetic opcodes or 'precompiled'], [DYNGEN_CC=$withval]) AC_ARG_WITH(bincue, @@ -68,11 +64,10 @@ AC_ARG_ENABLE(addressing, 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]) -AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphics [default=no]], [WANT_SDL_VIDEO=$enableval], [WANT_SDL_VIDEO=no]) -AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [default=no]], [WANT_SDL_AUDIO=$enableval], [WANT_SDL_AUDIO=no]) +AC_ARG_ENABLE(sdl-video, [ --enable-sdl-video use SDL for video graphics [default=no]], [WANT_SDL_VIDEO=$enableval], [WANT_SDL_VIDEO=yes]) +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(sdl2, [ --with-sdl2 use SDL 2.x, rather than SDL 1.x [default=no]], [WANT_SDL_VERSION_MAJOR=2], [WANT_SDL_VERSION_MAJOR=1]) dnl Checks for programs. AC_PROG_CC @@ -115,7 +110,7 @@ x/* | x.*) WANT_MON=yes ;; xyes) - mon_srcdir=../../../mon/src + mon_srcdir=../../../cxmon/src ;; esac if [[ "x$WANT_MON" = "xyes" ]]; then @@ -123,7 +118,7 @@ if [[ "x$WANT_MON" = "xyes" ]]; then if grep mon_init $mon_srcdir/mon.h >/dev/null 2>/dev/null; then AC_MSG_RESULT(yes) AC_DEFINE(ENABLE_MON, 1, [Define if using "mon".]) - MONSRCS="$mon_srcdir/mon.cpp $mon_srcdir/mon_6502.cpp $mon_srcdir/mon_z80.cpp $mon_srcdir/mon_cmd.cpp $mon_srcdir/mon_lowmem.cpp $mon_srcdir/mon_disass.cpp $mon_srcdir/mon_ppc.cpp $mon_srcdir/disass/floatformat.c $mon_srcdir/disass/i386-dis.c $mon_srcdir/disass/m68k-dis.c $mon_srcdir/disass/m68k-opc.c $mon_srcdir/disass/mips-dis.c $mon_srcdir/disass/mips-opc.c $mon_srcdir/disass/mips16-opc.c" + MONSRCS="$mon_srcdir/mon.cpp $mon_srcdir/mon_6502.cpp $mon_srcdir/mon_z80.cpp $mon_srcdir/mon_cmd.cpp $mon_srcdir/mon_lowmem.cpp $mon_srcdir/mon_disass.cpp $mon_srcdir/mon_ppc.cpp $mon_srcdir/disass/floatformat.c $mon_srcdir/disass/i386-dis.c $mon_srcdir/disass/m68k-dis.c $mon_srcdir/disass/m68k-opc.c" CXXFLAGS="$CXXFLAGS -I$mon_srcdir -I$mon_srcdir/disass" AC_CHECK_LIB(ncurses, tgetent, , [AC_CHECK_LIB(termcap, tgetent, , @@ -177,9 +172,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 @@ -188,66 +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 - if [[ "x$WANT_SDL_VERSION_MAJOR" = "x1" ]]; then - AC_DEFINE(ENABLE_SDL1, 1, [Define if using SDL1.]) - 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" + 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 - SDL_SUPPORT="none" - fi - fi - - if [[ "x$WANT_SDL_VERSION_MAJOR" = "x2" ]]; then - AC_DEFINE(ENABLE_SDL2, 1, [Define if using SDL2.]) - AC_PATH_PROG(sdl_config, "sdl2-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" - else - WANT_SDL=no - WANT_SDL_VIDEO=no - WANT_SDL_AUDIO=no - SDL_SUPPORT="none" + 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/^ //"` @@ -255,19 +207,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 @@ -303,38 +242,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 @@ -384,25 +291,10 @@ 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 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) @@ -499,8 +391,7 @@ esac dnl Check for headers and functions related to pty support (sshpty.c) dnl From openssh-3.2.2p1 configure.ac AC_CHECK_HEADERS(strings.h login.h sys/bsdtty.h sys/stat.h util.h pty.h) -AC_SEARCH_LIBS([openpty], [util bsd]) -AC_CHECK_FUNCS(_getpty openpty vhangup strlcpy) +AC_CHECK_FUNCS(_getpty vhangup strlcpy) case "$host" in *-*-hpux10.26) @@ -627,6 +518,7 @@ AC_CHECK_FRAMEWORK(CoreAudio, [#include ]) AC_CHECK_FRAMEWORK(AudioUnit, [#include ]) AC_CHECK_FRAMEWORK(AudioToolbox, [#include ]) AC_CHECK_FRAMEWORK(AppKit, []) +AC_CHECK_FRAMEWORK(Metal, []) dnl Select system-dependant sources. SERIALSRC=serial_unix.cpp @@ -639,7 +531,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" @@ -669,27 +560,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 @@ -700,6 +575,7 @@ AS_IF([test "x$have_bincue" = "xyes" ], [ AC_SUBST(USE_BINCUE, no) else CPPFLAGS="$CPPFLAGS -DBINCUE $OSX_CORE_AUDIO" + DEFINES="$DEFINES -DBINCUE" AC_SUBST(USE_BINCUE, yes) fi ], [AC_SUBST(USE_BINCUE, no)]) @@ -744,13 +620,10 @@ AC_SUBST(SLIRP_SRCS) dnl SDL overrides if [[ "x$WANT_SDL" = "xyes" ]]; then AC_DEFINE(USE_SDL, 1, [Define to enble SDL support.]) - if [[ "x$WANT_SDL_FRAMEWORK" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS ../SDL/SDLMain.m" - fi 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]) @@ -769,6 +642,9 @@ if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then CPPFLAGS="$CPPFLAGS -I../MacOSX" else EXTRASYSSRCS="$EXTRASYSSRCS ../dummy/clip_dummy.cpp" + if [[ "$WANT_GTK" != "no" ]]; then + LIBS="$LIBS -lX11" + fi fi else VIDEOSRCS="video_x.cpp" @@ -783,7 +659,7 @@ fi dnl BINCUE overrides if [[ "x$have_bincue" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS bincue_unix.cpp" + EXTRASYSSRCS="$EXTRASYSSRCS bincue.cpp" fi dnl libvhd overrides @@ -1448,7 +1324,7 @@ gcc_AC_C_FLOAT_FORMAT dnl Platform specific binary postprocessor AC_PATH_PROG(BLESS, "true") if [[ "x$ac_cv_pagezero_hack" = "xyes" ]]; then - BLESS=Darwin/lowmem +# BLESS=Darwin/lowmem LDFLAGS="$LDFLAGS -pagezero_size 0x3000" fi @@ -1640,13 +1516,13 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then esac fi if [[ "x$have_dyngen_gcc3" = "xyes" ]]; then - DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-align-functions" + DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-align-functions -fno-stack-protector" else DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -malign-functions=0" fi DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -finline-functions -finline-limit=10000 -fno-exceptions -g0" if [[ "x$have_dyngen_gcc3" = "xyes" ]]; then - DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-reorder-blocks -fno-optimize-sibling-calls" + DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-reorder-blocks -fno-optimize-sibling-calls -fno-reorder-blocks-and-partition" fi if [[ "x$DYNGEN_CC" != "x$CXX" ]]; then DYNGEN_CFLAGS="-O2 $CFLAGS" @@ -1742,16 +1618,11 @@ 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 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/dyngen_precompiled/basic-dyngen-ops-x86_64_macos.hpp b/SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops-x86_64_macos.hpp new file mode 100644 index 000000000..1910e577b --- /dev/null +++ b/SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops-x86_64_macos.hpp @@ -0,0 +1,1824 @@ +#define ADD_RAX_RCX 0x01,0xc8 +#define ADD_RDX_RCX 0x01,0xca +#define ADD_RAX_RDX 0x01,0xd0 +#define TRANS_RAX \ + 0x48,0x3D,0x00,0x30,0x00,0x00,\ + 0x72,0x16,\ + 0x48,0x3D,0x00,0xE0,0xFF,0x5F,\ + 0x72,0x14,\ + 0x48,0x25,0xFF,0x1F,0x00,0x00,\ + 0x48,0x05,0x00,0x00,0x00,0x00,\ + 0xEB,0x06,\ + 0x48,0x05,0x00,0x00,0x00,0x00 + +#define TRANS_RDX \ + 0x48,0x81,0xFA,0x00,0x30,0x00,0x00,\ + 0x72,0x19,\ + 0x48,0x81,0xFA,0x00,0xE0,0xFF,0x5F,\ + 0x72,0x17,\ + 0x48,0x81,0xE2,0xFF,0x1F,0x00,0x00,\ + 0x48,0x81,0xC2,0x00,0x00,0x00,0x00,\ + 0xEB,0x07,\ + 0x48,0x81,0xC2,0x00,0x00,0x00,0x00 + +#ifdef DYNGEN_IMPL +extern uint8 gZeroPage[0x3000], gKernelData[0x2000]; +#endif + +#ifndef DEFINE_CST +#define DEFINE_CST(NAME, VALUE) +#endif +DEFINE_GEN(gen_op_invoke,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke +{ + static const uint8 helper_op_invoke_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_code, 12); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0 +{ + static const uint8 helper_op_invoke_T0_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, + 0xe7, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_T0_code, 15); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0_T1,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0_T1 +{ + static const uint8 helper_op_invoke_T0_T1_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, + 0xee, 0x44, 0x89, 0xe7, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_T0_T1_code, 18); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0_T1_T2,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0_T1_T2 +{ + static const uint8 helper_op_invoke_T0_T1_T2_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, + 0xf2, 0x44, 0x89, 0xee, 0x44, 0x89, 0xe7, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_T0_T1_T2_code, 21); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0_ret_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0_ret_T0 +{ + static const uint8 helper_op_invoke_T0_ret_T0_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, + 0xe7, 0xff, 0xd0, 0x41, 0x89, 0xc4 + }; + copy_block(helper_op_invoke_T0_ret_T0_code, 18); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_im +{ + static const uint8 helper_op_invoke_im_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_im_code, 18); + *(uint32_t *)(code_ptr() + 12) = (int32_t)((long)param2 - (long)(code_ptr() + 12 + 4)) + 0; + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU +{ + static const uint8 helper_op_invoke_CPU_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, + 0xef, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_CPU_code, 15); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_T0 +{ + static const uint8 helper_op_invoke_CPU_T0_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, + 0xe6, 0x48, 0x89, 0xef, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_CPU_T0_code, 18); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_im +{ + static const uint8 helper_op_invoke_CPU_im_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, + 0xef, 0x8d, 0x35, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_CPU_im_code, 21); + *(uint32_t *)(code_ptr() + 15) = (int32_t)((long)param2 - (long)(code_ptr() + 15 + 4)) + 0; + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_im_im,void,(long param1, long param2, long param3)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_im_im +{ + static const uint8 helper_op_invoke_CPU_im_im_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, + 0xef, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x35, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xd0 + }; + copy_block(helper_op_invoke_CPU_im_im_code, 27); + *(uint32_t *)(code_ptr() + 21) = (int32_t)((long)param2 - (long)(code_ptr() + 21 + 4)) + 0; + *(uint32_t *)(code_ptr() + 15) = (int32_t)((long)param3 - (long)(code_ptr() + 15 + 4)) + 0; + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_A0_ret_A0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_A0_ret_A0 +{ + static const uint8 helper_op_invoke_CPU_A0_ret_A0_code[] = { + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, + 0xe6, 0x48, 0x89, 0xef, 0xff, 0xd0, 0x49, 0x89, 0xc4 + }; + copy_block(helper_op_invoke_CPU_A0_ret_A0_code, 21); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct +{ + static const uint8 helper_op_invoke_direct_code[] = { + 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_code, 5); + *(uint32_t *)(code_ptr() + 1) = (int32_t)((long)param1 - (long)(code_ptr() + 1 + 4)) + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0 +{ + static const uint8 helper_op_invoke_direct_T0_code[] = { + 0x44, 0x89, 0xe7, 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_T0_code, 8); + *(uint32_t *)(code_ptr() + 4) = (int32_t)((long)param1 - (long)(code_ptr() + 4 + 4)) + 0; + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0_T1,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0_T1 +{ + static const uint8 helper_op_invoke_direct_T0_T1_code[] = { + 0x44, 0x89, 0xee, 0x44, 0x89, 0xe7, 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_T0_T1_code, 11); + *(uint32_t *)(code_ptr() + 7) = (int32_t)((long)param1 - (long)(code_ptr() + 7 + 4)) + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0_T1_T2,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0_T1_T2 +{ + static const uint8 helper_op_invoke_direct_T0_T1_T2_code[] = { + 0x44, 0x89, 0xf2, 0x44, 0x89, 0xee, 0x44, 0x89, 0xe7, 0xe8, 0x00, 0x00, + 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_T0_T1_T2_code, 14); + *(uint32_t *)(code_ptr() + 10) = (int32_t)((long)param1 - (long)(code_ptr() + 10 + 4)) + 0; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0_ret_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0_ret_T0 +{ + static const uint8 helper_op_invoke_direct_T0_ret_T0_code[] = { + 0x44, 0x89, 0xe7, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc4 + }; + copy_block(helper_op_invoke_direct_T0_ret_T0_code, 11); + *(uint32_t *)(code_ptr() + 4) = (int32_t)((long)param1 - (long)(code_ptr() + 4 + 4)) + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_im +{ + static const uint8 helper_op_invoke_direct_im_code[] = { + 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_im_code, 11); + *(uint32_t *)(code_ptr() + 7) = (int32_t)((long)param1 - (long)(code_ptr() + 7 + 4)) + 0; + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param2 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU +{ + static const uint8 helper_op_invoke_direct_CPU_code[] = { + 0x48, 0x89, 0xef, 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_CPU_code, 8); + *(uint32_t *)(code_ptr() + 4) = (int32_t)((long)param1 - (long)(code_ptr() + 4 + 4)) + 0; + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_T0 +{ + static const uint8 helper_op_invoke_direct_CPU_T0_code[] = { + 0x44, 0x89, 0xe6, 0x48, 0x89, 0xef, 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_CPU_T0_code, 11); + *(uint32_t *)(code_ptr() + 7) = (int32_t)((long)param1 - (long)(code_ptr() + 7 + 4)) + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_im +{ + static const uint8 helper_op_invoke_direct_CPU_im_code[] = { + 0x48, 0x89, 0xef, 0x8d, 0x35, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, + 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_CPU_im_code, 14); + *(uint32_t *)(code_ptr() + 10) = (int32_t)((long)param1 - (long)(code_ptr() + 10 + 4)) + 0; + *(uint32_t *)(code_ptr() + 5) = (int32_t)((long)param2 - (long)(code_ptr() + 5 + 4)) + 0; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_im_im,void,(long param1, long param2, long param3)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_im_im +{ + static const uint8 helper_op_invoke_direct_CPU_im_im_code[] = { + 0x48, 0x89, 0xef, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x35, 0x00, + 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_CPU_im_im_code, 20); + *(uint32_t *)(code_ptr() + 16) = (int32_t)((long)param1 - (long)(code_ptr() + 16 + 4)) + 0; + *(uint32_t *)(code_ptr() + 11) = (int32_t)((long)param2 - (long)(code_ptr() + 11 + 4)) + 0; + *(uint32_t *)(code_ptr() + 5) = (int32_t)((long)param3 - (long)(code_ptr() + 5 + 4)) + 0; + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_A0_ret_A0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_A0_ret_A0 +{ + static const uint8 helper_op_invoke_direct_CPU_A0_ret_A0_code[] = { + 0x4c, 0x89, 0xe6, 0x48, 0x89, 0xef, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x89, 0xc4 + }; + copy_block(helper_op_invoke_direct_CPU_A0_ret_A0_code, 14); + *(uint32_t *)(code_ptr() + 7) = (int32_t)((long)param1 - (long)(code_ptr() + 7 + 4)) + 0; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_jmp_fast,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jmp_fast +{ + static const uint8 op_jmp_fast_code[] = { + 0xe9, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_jmp_fast_code, 5); + *(uint32_t *)(code_ptr() + 1) = (int32_t)((long)param1 - (long)(code_ptr() + 1 + 4)) + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_jmp_slow,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jmp_slow +{ + static const uint8 op_jmp_slow_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0 + }; + copy_block(op_jmp_slow_code, 9); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_neg_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_neg_32_T0 +{ + static const uint8 op_neg_32_T0_code[] = { + 0x41, 0xf7, 0xdc + }; + copy_block(op_neg_32_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_not_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_not_32_T0 +{ + static const uint8 op_not_32_T0_code[] = { + 0x45, 0x85, 0xe4, 0x0f, 0x94, 0xc0, 0x44, 0x0f, 0xb6, 0xe0 + }; + copy_block(op_not_32_T0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_not_32_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_not_32_T1 +{ + static const uint8 op_not_32_T1_code[] = { + 0x45, 0x85, 0xed, 0x0f, 0x94, 0xc0, 0x44, 0x0f, 0xb6, 0xe8 + }; + copy_block(op_not_32_T1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_se_8_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_se_8_32_T0 +{ + static const uint8 op_se_8_32_T0_code[] = { + 0x45, 0x0f, 0xbe, 0xe4 + }; + copy_block(op_se_8_32_T0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_ze_8_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ze_8_32_T0 +{ + static const uint8 op_ze_8_32_T0_code[] = { + 0x45, 0x0f, 0xb6, 0xe4 + }; + copy_block(op_ze_8_32_T0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_1 +{ + static const uint8 op_add_32_T0_1_code[] = { + 0x41, 0xff, 0xc4 + }; + copy_block(op_add_32_T0_1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_2 +{ + static const uint8 op_add_32_T0_2_code[] = { + 0x41, 0x83, 0xc4, 0x02 + }; + copy_block(op_add_32_T0_2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_4 +{ + static const uint8 op_add_32_T0_4_code[] = { + 0x41, 0x83, 0xc4, 0x04 + }; + copy_block(op_add_32_T0_4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_8 +{ + static const uint8 op_add_32_T0_8_code[] = { + 0x41, 0x83, 0xc4, 0x08 + }; + copy_block(op_add_32_T0_8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_1 +{ + static const uint8 op_add_32_T1_1_code[] = { + 0x41, 0xff, 0xc5 + }; + copy_block(op_add_32_T1_1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_2 +{ + static const uint8 op_add_32_T1_2_code[] = { + 0x41, 0x83, 0xc5, 0x02 + }; + copy_block(op_add_32_T1_2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_4 +{ + static const uint8 op_add_32_T1_4_code[] = { + 0x41, 0x83, 0xc5, 0x04 + }; + copy_block(op_add_32_T1_4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_8 +{ + static const uint8 op_add_32_T1_8_code[] = { + 0x41, 0x83, 0xc5, 0x08 + }; + copy_block(op_add_32_T1_8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_bswap_16_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_bswap_16_T0 +{ + static const uint8 op_bswap_16_T0_code[] = { + 0x44, 0x89, 0xe0, 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xb7, 0xe0 + }; + copy_block(op_bswap_16_T0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_bswap_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_bswap_32_T0 +{ + static const uint8 op_bswap_32_T0_code[] = { + 0x41, 0x0f, 0xcc + }; + copy_block(op_bswap_32_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_0 +{ + static const uint8 op_mov_32_T0_0_code[] = { + 0x45, 0x31, 0xe4 + }; + copy_block(op_mov_32_T0_0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_0 +{ + static const uint8 op_mov_32_T1_0_code[] = { + 0x45, 0x31, 0xed + }; + copy_block(op_mov_32_T1_0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_0 +{ + static const uint8 op_mov_32_T2_0_code[] = { + 0x45, 0x31, 0xf6 + }; + copy_block(op_mov_32_T2_0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_or_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_or_32_T0_T1 +{ + static const uint8 op_or_32_T0_T1_code[] = { + 0x45, 0x09, 0xec + }; + copy_block(op_or_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_or_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_or_32_T0_im +{ + static const uint8 op_or_32_T0_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x09, 0xc4 + }; + copy_block(op_or_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_se_16_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_se_16_32_T0 +{ + static const uint8 op_se_16_32_T0_code[] = { + 0x45, 0x0f, 0xbf, 0xe4 + }; + copy_block(op_se_16_32_T0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_se_16_32_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_se_16_32_T1 +{ + static const uint8 op_se_16_32_T1_code[] = { + 0x45, 0x0f, 0xbf, 0xed + }; + copy_block(op_se_16_32_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_1 +{ + static const uint8 op_sub_32_T0_1_code[] = { + 0x41, 0xff, 0xcc + }; + copy_block(op_sub_32_T0_1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_2 +{ + static const uint8 op_sub_32_T0_2_code[] = { + 0x41, 0x83, 0xec, 0x02 + }; + copy_block(op_sub_32_T0_2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_4 +{ + static const uint8 op_sub_32_T0_4_code[] = { + 0x41, 0x83, 0xec, 0x04 + }; + copy_block(op_sub_32_T0_4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_8 +{ + static const uint8 op_sub_32_T0_8_code[] = { + 0x41, 0x83, 0xec, 0x08 + }; + copy_block(op_sub_32_T0_8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_1 +{ + static const uint8 op_sub_32_T1_1_code[] = { + 0x41, 0xff, 0xcd + }; + copy_block(op_sub_32_T1_1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_2 +{ + static const uint8 op_sub_32_T1_2_code[] = { + 0x41, 0x83, 0xed, 0x02 + }; + copy_block(op_sub_32_T1_2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_4 +{ + static const uint8 op_sub_32_T1_4_code[] = { + 0x41, 0x83, 0xed, 0x04 + }; + copy_block(op_sub_32_T1_4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_8 +{ + static const uint8 op_sub_32_T1_8_code[] = { + 0x41, 0x83, 0xed, 0x08 + }; + copy_block(op_sub_32_T1_8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_ze_16_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ze_16_32_T0 +{ + static const uint8 op_ze_16_32_T0_code[] = { + 0x45, 0x0f, 0xb7, 0xe4 + }; + copy_block(op_ze_16_32_T0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_T1 +{ + static const uint8 op_add_32_T0_T1_code[] = { + 0x47, 0x8d, 0x64, 0x25, 0x00 + }; + copy_block(op_add_32_T0_T1_code, 5); + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_T2 +{ + static const uint8 op_add_32_T0_T2_code[] = { + 0x47, 0x8d, 0x24, 0x26 + }; + copy_block(op_add_32_T0_T2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_im +{ + static const uint8 op_add_32_T0_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xc4 + }; + copy_block(op_add_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_T0 +{ + static const uint8 op_add_32_T1_T0_code[] = { + 0x47, 0x8d, 0x2c, 0x2c + }; + copy_block(op_add_32_T1_T0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_T2 +{ + static const uint8 op_add_32_T1_T2_code[] = { + 0x47, 0x8d, 0x2c, 0x2e + }; + copy_block(op_add_32_T1_T2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_im +{ + static const uint8 op_add_32_T1_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xc5 + }; + copy_block(op_add_32_T1_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_and_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_and_32_T0_T1 +{ + static const uint8 op_and_32_T0_T1_code[] = { + 0x45, 0x21, 0xec + }; + copy_block(op_and_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_and_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_and_32_T0_im +{ + static const uint8 op_and_32_T0_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xc4 + }; + copy_block(op_and_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_asr_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_asr_32_T0_T1 +{ + static const uint8 op_asr_32_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xfc + }; + copy_block(op_asr_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_asr_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_asr_32_T0_im +{ + static const uint8 op_asr_32_T0_im_code[] = { + 0x48, 0x8d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x41, 0xd3, 0xfc + }; + copy_block(op_asr_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_eqv_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_eqv_32_T0_T1 +{ + static const uint8 op_eqv_32_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x31, 0xe0, 0x41, 0x89, 0xc4, 0x41, 0xf7, 0xd4 + }; + copy_block(op_eqv_32_T0_T1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_lsl_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsl_32_T0_T1 +{ + static const uint8 op_lsl_32_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xe4 + }; + copy_block(op_lsl_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_lsl_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsl_32_T0_im +{ + static const uint8 op_lsl_32_T0_im_code[] = { + 0x48, 0x8d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x41, 0xd3, 0xe4 + }; + copy_block(op_lsl_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_lsr_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsr_32_T0_T1 +{ + static const uint8 op_lsr_32_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xec + }; + copy_block(op_lsr_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_lsr_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsr_32_T0_im +{ + static const uint8 op_lsr_32_T0_im_code[] = { + 0x48, 0x8d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x41, 0xd3, 0xec + }; + copy_block(op_lsr_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_T1 +{ + static const uint8 op_mov_32_T0_T1_code[] = { + 0x45, 0x89, 0xec + }; + copy_block(op_mov_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_T2 +{ + static const uint8 op_mov_32_T0_T2_code[] = { + 0x45, 0x89, 0xf4 + }; + copy_block(op_mov_32_T0_T2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_im +{ + static const uint8 op_mov_32_T0_im_code[] = { + 0x44, 0x8d, 0x25, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_32_T0_im_code, 7); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_T0 +{ + static const uint8 op_mov_32_T1_T0_code[] = { + 0x45, 0x89, 0xe5 + }; + copy_block(op_mov_32_T1_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_T2 +{ + static const uint8 op_mov_32_T1_T2_code[] = { + 0x45, 0x89, 0xf5 + }; + copy_block(op_mov_32_T1_T2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_im +{ + static const uint8 op_mov_32_T1_im_code[] = { + 0x44, 0x8d, 0x2d, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_32_T1_im_code, 7); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_T0 +{ + static const uint8 op_mov_32_T2_T0_code[] = { + 0x45, 0x89, 0xe6 + }; + copy_block(op_mov_32_T2_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_T1 +{ + static const uint8 op_mov_32_T2_T1_code[] = { + 0x45, 0x89, 0xee + }; + copy_block(op_mov_32_T2_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_im +{ + static const uint8 op_mov_32_T2_im_code[] = { + 0x44, 0x8d, 0x35, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_32_T2_im_code, 7); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_mov_ad_A0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_ad_A0_im +{ + static const uint8 op_mov_ad_A0_im_code[] = { + 0x49, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_ad_A0_im_code, 10); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_mov_ad_A1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_ad_A1_im +{ + static const uint8 op_mov_ad_A1_im_code[] = { + 0x49, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_ad_A1_im_code, 10); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_mov_ad_A2_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_ad_A2_im +{ + static const uint8 op_mov_ad_A2_im_code[] = { + 0x49, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_ad_A2_im_code, 10); + *(uint64_t *)(code_ptr() + 2) = (uint64_t)param1 + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_nor_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_nor_32_T0_T1 +{ + static const uint8 op_nor_32_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x09, 0xe0, 0x41, 0x89, 0xc4, 0x41, 0xf7, 0xd4 + }; + copy_block(op_nor_32_T0_T1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_orc_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_orc_32_T0_T1 +{ + static const uint8 op_orc_32_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0xf7, 0xd0, 0x41, 0x09, 0xc4 + }; + copy_block(op_orc_32_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_rol_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rol_32_T0_T1 +{ + static const uint8 op_rol_32_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xc4 + }; + copy_block(op_rol_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_rol_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rol_32_T0_im +{ + static const uint8 op_rol_32_T0_im_code[] = { + 0x44, 0x89, 0xe0, 0x48, 0x8d, 0x35, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x20, + 0x00, 0x00, 0x00, 0x29, 0xf1, 0x44, 0x89, 0xe2, 0xd3, 0xea, 0x89, 0xf1, + 0xd3, 0xe0, 0x41, 0x89, 0xd4, 0x41, 0x09, 0xc4 + }; + copy_block(op_rol_32_T0_im_code, 32); + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(32); +} +#endif + +DEFINE_GEN(gen_op_ror_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ror_32_T0_T1 +{ + static const uint8 op_ror_32_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xcc + }; + copy_block(op_ror_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_ror_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ror_32_T0_im +{ + static const uint8 op_ror_32_T0_im_code[] = { + 0x53, 0x44, 0x89, 0xe0, 0x48, 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00, 0xb9, + 0x20, 0x00, 0x00, 0x00, 0x29, 0xd1, 0x44, 0x89, 0xe6, 0xd3, 0xe6, 0x89, + 0xd1, 0xd3, 0xe8, 0x41, 0x89, 0xf4, 0x41, 0x09, 0xc4, 0x5b + }; + copy_block(op_ror_32_T0_im_code, 34); + *(uint32_t *)(code_ptr() + 7) = (int32_t)((long)param1 - (long)(code_ptr() + 7 + 4)) + 0; + inc_code_ptr(34); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_T1 +{ + static const uint8 op_sub_32_T0_T1_code[] = { + 0x45, 0x29, 0xec + }; + copy_block(op_sub_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_T2 +{ + static const uint8 op_sub_32_T0_T2_code[] = { + 0x45, 0x29, 0xf4 + }; + copy_block(op_sub_32_T0_T2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_im +{ + static const uint8 op_sub_32_T0_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x29, 0xc4 + }; + copy_block(op_sub_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_T0 +{ + static const uint8 op_sub_32_T1_T0_code[] = { + 0x45, 0x29, 0xe5 + }; + copy_block(op_sub_32_T1_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_T2 +{ + static const uint8 op_sub_32_T1_T2_code[] = { + 0x45, 0x29, 0xf5 + }; + copy_block(op_sub_32_T1_T2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_im +{ + static const uint8 op_sub_32_T1_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x29, 0xc5 + }; + copy_block(op_sub_32_T1_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_xor_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_xor_32_T0_T1 +{ + static const uint8 op_xor_32_T0_T1_code[] = { + 0x45, 0x31, 0xec + }; + copy_block(op_xor_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_xor_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_xor_32_T0_im +{ + static const uint8 op_xor_32_T0_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x31, 0xc4 + }; + copy_block(op_xor_32_T0_im_code, 10); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_andc_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_andc_32_T0_T1 +{ + static const uint8 op_andc_32_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0xf7, 0xd0, 0x41, 0x21, 0xc4 + }; + copy_block(op_andc_32_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_nand_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_nand_32_T0_T1 +{ + static const uint8 op_nand_32_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x21, 0xe0, 0x41, 0x89, 0xc4, 0x41, 0xf7, 0xd4 + }; + copy_block(op_nand_32_T0_T1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_sdiv_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sdiv_32_T0_T1 +{ + static const uint8 op_sdiv_32_T0_T1_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe0, 0xc1, 0xfa, 0x1f, 0x41, 0xf7, 0xfd, + 0x41, 0x89, 0xc4 + }; + copy_block(op_sdiv_32_T0_T1_code, 15); + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_smul_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_smul_32_T0_T1 +{ + static const uint8 op_smul_32_T0_T1_code[] = { + 0x45, 0x0f, 0xaf, 0xe5 + }; + copy_block(op_smul_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_udiv_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_udiv_32_T0_T1 +{ + static const uint8 op_udiv_32_T0_T1_code[] = { + 0x44, 0x89, 0xe0, 0x31, 0xd2, 0x41, 0xf7, 0xf5, 0x41, 0x89, 0xc4 + }; + copy_block(op_udiv_32_T0_T1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_umul_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_umul_32_T0_T1 +{ + static const uint8 op_umul_32_T0_T1_code[] = { + 0x45, 0x0f, 0xaf, 0xe5 + }; + copy_block(op_umul_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_xchg_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_xchg_32_T0_T1 +{ + static const uint8 op_xchg_32_T0_T1_code[] = { + 0x45, 0x87, 0xe5 + }; + copy_block(op_xchg_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_s8_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s8_T0_T1_0 +{ + static const uint8 op_load_s8_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x0f, 0xbe, 0x20 + }; + copy_block(op_load_s8_T0_T1_0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_u8_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u8_T0_T1_0 +{ + static const uint8 op_load_u8_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x44, 0x0f, 0xb6, 0x20, + }; + copy_block(op_load_u8_T0_T1_0_code, 43); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(43); +} +#endif + +DEFINE_GEN(gen_op_store_8_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_8_T0_T1_0 +{ + static const uint8 op_store_8_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x44, 0x88, 0x20, + }; + copy_block(op_store_8_T0_T1_0_code, 42); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(42); +} +#endif + +DEFINE_GEN(gen_op_load_s16_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s16_T0_T1_0 +{ + static const uint8 op_load_s16_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x0f, 0xb7, 0x00, + 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xbf, 0xe0 + }; + copy_block(op_load_s16_T0_T1_0_code, 50); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(50); +} +#endif + +DEFINE_GEN(gen_op_load_s32_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s32_T0_T1_0 +{ + static const uint8 op_load_s32_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x8b, 0x00, + 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc + }; + copy_block(op_load_s32_T0_T1_0_code, 47); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(47); +} +#endif + +DEFINE_GEN(gen_op_load_s8_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s8_T0_T1_T2 +{ + static const uint8 op_load_s8_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, 0x44, 0x0f, 0xbe, 0x20 + }; + copy_block(op_load_s8_T0_T1_T2_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_load_s8_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s8_T0_T1_im +{ + static const uint8 op_load_s8_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x0f, + 0xbe, 0x24, 0x02 + }; + copy_block(op_load_s8_T0_T1_im_code, 15); + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_load_u16_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u16_T0_T1_0 +{ + static const uint8 op_load_u16_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x0f, 0xb7, 0x00, + 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xb7, 0xe0 + }; + copy_block(op_load_u16_T0_T1_0_code, 50); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(50); +} +#endif + +DEFINE_GEN(gen_op_load_u32_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u32_T0_T1_0 +{ + static const uint8 op_load_u32_T0_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x8b, 0x00, + 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc + }; + copy_block(op_load_u32_T0_T1_0_code, 47); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(47); +} +#endif + +DEFINE_GEN(gen_op_load_u8_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u8_T0_T1_T2 +{ + static const uint8 op_load_u8_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x44, 0x0f, 0xb6, 0x20, + }; + copy_block(op_load_u8_T0_T1_T2_code, 44); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(44); +} +#endif + +DEFINE_GEN(gen_op_load_u8_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u8_T0_T1_im +{ + static const uint8 op_load_u8_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x44, 0x0f, 0xb6, 0x20, + }; + copy_block(op_load_u8_T0_T1_im_code, 52); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(52); +} +#endif + +DEFINE_GEN(gen_op_store_16_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_16_T0_T1_0 +{ + static const uint8 op_store_16_T0_T1_0_code[] = { + 0x44, 0x89, 0xea, 0x44, 0x89, 0xe0, 0x66, 0xc1, 0xc0, 0x08, + TRANS_RDX, + 0x66, 0x89, 0x02, + }; + copy_block(op_store_16_T0_T1_0_code, 54); + *(uint32_t *)(code_ptr() + 38) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 47) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(54); +} +#endif + +DEFINE_GEN(gen_op_store_32_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_32_T0_T1_0 +{ + static const uint8 op_store_32_T0_T1_0_code[] = { + 0x44, 0x89, 0xe2, 0x0f, 0xca, 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x89, 0x10, + }; + copy_block(op_store_32_T0_T1_0_code, 46); + *(uint32_t *)(code_ptr() + 32) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 40) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(46); +} +#endif + +DEFINE_GEN(gen_op_store_8_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_8_T0_T1_T2 +{ + static const uint8 op_store_8_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x44, 0x88, 0x20, + }; + copy_block(op_store_8_T0_T1_T2_code, 43); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(43); +} +#endif + +DEFINE_GEN(gen_op_store_8_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_8_T0_T1_im +{ + static const uint8 op_store_8_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x44, 0x88, 0x20, + }; + copy_block(op_store_8_T0_T1_im_code, 51); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_load_s16_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s16_T0_T1_T2 +{ + static const uint8 op_load_s16_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x0f, 0xb7, 0x00, + 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xbf, 0xe0 + }; + copy_block(op_load_s16_T0_T1_T2_code, 51); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_load_s16_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s16_T0_T1_im +{ + static const uint8 op_load_s16_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x0f, 0xb7, 0x00, + 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xbf, 0xe0 + }; + copy_block(op_load_s16_T0_T1_im_code, 59); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(59); +} +#endif + +DEFINE_GEN(gen_op_load_s32_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s32_T0_T1_T2 +{ + static const uint8 op_load_s32_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x8b, 0x00, + 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc + }; + copy_block(op_load_s32_T0_T1_T2_code, 48); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_load_s32_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s32_T0_T1_im +{ + static const uint8 op_load_s32_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x8b, 0x00, + 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc + }; + copy_block(op_load_s32_T0_T1_im_code, 56); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(56); +} +#endif + +DEFINE_GEN(gen_op_load_u16_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u16_T0_T1_T2 +{ + static const uint8 op_load_u16_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x0f, 0xb7, 0x00, + 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xb7, 0xe0 + }; + copy_block(op_load_u16_T0_T1_T2_code, 51); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_load_u16_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u16_T0_T1_im +{ + static const uint8 op_load_u16_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x0f, 0xb7, 0x00, + 0x66, 0xc1, 0xc0, 0x08, 0x44, 0x0f, 0xb7, 0xe0 + }; + copy_block(op_load_u16_T0_T1_im_code, 59); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(59); +} +#endif + +DEFINE_GEN(gen_op_load_u32_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u32_T0_T1_T2 +{ + static const uint8 op_load_u32_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x8b, 0x00, + 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc + }; + copy_block(op_load_u32_T0_T1_T2_code, 48); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_load_u32_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u32_T0_T1_im +{ + static const uint8 op_load_u32_T0_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x8b, 0x00, + 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc + }; + copy_block(op_load_u32_T0_T1_im_code, 56); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(56); +} +#endif + +DEFINE_GEN(gen_op_store_16_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_16_T0_T1_T2 +{ + static const uint8 op_store_16_T0_T1_T2_code[] = { + 0x43, 0x8d, 0x14, 0x2e, 0x44, 0x89, 0xe0, 0x66, 0xc1, 0xc0, 0x08, + TRANS_RDX, + 0x66, 0x89, 0x02, + }; + copy_block(op_store_16_T0_T1_T2_code, 55); + *(uint32_t *)(code_ptr() + 39) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 48) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(55); +} +#endif + +DEFINE_GEN(gen_op_store_16_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_16_T0_T1_im +{ + static const uint8 op_store_16_T0_T1_im_code[] = { + 0x44, 0x89, 0xe9, 0x44, 0x89, 0xe2, 0x66, 0xc1, 0xc2, 0x08, 0x48, 0x8d, + 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RCX, + TRANS_RAX, + 0x66, 0x89, 0x10, + }; + copy_block(op_store_16_T0_T1_im_code, 58); + *(uint32_t *)(code_ptr() + 43) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 51) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 13) = (int32_t)((long)param1 - (long)(code_ptr() + 13 + 4)) + 0; + inc_code_ptr(58); +} +#endif + +DEFINE_GEN(gen_op_store_32_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_32_T0_T1_T2 +{ + static const uint8 op_store_32_T0_T1_T2_code[] = { + 0x44, 0x89, 0xf2, 0x44, 0x89, 0xe1, 0x0f, 0xc9, 0x44, 0x01, 0xea, + TRANS_RDX, + 0x89, 0x0a, + }; + copy_block(op_store_32_T0_T1_T2_code, 54); + *(uint32_t *)(code_ptr() + 39) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 48) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(54); +} +#endif + +DEFINE_GEN(gen_op_store_32_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_32_T0_T1_im +{ + static const uint8 op_store_32_T0_T1_im_code[] = { + 0x44, 0x89, 0xe1, 0x0f, 0xc9, 0x44, 0x89, 0xe8, 0x48, 0x8d, 0x15, 0x00, + 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x89, 0x08, + }; + copy_block(op_store_32_T0_T1_im_code, 55); + *(uint32_t *)(code_ptr() + 41) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 49) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 11) = (int32_t)((long)param1 - (long)(code_ptr() + 11 + 4)) + 0; + inc_code_ptr(55); +} +#endif + +DEFINE_GEN(gen_op_jmp_A0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jmp_A0 +{ + static const uint8 op_jmp_A0_code[] = { + 0x41, 0xff, 0xe4 + }; + copy_block(op_jmp_A0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_CST(op_exec_return_offset,0x32L) + +DEFINE_GEN(gen_op_execute,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_execute +{ + static const uint8 op_execute_code[] = { + 0x53, 0x48, 0x81, 0xec, 0xa0, 0x00, 0x00, 0x00, 0x48, 0x89, 0xfb, 0x48, + 0x89, 0xac, 0x24, 0x98, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xa4, 0x24, 0x90, + 0x00, 0x00, 0x00, 0x4c, 0x89, 0xac, 0x24, 0x88, 0x00, 0x00, 0x00, 0x4c, + 0x89, 0xb4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x89, 0xf5, 0xff, 0xe7, + 0xff, 0xd3, 0x48, 0x8b, 0x84, 0x24, 0x80, 0x00, 0x00, 0x00, 0x49, 0x89, + 0xc6, 0x48, 0x8b, 0x84, 0x24, 0x88, 0x00, 0x00, 0x00, 0x49, 0x89, 0xc5, + 0x48, 0x8b, 0x84, 0x24, 0x90, 0x00, 0x00, 0x00, 0x49, 0x89, 0xc4, 0x48, + 0x8b, 0x84, 0x24, 0x98, 0x00, 0x00, 0x00, 0x48, 0x89, 0xc5, 0x48, 0x81, + 0xc4, 0xa0, 0x00, 0x00, 0x00, 0x5b, 0xc3 + }; + copy_block(op_execute_code, 103); + inc_code_ptr(103); +} +#endif + +#undef DEFINE_CST +#undef DEFINE_GEN diff --git a/SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops.hpp b/SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops.hpp index 20fc4ff26..7738d341b 100644 --- a/SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops.hpp +++ b/SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops.hpp @@ -1,5 +1,9 @@ #if defined(__x86_64__) +#ifdef __APPLE__ + #include "basic-dyngen-ops-x86_64_macos.hpp" +#else #include "basic-dyngen-ops-x86_64.hpp" +#endif #elif defined(__i386__) #include "basic-dyngen-ops-x86_32.hpp" #else diff --git a/SheepShaver/src/Unix/dyngen_precompiled/patch_jit.pl b/SheepShaver/src/Unix/dyngen_precompiled/patch_jit.pl new file mode 100755 index 000000000..47b8b3507 --- /dev/null +++ b/SheepShaver/src/Unix/dyngen_precompiled/patch_jit.pl @@ -0,0 +1,166 @@ +#! /usr/bin/perl + +open(S, "basic-dyngen-ops-x86_64.hpp") || die; +open(O, "> basic-dyngen-ops-x86_64_macos.hpp") || die; +select O; +&patch; +close S; +close O; +open(S, "ppc-dyngen-ops-x86_64.hpp") || die; +open(O, "> ppc-dyngen-ops-x86_64_macos.hpp") || die; +select O; +&patch; +close S; +close O; +exit 0; + +sub patch { +print << "EOM"; +#define ADD_RAX_RCX 0x01,0xc8 +#define ADD_RDX_RCX 0x01,0xca +#define ADD_RAX_RDX 0x01,0xd0 +#define TRANS_RAX \\ + 0x48,0x3D,0x00,0x30,0x00,0x00,\\ + 0x72,0x16,\\ + 0x48,0x3D,0x00,0xE0,0xFF,0x5F,\\ + 0x72,0x14,\\ + 0x48,0x25,0xFF,0x1F,0x00,0x00,\\ + 0x48,0x05,0x00,0x00,0x00,0x00,\\ + 0xEB,0x06,\\ + 0x48,0x05,0x00,0x00,0x00,0x00 + +#define TRANS_RDX \\ + 0x48,0x81,0xFA,0x00,0x30,0x00,0x00,\\ + 0x72,0x19,\\ + 0x48,0x81,0xFA,0x00,0xE0,0xFF,0x5F,\\ + 0x72,0x17,\\ + 0x48,0x81,0xE2,0xFF,0x1F,0x00,0x00,\\ + 0x48,0x81,0xC2,0x00,0x00,0x00,0x00,\\ + 0xEB,0x07,\\ + 0x48,0x81,0xC2,0x00,0x00,0x00,0x00 + +#ifdef DYNGEN_IMPL +extern uint8 gZeroPage[0x3000], gKernelData[0x2000]; +#endif + +EOM +@keys = ("8b0402", "890c10", "891401", "890a", "8910", "882402", "8b00", + "8902", "0fb620", "8820", "0fb700", "0fb62402", "0fb70402", "890411"); +@keys_add_rax_rdx = ("8b0402", "890c10", "882402", "0fb62402", "0fb70402"); +@keys_trans_rdx = ("890a", "8902", "890411"); +$keys_add{"891401"} = "ADD_RAX_RCX"; +$keys_add{"890411"} = "ADD_RDX_RCX"; + +$keys{$_} = 1 while $_ = shift @keys; +$keys_add{$_} = "ADD_RAX_RDX" while $_ = shift @keys_add_rax_rdx; +$keys_trans_rdx{$_} = 1 while $_ = shift @keys_trans_rdx; +while () { + if (/static const uint8 (.+)\[/) { + print; + $name = $1; + $valid = $name =~ /load|store/; + } + elsif ($valid) { + if (/0x/) { + s/\s//g; + s/0x//g; + @code = (@code, split(",", $_)); + } + elsif (/};/) { + $n = 0; + $once = 0; + @ofs_k = (); + @ofs_z = (); + while (1) { + $found = -1; + $prefix = 0; + for ($i = 0; $i < @code - 1; $i++) { + $key = $code[$i] . $code[$i + 1]; + if ($keys{$key}) { + $found = $i; + $once = 1; + last; + } + $key .= $code[$i + 2]; + if ($keys{$key}) { + $found = $i; + $once = 1; + last; + } + $key .= $code[$i + 3]; + if ($keys{$key}) { + $found = $i; + $once = 1; + last; + } + } + if ($i > 0 && $code[$i - 1] =~ /44|48|66/) { + $prefix = 1; + $found--; + } + last if $found < 0; + $n += $found; + print " "; + for ($i = 0; $i < $found; $i++) { + printf "0x%s", shift @code; + print @code ? $i % 12 == 11 ? ",\n " : ", " : "\n };\n"; + } + if ($keys_add{$key}) { + $n += 2; + printf "\n %s,", $keys_add{$key}; + } + $trans_rdx = $keys_trans_rdx{$key}; + push @ofs_k, $n + ($trans_rdx ? 0x1c : 0x18); + push @ofs_z, $n + ($trans_rdx ? 0x25 : 0x20); + $n += $trans_rdx ? 0x29 : 0x24; + printf "\n TRANS_%s,\n ", $trans_rdx ? "RDX" : "RAX"; + if ($prefix) { + $n++; + printf "0x%02s, ", shift @code; + } + if ($keys_add{$key}) { + $n += 2; + if (length($key) == 8) { + $n++; + printf "0x%02s, ", shift @code; + } + printf "0x%02s, ", shift @code; + printf "0x%02x,\n", hex(shift @code) - ($keys_add{$key} =~ /RAX/ ? 4 : 2); + shift @code; + } + else { + for ($i = 0; $i < length($key); $i += 2) { + $n++; + printf "0x%s, ", shift @code; + } + print "\n"; + } + } + $valid = $once; + if (@code) { + $n += @code; + print " "; + for ($i = 0; @code; $i++) { + printf "0x%s", shift @code; + printf "%s", @code ==0 ? "\n" : $i % 12 == 11 ? ",\n " : ", "; + } + } + print " };\n"; + } + elsif (/copy_block/) { + printf " copy_block(%s, %d);\n", $name, $n; + printf " *(uint32_t *)(code_ptr() + %d) = (uint32_t)(uintptr)gKernelData;\n", shift @ofs_k while @ofs_k; + printf " *(uint32_t *)(code_ptr() + %d) = (uint32_t)(uintptr)gZeroPage;\n", shift @ofs_z while @ofs_z; + } + elsif (/inc_code_ptr/) { + printf " inc_code_ptr(%d);\n", $n; + } + else { + print; + } + } + else { + print; + } +} +} diff --git a/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_64_macos.hpp b/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_64_macos.hpp new file mode 100644 index 000000000..8aaea1c03 --- /dev/null +++ b/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_64_macos.hpp @@ -0,0 +1,11221 @@ +#define ADD_RAX_RCX 0x01,0xc8 +#define ADD_RDX_RCX 0x01,0xca +#define ADD_RAX_RDX 0x01,0xd0 +#define TRANS_RAX \ + 0x48,0x3D,0x00,0x30,0x00,0x00,\ + 0x72,0x16,\ + 0x48,0x3D,0x00,0xE0,0xFF,0x5F,\ + 0x72,0x14,\ + 0x48,0x25,0xFF,0x1F,0x00,0x00,\ + 0x48,0x05,0x00,0x00,0x00,0x00,\ + 0xEB,0x06,\ + 0x48,0x05,0x00,0x00,0x00,0x00 + +#define TRANS_RDX \ + 0x48,0x81,0xFA,0x00,0x30,0x00,0x00,\ + 0x72,0x19,\ + 0x48,0x81,0xFA,0x00,0xE0,0xFF,0x5F,\ + 0x72,0x17,\ + 0x48,0x81,0xE2,0xFF,0x1F,0x00,0x00,\ + 0x48,0x81,0xC2,0x00,0x00,0x00,0x00,\ + 0xEB,0x07,\ + 0x48,0x81,0xC2,0x00,0x00,0x00,0x00 + +#ifdef DYNGEN_IMPL +extern uint8 gZeroPage[0x3000], gKernelData[0x2000]; +#endif + +#ifndef DEFINE_CST +#define DEFINE_CST(NAME, VALUE) +#endif +DEFINE_GEN(gen_op_dcbz_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_dcbz_T0 +{ + static const uint8 op_dcbz_T0_code[] = { + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0xe0, 0x41, 0x89, 0xc4, 0x89, 0xc0, 0x48, + 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xc7, 0x40, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xc7, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x48, 0xc7, + 0x40, 0x18, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_dcbz_T0_code, 42); + inc_code_ptr(42); +} +#endif + +DEFINE_GEN(gen_op_mmx_vor,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vor +{ + static const uint8 op_mmx_vor_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xeb, 0x45, 0x00, 0x41, 0x0f, 0xeb, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vor_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_nego_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_nego_T0 +{ + static const uint8 op_nego_T0_code[] = { + 0x31, 0xd2, 0x41, 0x81, 0xfc, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x94, 0xc2, + 0x48, 0x8d, 0x45, 0x10, 0x88, 0x90, 0x85, 0x03, 0x00, 0x00, 0x08, 0x90, + 0x84, 0x03, 0x00, 0x00, 0x41, 0xf7, 0xdc + }; + copy_block(op_nego_T0_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_addme_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addme_T0 +{ + static const uint8 op_addme_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x41, + 0x83, 0xd4, 0xff, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_addme_T0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_addze_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addze_T0 +{ + static const uint8 op_addze_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x41, + 0x83, 0xd4, 0x00, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_addze_T0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_mmx_vand,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vand +{ + static const uint8 op_mmx_vand_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xdb, 0x45, 0x00, 0x41, 0x0f, 0xdb, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vand_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vxor,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vxor +{ + static const uint8 op_mmx_vxor_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xef, 0x45, 0x00, 0x41, 0x0f, 0xef, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vxor_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_addmeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addmeo_T0 +{ + static const uint8 op_addmeo_T0_code[] = { + 0x48, 0x89, 0xe8, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, + 0xe2, 0x00, 0x41, 0x83, 0xd4, 0xff, 0x0f, 0x92, 0xc2, 0x0f, 0x90, 0xc1, + 0x88, 0x95, 0x96, 0x03, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x10, 0x88, 0x88, + 0x85, 0x03, 0x00, 0x00, 0x08, 0x88, 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_addmeo_T0_code, 46); + inc_code_ptr(46); +} +#endif + +DEFINE_GEN(gen_op_addzeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addzeo_T0 +{ + static const uint8 op_addzeo_T0_code[] = { + 0x48, 0x89, 0xe8, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, + 0xe2, 0x00, 0x41, 0x83, 0xd4, 0x00, 0x0f, 0x92, 0xc2, 0x0f, 0x90, 0xc1, + 0x88, 0x95, 0x96, 0x03, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x10, 0x88, 0x88, + 0x85, 0x03, 0x00, 0x00, 0x08, 0x88, 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_addzeo_T0_code, 46); + inc_code_ptr(46); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_26 +{ + static const uint8 op_lmw_T0_26_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x45, + 0x78, 0x8d, 0x42, 0x04, 0x41, 0x89, 0xc4, 0x89, 0xc0, 0x8b, 0x00, 0x0f, + 0xc8, 0x89, 0x45, 0x7c, 0x8d, 0x42, 0x08, 0x41, 0x89, 0xc4, 0x89, 0xc0, + 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, 0x80, 0x00, 0x00, 0x00, 0x8d, 0x42, + 0x0c, 0x41, 0x89, 0xc4, 0x89, 0xc0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, + 0x84, 0x00, 0x00, 0x00, 0x8d, 0x42, 0x10, 0x41, 0x89, 0xc4, 0x89, 0xc0, + 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, 0x88, 0x00, 0x00, 0x00, 0x83, 0xc2, + 0x14, 0x41, 0x89, 0xd4, 0x89, 0xd2, 0x8b, 0x02, 0x0f, 0xc8, 0x89, 0x85, + 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_26_code, 100); + inc_code_ptr(100); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_27 +{ + static const uint8 op_lmw_T0_27_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x45, + 0x7c, 0x8d, 0x42, 0x04, 0x41, 0x89, 0xc4, 0x89, 0xc0, 0x8b, 0x00, 0x0f, + 0xc8, 0x89, 0x85, 0x80, 0x00, 0x00, 0x00, 0x8d, 0x42, 0x08, 0x41, 0x89, + 0xc4, 0x89, 0xc0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, 0x84, 0x00, 0x00, + 0x00, 0x8d, 0x42, 0x0c, 0x41, 0x89, 0xc4, 0x89, 0xc0, 0x8b, 0x00, 0x0f, + 0xc8, 0x89, 0x85, 0x88, 0x00, 0x00, 0x00, 0x83, 0xc2, 0x10, 0x41, 0x89, + 0xd4, 0x89, 0xd2, 0x8b, 0x02, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, + 0x00 + }; + copy_block(op_lmw_T0_27_code, 85); + inc_code_ptr(85); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_28 +{ + static const uint8 op_lmw_T0_28_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, + 0x80, 0x00, 0x00, 0x00, 0x8d, 0x42, 0x04, 0x41, 0x89, 0xc4, 0x89, 0xc0, + 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, 0x84, 0x00, 0x00, 0x00, 0x8d, 0x42, + 0x08, 0x41, 0x89, 0xc4, 0x89, 0xc0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, + 0x88, 0x00, 0x00, 0x00, 0x83, 0xc2, 0x0c, 0x41, 0x89, 0xd4, 0x89, 0xd2, + 0x8b, 0x02, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_28_code, 70); + inc_code_ptr(70); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_29 +{ + static const uint8 op_lmw_T0_29_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, + 0x84, 0x00, 0x00, 0x00, 0x8d, 0x42, 0x04, 0x41, 0x89, 0xc4, 0x89, 0xc0, + 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, 0x88, 0x00, 0x00, 0x00, 0x83, 0xc2, + 0x08, 0x41, 0x89, 0xd4, 0x89, 0xd2, 0x8b, 0x02, 0x0f, 0xc8, 0x89, 0x85, + 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_29_code, 52); + inc_code_ptr(52); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_30 +{ + static const uint8 op_lmw_T0_30_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, + 0x88, 0x00, 0x00, 0x00, 0x83, 0xc2, 0x04, 0x41, 0x89, 0xd4, 0x89, 0xd2, + 0x8b, 0x02, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_30_code, 34); + inc_code_ptr(34); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_31 +{ + static const uint8 op_lmw_T0_31_code[] = { + 0x44, 0x89, 0xe0, 0x8b, 0x00, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, + 0x00 + }; + copy_block(op_lmw_T0_31_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_im +{ + static const uint8 op_lmw_T0_im_code[] = { + 0x8d, 0x35, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, 0xe1, 0x48, 0x8d, 0x7d, + 0x10, 0xeb, 0x11, 0x89, 0xc8, 0x8b, 0x00, 0x0f, 0xc8, 0x48, 0x63, 0xd6, + 0x89, 0x04, 0x97, 0xff, 0xc6, 0x83, 0xc1, 0x04, 0x83, 0xfe, 0x1f, 0x76, + 0xea + }; + copy_block(op_lmw_T0_im_code, 37); + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param1 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(37); +} +#endif + +DEFINE_GEN(gen_op_mfvscr_VD,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mfvscr_VD +{ + static const uint8 op_mfvscr_VD_code[] = { + 0x41, 0xc7, 0x07, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc7, 0x47, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x41, 0xc7, 0x47, 0x08, 0x00, 0x00, 0x00, 0x00, 0x8b, + 0x85, 0x98, 0x03, 0x00, 0x00, 0x41, 0x89, 0x47, 0x0c + }; + copy_block(op_mfvscr_VD_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_mmx_vandc,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vandc +{ + static const uint8 op_mmx_vandc_code[] = { + 0x41, 0x0f, 0x6f, 0x45, 0x00, 0x41, 0x0f, 0x6f, 0x4d, 0x08, 0x41, 0x0f, + 0xdf, 0x04, 0x24, 0x41, 0x0f, 0xdf, 0x4c, 0x24, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vandc_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mtvscr_V0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mtvscr_V0 +{ + static const uint8 op_mtvscr_V0_code[] = { + 0x41, 0x8b, 0x44, 0x24, 0x0c, 0x89, 0x85, 0x98, 0x03, 0x00, 0x00 + }; + copy_block(op_mtvscr_V0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_set_PC_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_set_PC_T0 +{ + static const uint8 op_set_PC_T0_code[] = { + 0x44, 0x89, 0xa5, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_set_PC_T0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_set_PC_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_set_PC_im +{ + static const uint8 op_set_PC_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x89, 0x85, 0xac, 0x03, 0x00, + 0x00 + }; + copy_block(op_set_PC_im_code, 13); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_slw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_slw_T0_T1 +{ + static const uint8 op_slw_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xe4, 0x31, 0xc0, 0x83, 0xe1, 0x20, 0x41, + 0x0f, 0x44, 0xc4, 0x41, 0x89, 0xc4 + }; + copy_block(op_slw_T0_T1_code, 18); + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_srw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_srw_T0_T1 +{ + static const uint8 op_srw_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x41, 0xd3, 0xec, 0x31, 0xc0, 0x83, 0xe1, 0x20, 0x41, + 0x0f, 0x44, 0xc4, 0x41, 0x89, 0xc4 + }; + copy_block(op_srw_T0_T1_code, 18); + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_subfme_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfme_T0 +{ + static const uint8 op_subfme_T0_code[] = { + 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0xb8, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0xba, 0xe2, 0x00, 0xf5, 0x44, 0x19, 0xe0, 0xf5, 0x0f, 0x92, 0xc2, + 0x41, 0x89, 0xc4, 0x88, 0x95, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_subfme_T0_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_subfze_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfze_T0 +{ + static const uint8 op_subfze_T0_code[] = { + 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x31, 0xc0, 0x0f, 0xba, 0xe2, + 0x00, 0xf5, 0x44, 0x19, 0xe0, 0xf5, 0x0f, 0x92, 0xc2, 0x41, 0x89, 0xc4, + 0x88, 0x95, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_subfze_T0_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_addc_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addc_T0_T1 +{ + static const uint8 op_addc_T0_T1_code[] = { + 0x45, 0x01, 0xec, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_addc_T0_T1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_addc_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addc_T0_im +{ + static const uint8 op_addc_T0_im_code[] = { + 0x44, 0x89, 0xe2, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x04, + 0x02, 0x41, 0x39, 0xc4, 0x0f, 0x97, 0x85, 0x96, 0x03, 0x00, 0x00, 0x41, + 0x89, 0xc4 + }; + copy_block(op_addc_T0_im_code, 26); + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_adde_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_adde_T0_T1 +{ + static const uint8 op_adde_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x45, + 0x11, 0xec, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_adde_T0_T1_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_addo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addo_T0_T1 +{ + static const uint8 op_addo_T0_T1_code[] = { + 0x45, 0x01, 0xec, 0x0f, 0x90, 0xc2, 0x48, 0x8d, 0x45, 0x10, 0x88, 0x90, + 0x85, 0x03, 0x00, 0x00, 0x08, 0x90, 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_addo_T0_T1_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_divw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divw_T0_T1 +{ + static const uint8 op_divw_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x89, 0xe2, 0x45, 0x85, 0xed, 0x74, 0x0f, 0x41, + 0x81, 0xfc, 0x00, 0x00, 0x00, 0x80, 0x75, 0x0d, 0x41, 0x83, 0xfd, 0xff, + 0x75, 0x07, 0x89, 0xd0, 0xc1, 0xf8, 0x1f, 0xeb, 0x09, 0x89, 0xc1, 0x89, + 0xd0, 0xc1, 0xfa, 0x1f, 0xf7, 0xf9, 0x41, 0x89, 0xc4 + }; + copy_block(op_divw_T0_T1_code, 45); + inc_code_ptr(45); +} +#endif + +DEFINE_GEN(gen_op_fabs_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fabs_FD_F0 +{ + static const uint8 op_fabs_FD_F0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0xba, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x48, 0x21, 0xd0, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fabs_FD_F0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_fmov_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F0_F1 +{ + static const uint8 op_fmov_F0_F1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x49, 0x89, 0x04, 0x24 + }; + copy_block(op_fmov_F0_F1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_fmov_F0_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F0_F2 +{ + static const uint8 op_fmov_F0_F2_code[] = { + 0x49, 0x8b, 0x06, 0x49, 0x89, 0x04, 0x24 + }; + copy_block(op_fmov_F0_F2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_fmov_F1_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F1_F0 +{ + static const uint8 op_fmov_F1_F0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x49, 0x89, 0x45, 0x00 + }; + copy_block(op_fmov_F1_F0_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_fmov_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F1_F2 +{ + static const uint8 op_fmov_F1_F2_code[] = { + 0x49, 0x8b, 0x06, 0x49, 0x89, 0x45, 0x00 + }; + copy_block(op_fmov_F1_F2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_fmov_F2_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F2_F0 +{ + static const uint8 op_fmov_F2_F0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x49, 0x89, 0x06 + }; + copy_block(op_fmov_F2_F0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_fmov_F2_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F2_F1 +{ + static const uint8 op_fmov_F2_F1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x49, 0x89, 0x06 + }; + copy_block(op_fmov_F2_F1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_fmov_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_FD_F0 +{ + static const uint8 op_fmov_FD_F0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmov_FD_F0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_fmov_FD_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_FD_F1 +{ + static const uint8 op_fmov_FD_F1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmov_FD_F1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_fmov_FD_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_FD_F2 +{ + static const uint8 op_fmov_FD_F2_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmov_FD_F2_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fneg_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fneg_FD_F0 +{ + static const uint8 op_fneg_FD_F0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x48, 0x31, 0xc8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fneg_FD_F0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_inc_32_mem,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_inc_32_mem +{ + static const uint8 op_inc_32_mem_code[] = { + 0xff, 0x05, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_inc_32_mem_code, 6); + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param1 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_CR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_CR +{ + static const uint8 op_load_T0_CR_code[] = { + 0x44, 0x8b, 0xa5, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_CR_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_LR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_LR +{ + static const uint8 op_load_T0_LR_code[] = { + 0x44, 0x8b, 0xa5, 0xa4, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_LR_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_PC,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_PC +{ + static const uint8 op_load_T0_PC_code[] = { + 0x44, 0x8b, 0xa5, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_PC_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_mmx_vmaxsh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vmaxsh +{ + static const uint8 op_mmx_vmaxsh_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xee, 0x45, 0x00, 0x41, 0x0f, 0xee, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vmaxsh_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vmaxub,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vmaxub +{ + static const uint8 op_mmx_vmaxub_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xde, 0x45, 0x00, 0x41, 0x0f, 0xde, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vmaxub_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vminsh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vminsh +{ + static const uint8 op_mmx_vminsh_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xea, 0x45, 0x00, 0x41, 0x0f, 0xea, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vminsh_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vminub,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vminub +{ + static const uint8 op_mmx_vminub_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xda, 0x45, 0x00, 0x41, 0x0f, 0xda, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vminub_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_record_cr1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_record_cr1 +{ + static const uint8 op_record_cr1_code[] = { + 0x8b, 0x95, 0xa0, 0x03, 0x00, 0x00, 0xc1, 0xea, 0x04, 0x81, 0xe2, 0x00, + 0x00, 0x00, 0x0f, 0x8b, 0x8d, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe1, 0xff, + 0xff, 0xff, 0xf0, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_record_cr1_code, 35); + inc_code_ptr(35); +} +#endif + +DEFINE_GEN(gen_op_sraw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sraw_T0_T1 +{ + static const uint8 op_sraw_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x89, 0xe9, 0x83, 0xe1, 0x3f, 0x41, 0x89, 0xcd, + 0xa8, 0x20, 0x74, 0x14, 0x44, 0x89, 0xe0, 0xc1, 0xe8, 0x1f, 0x88, 0x85, + 0x96, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0xf7, 0xdc, 0xeb, 0x25, + 0x44, 0x89, 0xe2, 0x31, 0xc0, 0x45, 0x85, 0xe4, 0x79, 0x0f, 0xb8, 0xff, + 0xff, 0xff, 0xff, 0xd3, 0xe0, 0xf7, 0xd0, 0x41, 0x85, 0xc4, 0x0f, 0x95, + 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x41, 0x89, 0xd4, 0x41, 0xd3, + 0xfc + }; + copy_block(op_sraw_T0_T1_code, 73); + inc_code_ptr(73); +} +#endif + +DEFINE_GEN(gen_op_sraw_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sraw_T0_im +{ + static const uint8 op_sraw_T0_im_code[] = { + 0x44, 0x89, 0xe2, 0x8d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x45, + 0x85, 0xe4, 0x79, 0x0f, 0xb8, 0xff, 0xff, 0xff, 0xff, 0xd3, 0xe0, 0xf7, + 0xd0, 0x41, 0x85, 0xc4, 0x0f, 0x95, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, + 0x00, 0x41, 0x89, 0xd4, 0x41, 0xd3, 0xfc + }; + copy_block(op_sraw_T0_im_code, 43); + *(uint32_t *)(code_ptr() + 5) = (int32_t)((long)param1 - (long)(code_ptr() + 5 + 4)) + 0; + inc_code_ptr(43); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_26 +{ + static const uint8 op_stmw_T0_26_code[] = { + 0x8b, 0x45, 0x78, 0x0f, 0xc8, 0x44, 0x89, 0xe2, 0x89, 0x02, 0x41, 0x8d, + 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x45, 0x7c, 0x0f, 0xc8, 0x89, + 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, + 0x85, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, + 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x84, 0x00, 0x00, + 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, + 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x88, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, + 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, + 0x85, 0x8c, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02 + }; + copy_block(op_stmw_T0_26_code, 107); + inc_code_ptr(107); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_27 +{ + static const uint8 op_stmw_T0_27_code[] = { + 0x8b, 0x45, 0x7c, 0x0f, 0xc8, 0x44, 0x89, 0xe2, 0x89, 0x02, 0x41, 0x8d, + 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x80, 0x00, 0x00, 0x00, + 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, + 0x89, 0xd4, 0x8b, 0x85, 0x84, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, + 0x89, 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, + 0x88, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, 0x8d, + 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, + 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02 + }; + copy_block(op_stmw_T0_27_code, 90); + inc_code_ptr(90); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_28 +{ + static const uint8 op_stmw_T0_28_code[] = { + 0x8b, 0x85, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x44, 0x89, 0xe2, 0x89, + 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x84, + 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, + 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x88, 0x00, 0x00, 0x00, 0x0f, + 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, + 0xd4, 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, + 0x02 + }; + copy_block(op_stmw_T0_28_code, 73); + inc_code_ptr(73); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_29 +{ + static const uint8 op_stmw_T0_29_code[] = { + 0x8b, 0x85, 0x84, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x44, 0x89, 0xe2, 0x89, + 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x88, + 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02, 0x41, 0x8d, 0x54, + 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x0f, + 0xc8, 0x89, 0xd2, 0x89, 0x02 + }; + copy_block(op_stmw_T0_29_code, 53); + inc_code_ptr(53); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_30 +{ + static const uint8 op_stmw_T0_30_code[] = { + 0x8b, 0x85, 0x88, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x44, 0x89, 0xe2, 0x89, + 0x02, 0x41, 0x8d, 0x54, 0x24, 0x04, 0x41, 0x89, 0xd4, 0x8b, 0x85, 0x8c, + 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0xd2, 0x89, 0x02 + }; + copy_block(op_stmw_T0_30_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_31 +{ + static const uint8 op_stmw_T0_31_code[] = { + 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x44, 0x89, 0xe2, 0x89, + 0x02 + }; + copy_block(op_stmw_T0_31_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_im +{ + static const uint8 op_stmw_T0_im_code[] = { + 0x8d, 0x35, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, 0xe1, 0xeb, 0x12, 0x48, + 0x63, 0xc6, 0x8b, 0x44, 0x85, 0x10, 0x0f, 0xc8, 0x89, 0xca, 0x89, 0x02, + 0xff, 0xc6, 0x83, 0xc1, 0x04, 0x83, 0xfe, 0x1f, 0x76, 0xe9 + }; + copy_block(op_stmw_T0_im_code, 34); + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param1 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(34); +} +#endif + +DEFINE_GEN(gen_op_subf_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subf_T0_T1 +{ + static const uint8 op_subf_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x29, 0xe0, 0x41, 0x89, 0xc4 + }; + copy_block(op_subf_T0_T1_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_subfmeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfmeo_T0 +{ + static const uint8 op_subfmeo_T0_code[] = { + 0x53, 0x48, 0x89, 0xe9, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0xb8, + 0xff, 0xff, 0xff, 0xff, 0x89, 0xc3, 0x0f, 0xba, 0xe2, 0x00, 0xf5, 0x44, + 0x19, 0xe3, 0xf5, 0x0f, 0x92, 0xc2, 0x0f, 0x90, 0xc0, 0x41, 0x89, 0xdc, + 0x88, 0x95, 0x96, 0x03, 0x00, 0x00, 0x48, 0x83, 0xc1, 0x10, 0x88, 0x81, + 0x85, 0x03, 0x00, 0x00, 0x08, 0x81, 0x84, 0x03, 0x00, 0x00, 0x5b + }; + copy_block(op_subfmeo_T0_code, 59); + inc_code_ptr(59); +} +#endif + +DEFINE_GEN(gen_op_subfzeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfzeo_T0 +{ + static const uint8 op_subfzeo_T0_code[] = { + 0x53, 0x48, 0x89, 0xe9, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x31, + 0xc0, 0x89, 0xc3, 0x0f, 0xba, 0xe2, 0x00, 0xf5, 0x44, 0x19, 0xe3, 0xf5, + 0x0f, 0x92, 0xc2, 0x0f, 0x90, 0xc0, 0x41, 0x89, 0xdc, 0x88, 0x95, 0x96, + 0x03, 0x00, 0x00, 0x48, 0x83, 0xc1, 0x10, 0x88, 0x81, 0x85, 0x03, 0x00, + 0x00, 0x08, 0x81, 0x84, 0x03, 0x00, 0x00, 0x5b + }; + copy_block(op_subfzeo_T0_code, 56); + inc_code_ptr(56); +} +#endif + +DEFINE_GEN(gen_op_addco_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addco_T0_T1 +{ + static const uint8 op_addco_T0_T1_code[] = { + 0x45, 0x01, 0xec, 0x0f, 0x92, 0xc2, 0x0f, 0x90, 0xc1, 0x48, 0x89, 0xe8, + 0x88, 0x95, 0x96, 0x03, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x10, 0x88, 0x88, + 0x85, 0x03, 0x00, 0x00, 0x08, 0x88, 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_addco_T0_T1_code, 34); + inc_code_ptr(34); +} +#endif + +DEFINE_GEN(gen_op_addeo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addeo_T0_T1 +{ + static const uint8 op_addeo_T0_T1_code[] = { + 0x48, 0x89, 0xe8, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, + 0xe2, 0x00, 0x45, 0x11, 0xec, 0x0f, 0x92, 0xc2, 0x0f, 0x90, 0xc1, 0x88, + 0x95, 0x96, 0x03, 0x00, 0x00, 0x48, 0x83, 0xc0, 0x10, 0x88, 0x88, 0x85, + 0x03, 0x00, 0x00, 0x08, 0x88, 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_addeo_T0_T1_code, 45); + inc_code_ptr(45); +} +#endif + +DEFINE_GEN(gen_op_branch_1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_1_T0 +{ + static const uint8 op_branch_1_T0_code[] = { + 0x44, 0x89, 0xa5, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_1_T0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_branch_1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_1_im +{ + static const uint8 op_branch_1_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x89, 0x85, 0xac, 0x03, 0x00, + 0x00 + }; + copy_block(op_branch_1_im_code, 13); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_divwo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divwo_T0_T1 +{ + static const uint8 op_divwo_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x44, 0x89, 0xe2, 0x45, 0x85, 0xed, 0x74, 0x0f, 0x41, + 0x81, 0xfc, 0x00, 0x00, 0x00, 0x80, 0x75, 0x1f, 0x41, 0x83, 0xfd, 0xff, + 0x75, 0x19, 0x89, 0xd1, 0xc1, 0xf9, 0x1f, 0x48, 0x8d, 0x45, 0x10, 0xc6, + 0x80, 0x85, 0x03, 0x00, 0x00, 0x01, 0x80, 0x88, 0x84, 0x03, 0x00, 0x00, + 0x01, 0xeb, 0x10, 0x89, 0xd0, 0xc1, 0xfa, 0x1f, 0xf7, 0xf9, 0x89, 0xc1, + 0xc6, 0x85, 0x95, 0x03, 0x00, 0x00, 0x00, 0x41, 0x89, 0xcc + }; + copy_block(op_divwo_T0_T1_code, 70); + inc_code_ptr(70); +} +#endif + +DEFINE_GEN(gen_op_divwu_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divwu_T0_T1 +{ + static const uint8 op_divwu_T0_T1_code[] = { + 0x31, 0xc9, 0x45, 0x85, 0xed, 0x74, 0x0a, 0x44, 0x89, 0xe0, 0x31, 0xd2, + 0x41, 0xf7, 0xf5, 0x89, 0xc1, 0x41, 0x89, 0xcc + }; + copy_block(op_divwu_T0_T1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fnabs_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnabs_FD_F0 +{ + static const uint8 op_fnabs_FD_F0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x48, 0x21, 0xf8, 0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x48, 0x31, 0xf0, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, + 0x00 + }; + copy_block(op_fnabs_FD_F0_code, 37); + inc_code_ptr(37); +} +#endif + +DEFINE_GEN(gen_op_load_T0_CTR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_CTR +{ + static const uint8 op_load_T0_CTR_code[] = { + 0x44, 0x8b, 0xa5, 0xa8, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_CTR_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_XER,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_XER +{ + static const uint8 op_load_T0_XER_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x0f, 0xb6, 0x91, 0x84, 0x03, 0x00, 0x00, 0xc1, + 0xe2, 0x1f, 0x0f, 0xb6, 0x81, 0x85, 0x03, 0x00, 0x00, 0xc1, 0xe0, 0x1e, + 0x09, 0xc2, 0x0f, 0xb6, 0x81, 0x87, 0x03, 0x00, 0x00, 0x09, 0xc2, 0x0f, + 0xb6, 0x81, 0x86, 0x03, 0x00, 0x00, 0xc1, 0xe0, 0x1d, 0x41, 0x89, 0xd4, + 0x41, 0x09, 0xc4 + }; + copy_block(op_load_T0_XER_code, 51); + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr0 +{ + static const uint8 op_load_T0_cr0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0xc1, 0xec, + 0x1c + }; + copy_block(op_load_T0_cr0_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr1 +{ + static const uint8 op_load_T0_cr1_code[] = { + 0x0f, 0xb6, 0x85, 0x93, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0x83, + 0xe4, 0x0f + }; + copy_block(op_load_T0_cr1_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr2 +{ + static const uint8 op_load_T0_cr2_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x14, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x0f + }; + copy_block(op_load_T0_cr2_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr3 +{ + static const uint8 op_load_T0_cr3_code[] = { + 0x0f, 0xb7, 0x85, 0x92, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0x83, + 0xe4, 0x0f + }; + copy_block(op_load_T0_cr3_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr4 +{ + static const uint8 op_load_T0_cr4_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0c, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x0f + }; + copy_block(op_load_T0_cr4_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr5 +{ + static const uint8 op_load_T0_cr5_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x08, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x0f + }; + copy_block(op_load_T0_cr5_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr6 +{ + static const uint8 op_load_T0_cr6_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x04, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x0f + }; + copy_block(op_load_T0_cr6_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr7 +{ + static const uint8 op_load_T0_cr7_code[] = { + 0x44, 0x8b, 0xa5, 0x90, 0x03, 0x00, 0x00, 0x41, 0x83, 0xe4, 0x0f + }; + copy_block(op_load_T0_cr7_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_lwarx_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lwarx_T0_T1 +{ + static const uint8 op_lwarx_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x8b, 0x00, 0x41, 0x89, 0xc4, 0x41, 0x0f, 0xcc, 0x48, + 0x89, 0xe8, 0xc7, 0x85, 0xb8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x44, 0x89, 0xa8, 0xbc, 0x03, 0x00, 0x00 + }; + copy_block(op_lwarx_T0_T1_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_mmx_vaddubm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vaddubm +{ + static const uint8 op_mmx_vaddubm_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xfc, 0x45, 0x00, 0x41, 0x0f, 0xfc, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vaddubm_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vadduhm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vadduhm +{ + static const uint8 op_mmx_vadduhm_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xfd, 0x45, 0x00, 0x41, 0x0f, 0xfd, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vadduhm_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vadduwm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vadduwm +{ + static const uint8 op_mmx_vadduwm_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xfe, 0x45, 0x00, 0x41, 0x0f, 0xfe, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vadduwm_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vsububm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vsububm +{ + static const uint8 op_mmx_vsububm_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xf8, 0x45, 0x00, 0x41, 0x0f, 0xf8, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vsububm_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vsubuhm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vsubuhm +{ + static const uint8 op_mmx_vsubuhm_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xf9, 0x45, 0x00, 0x41, 0x0f, 0xf9, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vsubuhm_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vsubuwm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vsubuwm +{ + static const uint8 op_mmx_vsubuwm_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0xfa, 0x45, 0x00, 0x41, 0x0f, 0xfa, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vsubuwm_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mtcrf_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mtcrf_T0_im +{ + static const uint8 op_mtcrf_T0_im_code[] = { + 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x89, 0xc2, 0xf7, 0xd2, 0x23, 0x95, + 0x90, 0x03, 0x00, 0x00, 0x44, 0x21, 0xe0, 0x09, 0xc2, 0x89, 0x95, 0x90, + 0x03, 0x00, 0x00 + }; + copy_block(op_mtcrf_T0_im_code, 27); + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param1 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mulhw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mulhw_T0_T1 +{ + static const uint8 op_mulhw_T0_T1_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe8, 0xf7, 0xea, 0x41, 0x89, 0xd4 + }; + copy_block(op_mulhw_T0_T1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_mulli_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mulli_T0_im +{ + static const uint8 op_mulli_T0_im_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x44, 0x0f, 0xaf, 0xe0 + }; + copy_block(op_mulli_T0_im_code, 11); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_rlwnm_T0_T1,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rlwnm_T0_T1 +{ + static const uint8 op_rlwnm_T0_T1_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe9, 0xd3, 0xc2, 0x48, 0x8d, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x89, 0xd4, 0x41, 0x21, 0xc4 + }; + copy_block(op_rlwnm_T0_T1_code, 21); + *(uint32_t *)(code_ptr() + 11) = (int32_t)((long)param1 - (long)(code_ptr() + 11 + 4)) + 0; + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_store_T0_CR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_CR +{ + static const uint8 op_store_T0_CR_code[] = { + 0x44, 0x89, 0xa5, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_CR_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_LR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_LR +{ + static const uint8 op_store_T0_LR_code[] = { + 0x44, 0x89, 0xa5, 0xa4, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_LR_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_PC,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_PC +{ + static const uint8 op_store_T0_PC_code[] = { + 0x44, 0x89, 0xa5, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_PC_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_im_LR,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_im_LR +{ + static const uint8 op_store_im_LR_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x89, 0x85, 0xa4, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_im_LR_code, 13); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_stwcx_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stwcx_T0_T1 +{ + static const uint8 op_stwcx_T0_T1_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x25, 0xff, 0xff, 0xff, 0x0f, 0x0f, + 0xb6, 0x8d, 0x94, 0x03, 0x00, 0x00, 0xc1, 0xe1, 0x1c, 0x09, 0xc1, 0x44, + 0x8b, 0x85, 0xb8, 0x03, 0x00, 0x00, 0x45, 0x85, 0xc0, 0x74, 0x24, 0xc7, + 0x85, 0xb8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x85, 0xbc, + 0x03, 0x00, 0x00, 0x44, 0x39, 0xe8, 0x75, 0x0f, 0x44, 0x89, 0xe2, 0x0f, + 0xca, 0x89, 0xc0, 0x89, 0x10, 0x81, 0xc9, 0x00, 0x00, 0x00, 0x20, 0x89, + 0x8d, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_stwcx_T0_T1_code, 77); + inc_code_ptr(77); +} +#endif + +DEFINE_GEN(gen_op_subfc_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfc_T0_T1 +{ + static const uint8 op_subfc_T0_T1_code[] = { + 0x44, 0x89, 0xea, 0x44, 0x29, 0xe2, 0xf5, 0x0f, 0x92, 0xc0, 0x41, 0x89, + 0xd4, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_subfc_T0_T1_code, 19); + inc_code_ptr(19); +} +#endif + +DEFINE_GEN(gen_op_subfc_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfc_T0_im +{ + static const uint8 op_subfc_T0_im_code[] = { + 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x89, 0xc2, 0x44, 0x29, 0xe2, 0x39, + 0xd0, 0x0f, 0x93, 0x85, 0x96, 0x03, 0x00, 0x00, 0x41, 0x89, 0xd4 + }; + copy_block(op_subfc_T0_im_code, 23); + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param1 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_subfe_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfe_T0_T1 +{ + static const uint8 op_subfe_T0_T1_code[] = { + 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x44, 0x89, 0xe8, 0x0f, 0xba, + 0xe2, 0x00, 0xf5, 0x44, 0x19, 0xe0, 0xf5, 0x0f, 0x92, 0xc2, 0x41, 0x89, + 0xc4, 0x88, 0x95, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_subfe_T0_T1_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_subfo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfo_T0_T1 +{ + static const uint8 op_subfo_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x29, 0xe0, 0x0f, 0x90, 0xc2, 0x41, 0x89, 0xc4, + 0x48, 0x8d, 0x45, 0x10, 0x88, 0x90, 0x85, 0x03, 0x00, 0x00, 0x08, 0x90, + 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_subfo_T0_T1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_cntlzw_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_cntlzw_32_T0 +{ + static const uint8 op_cntlzw_32_T0_code[] = { + 0xb8, 0xff, 0xff, 0xff, 0xff, 0x41, 0x0f, 0xbd, 0xc4, 0xba, 0x1f, 0x00, + 0x00, 0x00, 0x41, 0x89, 0xd4, 0x41, 0x29, 0xc4 + }; + copy_block(op_cntlzw_32_T0_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_compare_T0_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_T0_0 +{ + static const uint8 op_compare_T0_0_code[] = { + 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0x41, 0x83, 0xfc, 0x00, 0x7d, + 0x09, 0x41, 0x89, 0xd4, 0x41, 0x83, 0xcc, 0x08, 0xeb, 0x12, 0x89, 0xd0, + 0x83, 0xc8, 0x04, 0x83, 0xca, 0x02, 0x45, 0x85, 0xe4, 0x41, 0x89, 0xc4, + 0x44, 0x0f, 0x44, 0xe2 + }; + copy_block(op_compare_T0_0_code, 40); + inc_code_ptr(40); +} +#endif + +DEFINE_GEN(gen_op_divwuo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divwuo_T0_T1 +{ + static const uint8 op_divwuo_T0_T1_code[] = { + 0x44, 0x89, 0xe9, 0x45, 0x85, 0xed, 0x75, 0x14, 0x48, 0x8d, 0x45, 0x10, + 0xc6, 0x80, 0x85, 0x03, 0x00, 0x00, 0x01, 0x80, 0x88, 0x84, 0x03, 0x00, + 0x00, 0x01, 0xeb, 0x11, 0x44, 0x89, 0xe0, 0x31, 0xd2, 0x41, 0xf7, 0xf5, + 0x89, 0xc1, 0xc6, 0x85, 0x95, 0x03, 0x00, 0x00, 0x00, 0x41, 0x89, 0xcc + }; + copy_block(op_divwuo_T0_T1_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_jump_next_A0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jump_next_A0 +{ + static const uint8 op_jump_next_A0_code[] = { + 0x4c, 0x89, 0xe0, 0x8b, 0x95, 0xac, 0x03, 0x00, 0x00, 0x49, 0x39, 0x14, + 0x24, 0x74, 0x1e, 0x48, 0x89, 0xd0, 0x48, 0xc1, 0xe8, 0x02, 0x25, 0xff, + 0x7f, 0x00, 0x00, 0x48, 0x8b, 0x84, 0xc5, 0x28, 0x08, 0x0c, 0x00, 0x48, + 0x85, 0xc0, 0x74, 0x08, 0x48, 0x3b, 0x10, 0x75, 0x03, 0xff, 0x60, 0x70 + }; + copy_block(op_jump_next_A0_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR0 +{ + static const uint8 op_load_F0_FPR0_code[] = { + 0x4c, 0x8d, 0xa5, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR1 +{ + static const uint8 op_load_F0_FPR1_code[] = { + 0x4c, 0x8d, 0xa5, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR2 +{ + static const uint8 op_load_F0_FPR2_code[] = { + 0x4c, 0x8d, 0xa5, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR3 +{ + static const uint8 op_load_F0_FPR3_code[] = { + 0x4c, 0x8d, 0xa5, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR4 +{ + static const uint8 op_load_F0_FPR4_code[] = { + 0x4c, 0x8d, 0xa5, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR5 +{ + static const uint8 op_load_F0_FPR5_code[] = { + 0x4c, 0x8d, 0xa5, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR6 +{ + static const uint8 op_load_F0_FPR6_code[] = { + 0x4c, 0x8d, 0xa5, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR7 +{ + static const uint8 op_load_F0_FPR7_code[] = { + 0x4c, 0x8d, 0xa5, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR8 +{ + static const uint8 op_load_F0_FPR8_code[] = { + 0x4c, 0x8d, 0xa5, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR9 +{ + static const uint8 op_load_F0_FPR9_code[] = { + 0x4c, 0x8d, 0xa5, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR0 +{ + static const uint8 op_load_F1_FPR0_code[] = { + 0x4c, 0x8d, 0xad, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR1 +{ + static const uint8 op_load_F1_FPR1_code[] = { + 0x4c, 0x8d, 0xad, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR2 +{ + static const uint8 op_load_F1_FPR2_code[] = { + 0x4c, 0x8d, 0xad, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR3 +{ + static const uint8 op_load_F1_FPR3_code[] = { + 0x4c, 0x8d, 0xad, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR4 +{ + static const uint8 op_load_F1_FPR4_code[] = { + 0x4c, 0x8d, 0xad, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR5 +{ + static const uint8 op_load_F1_FPR5_code[] = { + 0x4c, 0x8d, 0xad, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR6 +{ + static const uint8 op_load_F1_FPR6_code[] = { + 0x4c, 0x8d, 0xad, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR7 +{ + static const uint8 op_load_F1_FPR7_code[] = { + 0x4c, 0x8d, 0xad, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR8 +{ + static const uint8 op_load_F1_FPR8_code[] = { + 0x4c, 0x8d, 0xad, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR9 +{ + static const uint8 op_load_F1_FPR9_code[] = { + 0x4c, 0x8d, 0xad, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR0 +{ + static const uint8 op_load_F2_FPR0_code[] = { + 0x4c, 0x8d, 0xb5, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR1 +{ + static const uint8 op_load_F2_FPR1_code[] = { + 0x4c, 0x8d, 0xb5, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR2 +{ + static const uint8 op_load_F2_FPR2_code[] = { + 0x4c, 0x8d, 0xb5, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR3 +{ + static const uint8 op_load_F2_FPR3_code[] = { + 0x4c, 0x8d, 0xb5, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR4 +{ + static const uint8 op_load_F2_FPR4_code[] = { + 0x4c, 0x8d, 0xb5, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR5 +{ + static const uint8 op_load_F2_FPR5_code[] = { + 0x4c, 0x8d, 0xb5, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR6 +{ + static const uint8 op_load_F2_FPR6_code[] = { + 0x4c, 0x8d, 0xb5, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR7 +{ + static const uint8 op_load_F2_FPR7_code[] = { + 0x4c, 0x8d, 0xb5, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR8 +{ + static const uint8 op_load_F2_FPR8_code[] = { + 0x4c, 0x8d, 0xb5, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR9 +{ + static const uint8 op_load_F2_FPR9_code[] = { + 0x4c, 0x8d, 0xb5, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR0 +{ + static const uint8 op_load_T0_GPR0_code[] = { + 0x44, 0x8b, 0x65, 0x10 + }; + copy_block(op_load_T0_GPR0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR1 +{ + static const uint8 op_load_T0_GPR1_code[] = { + 0x44, 0x8b, 0x65, 0x14 + }; + copy_block(op_load_T0_GPR1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR2 +{ + static const uint8 op_load_T0_GPR2_code[] = { + 0x44, 0x8b, 0x65, 0x18 + }; + copy_block(op_load_T0_GPR2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR3 +{ + static const uint8 op_load_T0_GPR3_code[] = { + 0x44, 0x8b, 0x65, 0x1c + }; + copy_block(op_load_T0_GPR3_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR4 +{ + static const uint8 op_load_T0_GPR4_code[] = { + 0x44, 0x8b, 0x65, 0x20 + }; + copy_block(op_load_T0_GPR4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR5 +{ + static const uint8 op_load_T0_GPR5_code[] = { + 0x44, 0x8b, 0x65, 0x24 + }; + copy_block(op_load_T0_GPR5_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR6 +{ + static const uint8 op_load_T0_GPR6_code[] = { + 0x44, 0x8b, 0x65, 0x28 + }; + copy_block(op_load_T0_GPR6_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR7 +{ + static const uint8 op_load_T0_GPR7_code[] = { + 0x44, 0x8b, 0x65, 0x2c + }; + copy_block(op_load_T0_GPR7_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR8 +{ + static const uint8 op_load_T0_GPR8_code[] = { + 0x44, 0x8b, 0x65, 0x30 + }; + copy_block(op_load_T0_GPR8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR9 +{ + static const uint8 op_load_T0_GPR9_code[] = { + 0x44, 0x8b, 0x65, 0x34 + }; + copy_block(op_load_T0_GPR9_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb0 +{ + static const uint8 op_load_T0_crb0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0xc1, 0xec, + 0x1f + }; + copy_block(op_load_T0_crb0_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb1 +{ + static const uint8 op_load_T0_crb1_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1e, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb1_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb2 +{ + static const uint8 op_load_T0_crb2_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1d, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb2_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb3 +{ + static const uint8 op_load_T0_crb3_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1c, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb3_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb4 +{ + static const uint8 op_load_T0_crb4_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1b, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb4_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb5 +{ + static const uint8 op_load_T0_crb5_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1a, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb5_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb6 +{ + static const uint8 op_load_T0_crb6_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x19, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb6_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb7 +{ + static const uint8 op_load_T0_crb7_code[] = { + 0x0f, 0xb6, 0x85, 0x93, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0x83, + 0xe4, 0x01 + }; + copy_block(op_load_T0_crb7_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb8 +{ + static const uint8 op_load_T0_crb8_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x17, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb8_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb9 +{ + static const uint8 op_load_T0_crb9_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x16, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb9_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR0 +{ + static const uint8 op_load_T1_GPR0_code[] = { + 0x44, 0x8b, 0x6d, 0x10 + }; + copy_block(op_load_T1_GPR0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR1 +{ + static const uint8 op_load_T1_GPR1_code[] = { + 0x44, 0x8b, 0x6d, 0x14 + }; + copy_block(op_load_T1_GPR1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR2 +{ + static const uint8 op_load_T1_GPR2_code[] = { + 0x44, 0x8b, 0x6d, 0x18 + }; + copy_block(op_load_T1_GPR2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR3 +{ + static const uint8 op_load_T1_GPR3_code[] = { + 0x44, 0x8b, 0x6d, 0x1c + }; + copy_block(op_load_T1_GPR3_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR4 +{ + static const uint8 op_load_T1_GPR4_code[] = { + 0x44, 0x8b, 0x6d, 0x20 + }; + copy_block(op_load_T1_GPR4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR5 +{ + static const uint8 op_load_T1_GPR5_code[] = { + 0x44, 0x8b, 0x6d, 0x24 + }; + copy_block(op_load_T1_GPR5_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR6 +{ + static const uint8 op_load_T1_GPR6_code[] = { + 0x44, 0x8b, 0x6d, 0x28 + }; + copy_block(op_load_T1_GPR6_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR7 +{ + static const uint8 op_load_T1_GPR7_code[] = { + 0x44, 0x8b, 0x6d, 0x2c + }; + copy_block(op_load_T1_GPR7_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR8 +{ + static const uint8 op_load_T1_GPR8_code[] = { + 0x44, 0x8b, 0x6d, 0x30 + }; + copy_block(op_load_T1_GPR8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR9 +{ + static const uint8 op_load_T1_GPR9_code[] = { + 0x44, 0x8b, 0x6d, 0x34 + }; + copy_block(op_load_T1_GPR9_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb0 +{ + static const uint8 op_load_T1_crb0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc5, 0x41, 0xc1, 0xed, + 0x1f + }; + copy_block(op_load_T1_crb0_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb1 +{ + static const uint8 op_load_T1_crb1_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1e, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb1_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb2 +{ + static const uint8 op_load_T1_crb2_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1d, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb2_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb3 +{ + static const uint8 op_load_T1_crb3_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1c, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb3_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb4 +{ + static const uint8 op_load_T1_crb4_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1b, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb4_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb5 +{ + static const uint8 op_load_T1_crb5_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1a, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb5_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb6 +{ + static const uint8 op_load_T1_crb6_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x19, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb6_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb7 +{ + static const uint8 op_load_T1_crb7_code[] = { + 0x0f, 0xb6, 0x85, 0x93, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc5, 0x41, 0x83, + 0xe5, 0x01 + }; + copy_block(op_load_T1_crb7_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb8 +{ + static const uint8 op_load_T1_crb8_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x17, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb8_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb9 +{ + static const uint8 op_load_T1_crb9_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x16, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb9_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR0 +{ + static const uint8 op_load_T2_GPR0_code[] = { + 0x44, 0x8b, 0x75, 0x10 + }; + copy_block(op_load_T2_GPR0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR1 +{ + static const uint8 op_load_T2_GPR1_code[] = { + 0x44, 0x8b, 0x75, 0x14 + }; + copy_block(op_load_T2_GPR1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR2 +{ + static const uint8 op_load_T2_GPR2_code[] = { + 0x44, 0x8b, 0x75, 0x18 + }; + copy_block(op_load_T2_GPR2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR3 +{ + static const uint8 op_load_T2_GPR3_code[] = { + 0x44, 0x8b, 0x75, 0x1c + }; + copy_block(op_load_T2_GPR3_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR4 +{ + static const uint8 op_load_T2_GPR4_code[] = { + 0x44, 0x8b, 0x75, 0x20 + }; + copy_block(op_load_T2_GPR4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR5 +{ + static const uint8 op_load_T2_GPR5_code[] = { + 0x44, 0x8b, 0x75, 0x24 + }; + copy_block(op_load_T2_GPR5_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR6 +{ + static const uint8 op_load_T2_GPR6_code[] = { + 0x44, 0x8b, 0x75, 0x28 + }; + copy_block(op_load_T2_GPR6_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR7 +{ + static const uint8 op_load_T2_GPR7_code[] = { + 0x44, 0x8b, 0x75, 0x2c + }; + copy_block(op_load_T2_GPR7_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR8 +{ + static const uint8 op_load_T2_GPR8_code[] = { + 0x44, 0x8b, 0x75, 0x30 + }; + copy_block(op_load_T2_GPR8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR9 +{ + static const uint8 op_load_T2_GPR9_code[] = { + 0x44, 0x8b, 0x75, 0x34 + }; + copy_block(op_load_T2_GPR9_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpequb,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpequb +{ + static const uint8 op_mmx_vcmpequb_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0x74, 0x45, 0x00, 0x41, 0x0f, 0x74, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vcmpequb_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpequh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpequh +{ + static const uint8 op_mmx_vcmpequh_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0x75, 0x45, 0x00, 0x41, 0x0f, 0x75, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vcmpequh_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpequw,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpequw +{ + static const uint8 op_mmx_vcmpequw_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0x76, 0x45, 0x00, 0x41, 0x0f, 0x76, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vcmpequw_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpgtsb,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpgtsb +{ + static const uint8 op_mmx_vcmpgtsb_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0x64, 0x45, 0x00, 0x41, 0x0f, 0x64, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vcmpgtsb_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpgtsh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpgtsh +{ + static const uint8 op_mmx_vcmpgtsh_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0x65, 0x45, 0x00, 0x41, 0x0f, 0x65, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vcmpgtsh_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpgtsw,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpgtsw +{ + static const uint8 op_mmx_vcmpgtsw_code[] = { + 0x41, 0x0f, 0x6f, 0x04, 0x24, 0x41, 0x0f, 0x6f, 0x4c, 0x24, 0x08, 0x41, + 0x0f, 0x66, 0x45, 0x00, 0x41, 0x0f, 0x66, 0x4d, 0x08, 0x41, 0x0f, 0x7f, + 0x07, 0x41, 0x0f, 0x7f, 0x4f, 0x08 + }; + copy_block(op_mmx_vcmpgtsw_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_mulhwu_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mulhwu_T0_T1 +{ + static const uint8 op_mulhwu_T0_T1_code[] = { + 0x44, 0x89, 0xe2, 0x44, 0x89, 0xe8, 0xf7, 0xe2, 0x41, 0x89, 0xd4 + }; + copy_block(op_mulhwu_T0_T1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_mullwo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mullwo_T0_T1 +{ + static const uint8 op_mullwo_T0_T1_code[] = { + 0x49, 0x63, 0xcd, 0x49, 0x63, 0xc4, 0x48, 0x0f, 0xaf, 0xc8, 0x48, 0x63, + 0xc1, 0x31, 0xd2, 0x48, 0x39, 0xc8, 0x0f, 0x95, 0xc2, 0x48, 0x8d, 0x45, + 0x10, 0x88, 0x90, 0x85, 0x03, 0x00, 0x00, 0x08, 0x90, 0x84, 0x03, 0x00, + 0x00, 0x41, 0x89, 0xcc + }; + copy_block(op_mullwo_T0_T1_code, 40); + inc_code_ptr(40); +} +#endif + +DEFINE_GEN(gen_op_rlwimi_T0_T1,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rlwimi_T0_T1 +{ + static const uint8 op_rlwimi_T0_T1_code[] = { + 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x89, 0xd6, 0xf7, 0xd6, 0x44, 0x21, + 0xe6, 0x48, 0x8d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, 0xe8, 0xd3, + 0xc0, 0x21, 0xc2, 0x41, 0x89, 0xf4, 0x41, 0x09, 0xd4 + }; + copy_block(op_rlwimi_T0_T1_code, 33); + *(uint32_t *)(code_ptr() + 16) = (int32_t)((long)param1 - (long)(code_ptr() + 16 + 4)) + 0; + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param2 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_rlwinm_T0_T1,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rlwinm_T0_T1 +{ + static const uint8 op_rlwinm_T0_T1_code[] = { + 0x48, 0x8d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x44, 0x89, 0xe2, 0xd3, 0xc2, + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xd4, 0x41, 0x21, + 0xc4 + }; + copy_block(op_rlwinm_T0_T1_code, 25); + *(uint32_t *)(code_ptr() + 15) = (int32_t)((long)param2 - (long)(code_ptr() + 15 + 4)) + 0; + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_spcflags_set,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_set +{ + static const uint8 op_spcflags_set_code[] = { + 0x48, 0x8d, 0x8d, 0xb0, 0x03, 0x00, 0x00, 0x48, 0x8d, 0x95, 0xb4, 0x03, + 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x87, 0x02, 0x85, 0xc0, 0x75, + 0xf5, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0xc7, 0x41, + 0x04, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_spcflags_set_code, 41); + *(uint32_t *)(code_ptr() + 28) = (int32_t)((long)param1 - (long)(code_ptr() + 28 + 4)) + 0; + inc_code_ptr(41); +} +#endif + +DEFINE_GEN(gen_op_store_T0_CTR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_CTR +{ + static const uint8 op_store_T0_CTR_code[] = { + 0x44, 0x89, 0xa5, 0xa8, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_CTR_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_XER,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_XER +{ + static const uint8 op_store_T0_XER_code[] = { + 0x44, 0x89, 0xe2, 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe0, 0xc1, 0xe8, + 0x1f, 0x88, 0x81, 0x84, 0x03, 0x00, 0x00, 0x44, 0x89, 0xe0, 0xc1, 0xe8, + 0x1e, 0x83, 0xe0, 0x01, 0x88, 0x81, 0x85, 0x03, 0x00, 0x00, 0x44, 0x89, + 0xe0, 0xc1, 0xe8, 0x1d, 0x83, 0xe0, 0x01, 0x88, 0x81, 0x86, 0x03, 0x00, + 0x00, 0x83, 0xe2, 0x7f, 0x88, 0x91, 0x87, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_XER_code, 58); + inc_code_ptr(58); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr0 +{ + static const uint8 op_store_T0_cr0_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x1c, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x25, 0xff, 0xff, 0xff, 0x0f, 0x09, 0xd0, 0x89, + 0x81, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr0_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr1 +{ + static const uint8 op_store_T0_cr1_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x18, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x25, 0xff, 0xff, 0xff, 0xf0, 0x09, 0xd0, 0x89, + 0x81, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr1_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr2 +{ + static const uint8 op_store_T0_cr2_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x14, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x25, 0xff, 0xff, 0x0f, 0xff, 0x09, 0xd0, 0x89, + 0x81, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr2_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr3 +{ + static const uint8 op_store_T0_cr3_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x10, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x25, 0xff, 0xff, 0xf0, 0xff, 0x09, 0xd0, 0x89, + 0x81, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr3_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr4 +{ + static const uint8 op_store_T0_cr4_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x0c, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x80, 0xe4, 0x0f, 0x09, 0xd0, 0x89, 0x81, 0x80, + 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr4_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr5 +{ + static const uint8 op_store_T0_cr5_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x08, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x80, 0xe4, 0xf0, 0x09, 0xd0, 0x89, 0x81, 0x80, + 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr5_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr6 +{ + static const uint8 op_store_T0_cr6_code[] = { + 0x48, 0x8d, 0x4d, 0x10, 0x44, 0x89, 0xe2, 0xc1, 0xe2, 0x04, 0x8b, 0x81, + 0x80, 0x03, 0x00, 0x00, 0x24, 0x0f, 0x09, 0xd0, 0x89, 0x81, 0x80, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_cr6_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr7 +{ + static const uint8 op_store_T0_cr7_code[] = { + 0x48, 0x8d, 0x55, 0x10, 0x8b, 0x82, 0x80, 0x03, 0x00, 0x00, 0x83, 0xe0, + 0xf0, 0x44, 0x09, 0xe0, 0x89, 0x82, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr7_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_subfco_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfco_T0_T1 +{ + static const uint8 op_subfco_T0_T1_code[] = { + 0x44, 0x89, 0xe8, 0x44, 0x29, 0xe0, 0xf5, 0x0f, 0x92, 0xc2, 0x0f, 0x90, + 0xc1, 0x41, 0x89, 0xc4, 0x48, 0x89, 0xe8, 0x88, 0x95, 0x96, 0x03, 0x00, + 0x00, 0x48, 0x83, 0xc0, 0x10, 0x88, 0x88, 0x85, 0x03, 0x00, 0x00, 0x08, + 0x88, 0x84, 0x03, 0x00, 0x00 + }; + copy_block(op_subfco_T0_T1_code, 41); + inc_code_ptr(41); +} +#endif + +DEFINE_GEN(gen_op_subfeo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfeo_T0_T1 +{ + static const uint8 op_subfeo_T0_T1_code[] = { + 0x53, 0x48, 0x89, 0xe9, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, 0x44, + 0x89, 0xeb, 0x0f, 0xba, 0xe2, 0x00, 0xf5, 0x44, 0x19, 0xe3, 0xf5, 0x0f, + 0x92, 0xc2, 0x0f, 0x90, 0xc0, 0x41, 0x89, 0xdc, 0x88, 0x95, 0x96, 0x03, + 0x00, 0x00, 0x48, 0x83, 0xc1, 0x10, 0x88, 0x81, 0x85, 0x03, 0x00, 0x00, + 0x08, 0x81, 0x84, 0x03, 0x00, 0x00, 0x5b + }; + copy_block(op_subfeo_T0_T1_code, 55); + inc_code_ptr(55); +} +#endif + +DEFINE_GEN(gen_op_vor_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vor_VD_V0_V1 +{ + static const uint8 op_vor_VD_V0_V1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x49, 0x0b, 0x04, 0x24, 0x49, 0x89, 0x07, 0x49, + 0x8b, 0x45, 0x08, 0x49, 0x0b, 0x44, 0x24, 0x08, 0x49, 0x89, 0x47, 0x08 + }; + copy_block(op_vor_VD_V0_V1_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_compare_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_T0_T1 +{ + static const uint8 op_compare_T0_T1_code[] = { + 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0x45, 0x39, 0xec, 0x7d, 0x09, + 0x41, 0x89, 0xd4, 0x41, 0x83, 0xcc, 0x08, 0xeb, 0x12, 0x89, 0xd0, 0x83, + 0xc8, 0x04, 0x83, 0xca, 0x02, 0x45, 0x39, 0xec, 0x41, 0x89, 0xc4, 0x44, + 0x0f, 0x4e, 0xe2 + }; + copy_block(op_compare_T0_T1_code, 39); + inc_code_ptr(39); +} +#endif + +DEFINE_GEN(gen_op_compare_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_T0_im +{ + static const uint8 op_compare_T0_im_code[] = { + 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0x8d, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x39, 0xf4, 0x7d, 0x09, 0x41, 0x89, 0xd4, 0x41, 0x83, 0xcc, + 0x08, 0xeb, 0x12, 0x89, 0xd0, 0x83, 0xc8, 0x04, 0x83, 0xca, 0x02, 0x41, + 0x39, 0xf4, 0x41, 0x89, 0xc4, 0x44, 0x0f, 0x4e, 0xe2 + }; + copy_block(op_compare_T0_im_code, 45); + *(uint32_t *)(code_ptr() + 9) = (int32_t)((long)param1 - (long)(code_ptr() + 9 + 4)) + 0; + inc_code_ptr(45); +} +#endif + +DEFINE_GEN(gen_op_fadd_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fadd_FD_F0_F1 +{ + static const uint8 op_fadd_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x58, 0x45, 0x00, + 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fadd_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fdiv_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fdiv_FD_F0_F1 +{ + static const uint8 op_fdiv_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x5e, 0x45, 0x00, + 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fdiv_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fmul_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmul_FD_F0_F1 +{ + static const uint8 op_fmul_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmul_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fsub_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fsub_FD_F0_F1 +{ + static const uint8 op_fsub_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x5c, 0x45, 0x00, + 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fsub_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR10 +{ + static const uint8 op_load_F0_FPR10_code[] = { + 0x4c, 0x8d, 0xa5, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR11 +{ + static const uint8 op_load_F0_FPR11_code[] = { + 0x4c, 0x8d, 0xa5, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR12 +{ + static const uint8 op_load_F0_FPR12_code[] = { + 0x4c, 0x8d, 0xa5, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR13 +{ + static const uint8 op_load_F0_FPR13_code[] = { + 0x4c, 0x8d, 0xa5, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR14 +{ + static const uint8 op_load_F0_FPR14_code[] = { + 0x4c, 0x8d, 0xa5, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR15 +{ + static const uint8 op_load_F0_FPR15_code[] = { + 0x4c, 0x8d, 0xa5, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR16 +{ + static const uint8 op_load_F0_FPR16_code[] = { + 0x4c, 0x8d, 0xa5, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR17 +{ + static const uint8 op_load_F0_FPR17_code[] = { + 0x4c, 0x8d, 0xa5, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR18 +{ + static const uint8 op_load_F0_FPR18_code[] = { + 0x4c, 0x8d, 0xa5, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR19 +{ + static const uint8 op_load_F0_FPR19_code[] = { + 0x4c, 0x8d, 0xa5, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR20 +{ + static const uint8 op_load_F0_FPR20_code[] = { + 0x4c, 0x8d, 0xa5, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR21 +{ + static const uint8 op_load_F0_FPR21_code[] = { + 0x4c, 0x8d, 0xa5, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR22 +{ + static const uint8 op_load_F0_FPR22_code[] = { + 0x4c, 0x8d, 0xa5, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR23 +{ + static const uint8 op_load_F0_FPR23_code[] = { + 0x4c, 0x8d, 0xa5, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR24 +{ + static const uint8 op_load_F0_FPR24_code[] = { + 0x4c, 0x8d, 0xa5, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR25 +{ + static const uint8 op_load_F0_FPR25_code[] = { + 0x4c, 0x8d, 0xa5, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR26 +{ + static const uint8 op_load_F0_FPR26_code[] = { + 0x4c, 0x8d, 0xa5, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR27 +{ + static const uint8 op_load_F0_FPR27_code[] = { + 0x4c, 0x8d, 0xa5, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR28 +{ + static const uint8 op_load_F0_FPR28_code[] = { + 0x4c, 0x8d, 0xa5, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR29 +{ + static const uint8 op_load_F0_FPR29_code[] = { + 0x4c, 0x8d, 0xa5, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR30 +{ + static const uint8 op_load_F0_FPR30_code[] = { + 0x4c, 0x8d, 0xa5, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR31 +{ + static const uint8 op_load_F0_FPR31_code[] = { + 0x4c, 0x8d, 0xa5, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR10 +{ + static const uint8 op_load_F1_FPR10_code[] = { + 0x4c, 0x8d, 0xad, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR11 +{ + static const uint8 op_load_F1_FPR11_code[] = { + 0x4c, 0x8d, 0xad, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR12 +{ + static const uint8 op_load_F1_FPR12_code[] = { + 0x4c, 0x8d, 0xad, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR13 +{ + static const uint8 op_load_F1_FPR13_code[] = { + 0x4c, 0x8d, 0xad, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR14 +{ + static const uint8 op_load_F1_FPR14_code[] = { + 0x4c, 0x8d, 0xad, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR15 +{ + static const uint8 op_load_F1_FPR15_code[] = { + 0x4c, 0x8d, 0xad, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR16 +{ + static const uint8 op_load_F1_FPR16_code[] = { + 0x4c, 0x8d, 0xad, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR17 +{ + static const uint8 op_load_F1_FPR17_code[] = { + 0x4c, 0x8d, 0xad, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR18 +{ + static const uint8 op_load_F1_FPR18_code[] = { + 0x4c, 0x8d, 0xad, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR19 +{ + static const uint8 op_load_F1_FPR19_code[] = { + 0x4c, 0x8d, 0xad, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR20 +{ + static const uint8 op_load_F1_FPR20_code[] = { + 0x4c, 0x8d, 0xad, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR21 +{ + static const uint8 op_load_F1_FPR21_code[] = { + 0x4c, 0x8d, 0xad, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR22 +{ + static const uint8 op_load_F1_FPR22_code[] = { + 0x4c, 0x8d, 0xad, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR23 +{ + static const uint8 op_load_F1_FPR23_code[] = { + 0x4c, 0x8d, 0xad, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR24 +{ + static const uint8 op_load_F1_FPR24_code[] = { + 0x4c, 0x8d, 0xad, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR25 +{ + static const uint8 op_load_F1_FPR25_code[] = { + 0x4c, 0x8d, 0xad, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR26 +{ + static const uint8 op_load_F1_FPR26_code[] = { + 0x4c, 0x8d, 0xad, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR27 +{ + static const uint8 op_load_F1_FPR27_code[] = { + 0x4c, 0x8d, 0xad, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR28 +{ + static const uint8 op_load_F1_FPR28_code[] = { + 0x4c, 0x8d, 0xad, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR29 +{ + static const uint8 op_load_F1_FPR29_code[] = { + 0x4c, 0x8d, 0xad, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR30 +{ + static const uint8 op_load_F1_FPR30_code[] = { + 0x4c, 0x8d, 0xad, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR31 +{ + static const uint8 op_load_F1_FPR31_code[] = { + 0x4c, 0x8d, 0xad, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR10 +{ + static const uint8 op_load_F2_FPR10_code[] = { + 0x4c, 0x8d, 0xb5, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR11 +{ + static const uint8 op_load_F2_FPR11_code[] = { + 0x4c, 0x8d, 0xb5, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR12 +{ + static const uint8 op_load_F2_FPR12_code[] = { + 0x4c, 0x8d, 0xb5, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR13 +{ + static const uint8 op_load_F2_FPR13_code[] = { + 0x4c, 0x8d, 0xb5, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR14 +{ + static const uint8 op_load_F2_FPR14_code[] = { + 0x4c, 0x8d, 0xb5, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR15 +{ + static const uint8 op_load_F2_FPR15_code[] = { + 0x4c, 0x8d, 0xb5, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR16 +{ + static const uint8 op_load_F2_FPR16_code[] = { + 0x4c, 0x8d, 0xb5, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR17 +{ + static const uint8 op_load_F2_FPR17_code[] = { + 0x4c, 0x8d, 0xb5, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR18 +{ + static const uint8 op_load_F2_FPR18_code[] = { + 0x4c, 0x8d, 0xb5, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR19 +{ + static const uint8 op_load_F2_FPR19_code[] = { + 0x4c, 0x8d, 0xb5, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR20 +{ + static const uint8 op_load_F2_FPR20_code[] = { + 0x4c, 0x8d, 0xb5, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR21 +{ + static const uint8 op_load_F2_FPR21_code[] = { + 0x4c, 0x8d, 0xb5, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR22 +{ + static const uint8 op_load_F2_FPR22_code[] = { + 0x4c, 0x8d, 0xb5, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR23 +{ + static const uint8 op_load_F2_FPR23_code[] = { + 0x4c, 0x8d, 0xb5, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR24 +{ + static const uint8 op_load_F2_FPR24_code[] = { + 0x4c, 0x8d, 0xb5, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR25 +{ + static const uint8 op_load_F2_FPR25_code[] = { + 0x4c, 0x8d, 0xb5, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR26 +{ + static const uint8 op_load_F2_FPR26_code[] = { + 0x4c, 0x8d, 0xb5, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR27 +{ + static const uint8 op_load_F2_FPR27_code[] = { + 0x4c, 0x8d, 0xb5, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR28 +{ + static const uint8 op_load_F2_FPR28_code[] = { + 0x4c, 0x8d, 0xb5, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR29 +{ + static const uint8 op_load_F2_FPR29_code[] = { + 0x4c, 0x8d, 0xb5, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR30 +{ + static const uint8 op_load_F2_FPR30_code[] = { + 0x4c, 0x8d, 0xb5, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR31 +{ + static const uint8 op_load_F2_FPR31_code[] = { + 0x4c, 0x8d, 0xb5, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR10 +{ + static const uint8 op_load_T0_GPR10_code[] = { + 0x44, 0x8b, 0x65, 0x38 + }; + copy_block(op_load_T0_GPR10_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR11 +{ + static const uint8 op_load_T0_GPR11_code[] = { + 0x44, 0x8b, 0x65, 0x3c + }; + copy_block(op_load_T0_GPR11_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR12 +{ + static const uint8 op_load_T0_GPR12_code[] = { + 0x44, 0x8b, 0x65, 0x40 + }; + copy_block(op_load_T0_GPR12_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR13 +{ + static const uint8 op_load_T0_GPR13_code[] = { + 0x44, 0x8b, 0x65, 0x44 + }; + copy_block(op_load_T0_GPR13_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR14 +{ + static const uint8 op_load_T0_GPR14_code[] = { + 0x44, 0x8b, 0x65, 0x48 + }; + copy_block(op_load_T0_GPR14_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR15 +{ + static const uint8 op_load_T0_GPR15_code[] = { + 0x44, 0x8b, 0x65, 0x4c + }; + copy_block(op_load_T0_GPR15_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR16 +{ + static const uint8 op_load_T0_GPR16_code[] = { + 0x44, 0x8b, 0x65, 0x50 + }; + copy_block(op_load_T0_GPR16_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR17 +{ + static const uint8 op_load_T0_GPR17_code[] = { + 0x44, 0x8b, 0x65, 0x54 + }; + copy_block(op_load_T0_GPR17_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR18 +{ + static const uint8 op_load_T0_GPR18_code[] = { + 0x44, 0x8b, 0x65, 0x58 + }; + copy_block(op_load_T0_GPR18_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR19 +{ + static const uint8 op_load_T0_GPR19_code[] = { + 0x44, 0x8b, 0x65, 0x5c + }; + copy_block(op_load_T0_GPR19_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR20 +{ + static const uint8 op_load_T0_GPR20_code[] = { + 0x44, 0x8b, 0x65, 0x60 + }; + copy_block(op_load_T0_GPR20_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR21 +{ + static const uint8 op_load_T0_GPR21_code[] = { + 0x44, 0x8b, 0x65, 0x64 + }; + copy_block(op_load_T0_GPR21_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR22 +{ + static const uint8 op_load_T0_GPR22_code[] = { + 0x44, 0x8b, 0x65, 0x68 + }; + copy_block(op_load_T0_GPR22_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR23 +{ + static const uint8 op_load_T0_GPR23_code[] = { + 0x44, 0x8b, 0x65, 0x6c + }; + copy_block(op_load_T0_GPR23_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR24 +{ + static const uint8 op_load_T0_GPR24_code[] = { + 0x44, 0x8b, 0x65, 0x70 + }; + copy_block(op_load_T0_GPR24_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR25 +{ + static const uint8 op_load_T0_GPR25_code[] = { + 0x44, 0x8b, 0x65, 0x74 + }; + copy_block(op_load_T0_GPR25_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR26 +{ + static const uint8 op_load_T0_GPR26_code[] = { + 0x44, 0x8b, 0x65, 0x78 + }; + copy_block(op_load_T0_GPR26_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR27 +{ + static const uint8 op_load_T0_GPR27_code[] = { + 0x44, 0x8b, 0x65, 0x7c + }; + copy_block(op_load_T0_GPR27_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR28 +{ + static const uint8 op_load_T0_GPR28_code[] = { + 0x44, 0x8b, 0xa5, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR29 +{ + static const uint8 op_load_T0_GPR29_code[] = { + 0x44, 0x8b, 0xa5, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR30 +{ + static const uint8 op_load_T0_GPR30_code[] = { + 0x44, 0x8b, 0xa5, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR31 +{ + static const uint8 op_load_T0_GPR31_code[] = { + 0x44, 0x8b, 0xa5, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb10 +{ + static const uint8 op_load_T0_crb10_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x15, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb10_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb11 +{ + static const uint8 op_load_T0_crb11_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x14, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb11_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb12 +{ + static const uint8 op_load_T0_crb12_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x13, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb12_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb13 +{ + static const uint8 op_load_T0_crb13_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x12, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb13_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb14 +{ + static const uint8 op_load_T0_crb14_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x11, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb14_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb15 +{ + static const uint8 op_load_T0_crb15_code[] = { + 0x0f, 0xb7, 0x85, 0x92, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc4, 0x41, 0x83, + 0xe4, 0x01 + }; + copy_block(op_load_T0_crb15_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb16 +{ + static const uint8 op_load_T0_crb16_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0f, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb16_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb17 +{ + static const uint8 op_load_T0_crb17_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0e, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb17_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb18 +{ + static const uint8 op_load_T0_crb18_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0d, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb18_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb19 +{ + static const uint8 op_load_T0_crb19_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0c, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb19_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb20 +{ + static const uint8 op_load_T0_crb20_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0b, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb20_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb21 +{ + static const uint8 op_load_T0_crb21_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0a, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb21_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb22 +{ + static const uint8 op_load_T0_crb22_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x09, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb22_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb23 +{ + static const uint8 op_load_T0_crb23_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x08, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb23_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb24 +{ + static const uint8 op_load_T0_crb24_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x07, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb24_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb25 +{ + static const uint8 op_load_T0_crb25_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x06, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb25_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb26 +{ + static const uint8 op_load_T0_crb26_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x05, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb26_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb27 +{ + static const uint8 op_load_T0_crb27_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x04, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb27_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb28 +{ + static const uint8 op_load_T0_crb28_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x03, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb28_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb29 +{ + static const uint8 op_load_T0_crb29_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x02, 0x41, 0x89, 0xc4, + 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb29_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb30 +{ + static const uint8 op_load_T0_crb30_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xd1, 0xe8, 0x41, 0x89, 0xc4, 0x41, + 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb30_code, 15); + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb31 +{ + static const uint8 op_load_T0_crb31_code[] = { + 0x44, 0x8b, 0xa5, 0x90, 0x03, 0x00, 0x00, 0x41, 0x83, 0xe4, 0x01 + }; + copy_block(op_load_T0_crb31_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR10 +{ + static const uint8 op_load_T1_GPR10_code[] = { + 0x44, 0x8b, 0x6d, 0x38 + }; + copy_block(op_load_T1_GPR10_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR11 +{ + static const uint8 op_load_T1_GPR11_code[] = { + 0x44, 0x8b, 0x6d, 0x3c + }; + copy_block(op_load_T1_GPR11_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR12 +{ + static const uint8 op_load_T1_GPR12_code[] = { + 0x44, 0x8b, 0x6d, 0x40 + }; + copy_block(op_load_T1_GPR12_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR13 +{ + static const uint8 op_load_T1_GPR13_code[] = { + 0x44, 0x8b, 0x6d, 0x44 + }; + copy_block(op_load_T1_GPR13_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR14 +{ + static const uint8 op_load_T1_GPR14_code[] = { + 0x44, 0x8b, 0x6d, 0x48 + }; + copy_block(op_load_T1_GPR14_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR15 +{ + static const uint8 op_load_T1_GPR15_code[] = { + 0x44, 0x8b, 0x6d, 0x4c + }; + copy_block(op_load_T1_GPR15_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR16 +{ + static const uint8 op_load_T1_GPR16_code[] = { + 0x44, 0x8b, 0x6d, 0x50 + }; + copy_block(op_load_T1_GPR16_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR17 +{ + static const uint8 op_load_T1_GPR17_code[] = { + 0x44, 0x8b, 0x6d, 0x54 + }; + copy_block(op_load_T1_GPR17_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR18 +{ + static const uint8 op_load_T1_GPR18_code[] = { + 0x44, 0x8b, 0x6d, 0x58 + }; + copy_block(op_load_T1_GPR18_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR19 +{ + static const uint8 op_load_T1_GPR19_code[] = { + 0x44, 0x8b, 0x6d, 0x5c + }; + copy_block(op_load_T1_GPR19_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR20 +{ + static const uint8 op_load_T1_GPR20_code[] = { + 0x44, 0x8b, 0x6d, 0x60 + }; + copy_block(op_load_T1_GPR20_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR21 +{ + static const uint8 op_load_T1_GPR21_code[] = { + 0x44, 0x8b, 0x6d, 0x64 + }; + copy_block(op_load_T1_GPR21_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR22 +{ + static const uint8 op_load_T1_GPR22_code[] = { + 0x44, 0x8b, 0x6d, 0x68 + }; + copy_block(op_load_T1_GPR22_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR23 +{ + static const uint8 op_load_T1_GPR23_code[] = { + 0x44, 0x8b, 0x6d, 0x6c + }; + copy_block(op_load_T1_GPR23_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR24 +{ + static const uint8 op_load_T1_GPR24_code[] = { + 0x44, 0x8b, 0x6d, 0x70 + }; + copy_block(op_load_T1_GPR24_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR25 +{ + static const uint8 op_load_T1_GPR25_code[] = { + 0x44, 0x8b, 0x6d, 0x74 + }; + copy_block(op_load_T1_GPR25_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR26 +{ + static const uint8 op_load_T1_GPR26_code[] = { + 0x44, 0x8b, 0x6d, 0x78 + }; + copy_block(op_load_T1_GPR26_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR27 +{ + static const uint8 op_load_T1_GPR27_code[] = { + 0x44, 0x8b, 0x6d, 0x7c + }; + copy_block(op_load_T1_GPR27_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR28 +{ + static const uint8 op_load_T1_GPR28_code[] = { + 0x44, 0x8b, 0xad, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR29 +{ + static const uint8 op_load_T1_GPR29_code[] = { + 0x44, 0x8b, 0xad, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR30 +{ + static const uint8 op_load_T1_GPR30_code[] = { + 0x44, 0x8b, 0xad, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR31 +{ + static const uint8 op_load_T1_GPR31_code[] = { + 0x44, 0x8b, 0xad, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb10 +{ + static const uint8 op_load_T1_crb10_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x15, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb10_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb11 +{ + static const uint8 op_load_T1_crb11_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x14, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb11_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb12 +{ + static const uint8 op_load_T1_crb12_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x13, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb12_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb13 +{ + static const uint8 op_load_T1_crb13_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x12, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb13_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb14 +{ + static const uint8 op_load_T1_crb14_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x11, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb14_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb15 +{ + static const uint8 op_load_T1_crb15_code[] = { + 0x0f, 0xb7, 0x85, 0x92, 0x03, 0x00, 0x00, 0x41, 0x89, 0xc5, 0x41, 0x83, + 0xe5, 0x01 + }; + copy_block(op_load_T1_crb15_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb16 +{ + static const uint8 op_load_T1_crb16_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0f, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb16_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb17 +{ + static const uint8 op_load_T1_crb17_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0e, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb17_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb18 +{ + static const uint8 op_load_T1_crb18_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0d, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb18_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb19 +{ + static const uint8 op_load_T1_crb19_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0c, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb19_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb20 +{ + static const uint8 op_load_T1_crb20_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0b, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb20_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb21 +{ + static const uint8 op_load_T1_crb21_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0a, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb21_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb22 +{ + static const uint8 op_load_T1_crb22_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x09, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb22_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb23 +{ + static const uint8 op_load_T1_crb23_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x08, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb23_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb24 +{ + static const uint8 op_load_T1_crb24_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x07, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb24_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb25 +{ + static const uint8 op_load_T1_crb25_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x06, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb25_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb26 +{ + static const uint8 op_load_T1_crb26_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x05, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb26_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb27 +{ + static const uint8 op_load_T1_crb27_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x04, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb27_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb28 +{ + static const uint8 op_load_T1_crb28_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x03, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb28_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb29 +{ + static const uint8 op_load_T1_crb29_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x02, 0x41, 0x89, 0xc5, + 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb29_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb30 +{ + static const uint8 op_load_T1_crb30_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xd1, 0xe8, 0x41, 0x89, 0xc5, 0x41, + 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb30_code, 15); + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb31 +{ + static const uint8 op_load_T1_crb31_code[] = { + 0x44, 0x8b, 0xad, 0x90, 0x03, 0x00, 0x00, 0x41, 0x83, 0xe5, 0x01 + }; + copy_block(op_load_T1_crb31_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR10 +{ + static const uint8 op_load_T2_GPR10_code[] = { + 0x44, 0x8b, 0x75, 0x38 + }; + copy_block(op_load_T2_GPR10_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR11 +{ + static const uint8 op_load_T2_GPR11_code[] = { + 0x44, 0x8b, 0x75, 0x3c + }; + copy_block(op_load_T2_GPR11_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR12 +{ + static const uint8 op_load_T2_GPR12_code[] = { + 0x44, 0x8b, 0x75, 0x40 + }; + copy_block(op_load_T2_GPR12_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR13 +{ + static const uint8 op_load_T2_GPR13_code[] = { + 0x44, 0x8b, 0x75, 0x44 + }; + copy_block(op_load_T2_GPR13_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR14 +{ + static const uint8 op_load_T2_GPR14_code[] = { + 0x44, 0x8b, 0x75, 0x48 + }; + copy_block(op_load_T2_GPR14_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR15 +{ + static const uint8 op_load_T2_GPR15_code[] = { + 0x44, 0x8b, 0x75, 0x4c + }; + copy_block(op_load_T2_GPR15_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR16 +{ + static const uint8 op_load_T2_GPR16_code[] = { + 0x44, 0x8b, 0x75, 0x50 + }; + copy_block(op_load_T2_GPR16_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR17 +{ + static const uint8 op_load_T2_GPR17_code[] = { + 0x44, 0x8b, 0x75, 0x54 + }; + copy_block(op_load_T2_GPR17_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR18 +{ + static const uint8 op_load_T2_GPR18_code[] = { + 0x44, 0x8b, 0x75, 0x58 + }; + copy_block(op_load_T2_GPR18_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR19 +{ + static const uint8 op_load_T2_GPR19_code[] = { + 0x44, 0x8b, 0x75, 0x5c + }; + copy_block(op_load_T2_GPR19_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR20 +{ + static const uint8 op_load_T2_GPR20_code[] = { + 0x44, 0x8b, 0x75, 0x60 + }; + copy_block(op_load_T2_GPR20_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR21 +{ + static const uint8 op_load_T2_GPR21_code[] = { + 0x44, 0x8b, 0x75, 0x64 + }; + copy_block(op_load_T2_GPR21_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR22 +{ + static const uint8 op_load_T2_GPR22_code[] = { + 0x44, 0x8b, 0x75, 0x68 + }; + copy_block(op_load_T2_GPR22_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR23 +{ + static const uint8 op_load_T2_GPR23_code[] = { + 0x44, 0x8b, 0x75, 0x6c + }; + copy_block(op_load_T2_GPR23_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR24 +{ + static const uint8 op_load_T2_GPR24_code[] = { + 0x44, 0x8b, 0x75, 0x70 + }; + copy_block(op_load_T2_GPR24_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR25 +{ + static const uint8 op_load_T2_GPR25_code[] = { + 0x44, 0x8b, 0x75, 0x74 + }; + copy_block(op_load_T2_GPR25_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR26 +{ + static const uint8 op_load_T2_GPR26_code[] = { + 0x44, 0x8b, 0x75, 0x78 + }; + copy_block(op_load_T2_GPR26_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR27 +{ + static const uint8 op_load_T2_GPR27_code[] = { + 0x44, 0x8b, 0x75, 0x7c + }; + copy_block(op_load_T2_GPR27_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR28 +{ + static const uint8 op_load_T2_GPR28_code[] = { + 0x44, 0x8b, 0xb5, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR29 +{ + static const uint8 op_load_T2_GPR29_code[] = { + 0x44, 0x8b, 0xb5, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR30 +{ + static const uint8 op_load_T2_GPR30_code[] = { + 0x44, 0x8b, 0xb5, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR31 +{ + static const uint8 op_load_T2_GPR31_code[] = { + 0x44, 0x8b, 0xb5, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_record_cr0_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_record_cr0_T0 +{ + static const uint8 op_record_cr0_T0_code[] = { + 0x48, 0x89, 0xe9, 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x25, 0xff, 0xff, + 0xff, 0x0f, 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0xc1, 0xe2, 0x1c, + 0x09, 0xc2, 0x41, 0x83, 0xfc, 0x00, 0x7d, 0x09, 0x89, 0xd0, 0x0d, 0x00, + 0x00, 0x00, 0x80, 0xeb, 0x13, 0x89, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x40, + 0x81, 0xca, 0x00, 0x00, 0x00, 0x20, 0x45, 0x85, 0xe4, 0x0f, 0x44, 0xc2, + 0x89, 0x81, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_record_cr0_T0_code, 66); + inc_code_ptr(66); +} +#endif + +DEFINE_GEN(gen_op_record_cr6_VD,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_record_cr6_VD +{ + static const uint8 op_record_cr6_VD_code[] = { + 0x49, 0x8b, 0x37, 0x49, 0x8b, 0x57, 0x08, 0x48, 0x89, 0xd0, 0x48, 0x21, + 0xf0, 0xb9, 0x08, 0x00, 0x00, 0x00, 0x48, 0xff, 0xc0, 0x74, 0x0c, 0x48, + 0x09, 0xf2, 0x48, 0x83, 0xfa, 0x01, 0x19, 0xc9, 0x83, 0xe1, 0x02, 0x48, + 0x8d, 0x55, 0x10, 0xc1, 0xe1, 0x04, 0x8b, 0x82, 0x80, 0x03, 0x00, 0x00, + 0x24, 0x0f, 0x09, 0xc1, 0x89, 0x8a, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_record_cr6_VD_code, 58); + inc_code_ptr(58); +} +#endif + +DEFINE_GEN(gen_op_spcflags_init,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_init +{ + static const uint8 op_spcflags_init_code[] = { + 0x48, 0x8d, 0x8d, 0xb0, 0x03, 0x00, 0x00, 0x48, 0x8d, 0x95, 0xb4, 0x03, + 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x87, 0x02, 0x85, 0xc0, 0x75, + 0xf5, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0xc7, 0x41, + 0x04, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_spcflags_init_code, 41); + *(uint32_t *)(code_ptr() + 28) = (int32_t)((long)param1 - (long)(code_ptr() + 28 + 4)) + 0; + inc_code_ptr(41); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR0 +{ + static const uint8 op_store_F0_FPR0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR1 +{ + static const uint8 op_store_F0_FPR1_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR2 +{ + static const uint8 op_store_F0_FPR2_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR2_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR3 +{ + static const uint8 op_store_F0_FPR3_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR3_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR4 +{ + static const uint8 op_store_F0_FPR4_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR4_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR5 +{ + static const uint8 op_store_F0_FPR5_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR5_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR6 +{ + static const uint8 op_store_F0_FPR6_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR6_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR7 +{ + static const uint8 op_store_F0_FPR7_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR7_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR8 +{ + static const uint8 op_store_F0_FPR8_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR8_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR9 +{ + static const uint8 op_store_F0_FPR9_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR9_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR0 +{ + static const uint8 op_store_F1_FPR0_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR1 +{ + static const uint8 op_store_F1_FPR1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR2 +{ + static const uint8 op_store_F1_FPR2_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR2_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR3 +{ + static const uint8 op_store_F1_FPR3_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR3_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR4 +{ + static const uint8 op_store_F1_FPR4_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR4_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR5 +{ + static const uint8 op_store_F1_FPR5_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR5_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR6 +{ + static const uint8 op_store_F1_FPR6_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR6_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR7 +{ + static const uint8 op_store_F1_FPR7_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR7_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR8 +{ + static const uint8 op_store_F1_FPR8_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR8_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR9 +{ + static const uint8 op_store_F1_FPR9_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR9_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR0 +{ + static const uint8 op_store_F2_FPR0_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR1 +{ + static const uint8 op_store_F2_FPR1_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR2 +{ + static const uint8 op_store_F2_FPR2_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR2_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR3 +{ + static const uint8 op_store_F2_FPR3_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR3_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR4 +{ + static const uint8 op_store_F2_FPR4_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR4_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR5 +{ + static const uint8 op_store_F2_FPR5_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR5_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR6 +{ + static const uint8 op_store_F2_FPR6_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR6_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR7 +{ + static const uint8 op_store_F2_FPR7_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR7_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR8 +{ + static const uint8 op_store_F2_FPR8_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR8_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR9 +{ + static const uint8 op_store_F2_FPR9_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR9_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR0 +{ + static const uint8 op_store_FD_FPR0_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x90, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR0_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR1 +{ + static const uint8 op_store_FD_FPR1_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x98, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR1_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR2 +{ + static const uint8 op_store_FD_FPR2_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xa0, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR2_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR3 +{ + static const uint8 op_store_FD_FPR3_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xa8, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR3_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR4 +{ + static const uint8 op_store_FD_FPR4_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xb0, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR4_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR5 +{ + static const uint8 op_store_FD_FPR5_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xb8, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR5_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR6 +{ + static const uint8 op_store_FD_FPR6_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xc0, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR6_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR7 +{ + static const uint8 op_store_FD_FPR7_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xc8, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR7_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR8 +{ + static const uint8 op_store_FD_FPR8_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xd0, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR8_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR9 +{ + static const uint8 op_store_FD_FPR9_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xd8, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR9_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR0 +{ + static const uint8 op_store_T0_GPR0_code[] = { + 0x44, 0x89, 0x65, 0x10 + }; + copy_block(op_store_T0_GPR0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR1 +{ + static const uint8 op_store_T0_GPR1_code[] = { + 0x44, 0x89, 0x65, 0x14 + }; + copy_block(op_store_T0_GPR1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR2 +{ + static const uint8 op_store_T0_GPR2_code[] = { + 0x44, 0x89, 0x65, 0x18 + }; + copy_block(op_store_T0_GPR2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR3 +{ + static const uint8 op_store_T0_GPR3_code[] = { + 0x44, 0x89, 0x65, 0x1c + }; + copy_block(op_store_T0_GPR3_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR4 +{ + static const uint8 op_store_T0_GPR4_code[] = { + 0x44, 0x89, 0x65, 0x20 + }; + copy_block(op_store_T0_GPR4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR5 +{ + static const uint8 op_store_T0_GPR5_code[] = { + 0x44, 0x89, 0x65, 0x24 + }; + copy_block(op_store_T0_GPR5_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR6 +{ + static const uint8 op_store_T0_GPR6_code[] = { + 0x44, 0x89, 0x65, 0x28 + }; + copy_block(op_store_T0_GPR6_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR7 +{ + static const uint8 op_store_T0_GPR7_code[] = { + 0x44, 0x89, 0x65, 0x2c + }; + copy_block(op_store_T0_GPR7_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR8 +{ + static const uint8 op_store_T0_GPR8_code[] = { + 0x44, 0x89, 0x65, 0x30 + }; + copy_block(op_store_T0_GPR8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR9 +{ + static const uint8 op_store_T0_GPR9_code[] = { + 0x44, 0x89, 0x65, 0x34 + }; + copy_block(op_store_T0_GPR9_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb0 +{ + static const uint8 op_store_T0_crb0_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0x7f, + 0x44, 0x89, 0xe1, 0xc1, 0xe1, 0x1f, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb0_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb1 +{ + static const uint8 op_store_T0_crb1_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xbf, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1e, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb1_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb2 +{ + static const uint8 op_store_T0_crb2_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xdf, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1d, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb2_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb3 +{ + static const uint8 op_store_T0_crb3_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xef, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1c, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb3_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb4 +{ + static const uint8 op_store_T0_crb4_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xf7, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1b, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb4_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb5 +{ + static const uint8 op_store_T0_crb5_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfb, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1a, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb5_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb6 +{ + static const uint8 op_store_T0_crb6_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfd, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x19, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb6_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb7 +{ + static const uint8 op_store_T0_crb7_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfe, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x18, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb7_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb8 +{ + static const uint8 op_store_T0_crb8_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0x7f, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x17, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb8_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb9 +{ + static const uint8 op_store_T0_crb9_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xbf, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x16, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb9_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR0 +{ + static const uint8 op_store_T1_GPR0_code[] = { + 0x44, 0x89, 0x6d, 0x10 + }; + copy_block(op_store_T1_GPR0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR1 +{ + static const uint8 op_store_T1_GPR1_code[] = { + 0x44, 0x89, 0x6d, 0x14 + }; + copy_block(op_store_T1_GPR1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR2 +{ + static const uint8 op_store_T1_GPR2_code[] = { + 0x44, 0x89, 0x6d, 0x18 + }; + copy_block(op_store_T1_GPR2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR3 +{ + static const uint8 op_store_T1_GPR3_code[] = { + 0x44, 0x89, 0x6d, 0x1c + }; + copy_block(op_store_T1_GPR3_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR4 +{ + static const uint8 op_store_T1_GPR4_code[] = { + 0x44, 0x89, 0x6d, 0x20 + }; + copy_block(op_store_T1_GPR4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR5 +{ + static const uint8 op_store_T1_GPR5_code[] = { + 0x44, 0x89, 0x6d, 0x24 + }; + copy_block(op_store_T1_GPR5_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR6 +{ + static const uint8 op_store_T1_GPR6_code[] = { + 0x44, 0x89, 0x6d, 0x28 + }; + copy_block(op_store_T1_GPR6_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR7 +{ + static const uint8 op_store_T1_GPR7_code[] = { + 0x44, 0x89, 0x6d, 0x2c + }; + copy_block(op_store_T1_GPR7_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR8 +{ + static const uint8 op_store_T1_GPR8_code[] = { + 0x44, 0x89, 0x6d, 0x30 + }; + copy_block(op_store_T1_GPR8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR9 +{ + static const uint8 op_store_T1_GPR9_code[] = { + 0x44, 0x89, 0x6d, 0x34 + }; + copy_block(op_store_T1_GPR9_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb0 +{ + static const uint8 op_store_T1_crb0_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0x7f, + 0x44, 0x89, 0xe9, 0xc1, 0xe1, 0x1f, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb0_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb1 +{ + static const uint8 op_store_T1_crb1_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xbf, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1e, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb1_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb2 +{ + static const uint8 op_store_T1_crb2_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xdf, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1d, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb2_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb3 +{ + static const uint8 op_store_T1_crb3_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xef, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1c, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb3_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb4 +{ + static const uint8 op_store_T1_crb4_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xf7, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1b, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb4_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb5 +{ + static const uint8 op_store_T1_crb5_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfb, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x1a, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb5_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb6 +{ + static const uint8 op_store_T1_crb6_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfd, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x19, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb6_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb7 +{ + static const uint8 op_store_T1_crb7_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfe, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x18, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb7_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb8 +{ + static const uint8 op_store_T1_crb8_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0x7f, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x17, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb8_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb9 +{ + static const uint8 op_store_T1_crb9_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xbf, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x16, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb9_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR0 +{ + static const uint8 op_store_T2_GPR0_code[] = { + 0x44, 0x89, 0x75, 0x10 + }; + copy_block(op_store_T2_GPR0_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR1 +{ + static const uint8 op_store_T2_GPR1_code[] = { + 0x44, 0x89, 0x75, 0x14 + }; + copy_block(op_store_T2_GPR1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR2 +{ + static const uint8 op_store_T2_GPR2_code[] = { + 0x44, 0x89, 0x75, 0x18 + }; + copy_block(op_store_T2_GPR2_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR3 +{ + static const uint8 op_store_T2_GPR3_code[] = { + 0x44, 0x89, 0x75, 0x1c + }; + copy_block(op_store_T2_GPR3_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR4 +{ + static const uint8 op_store_T2_GPR4_code[] = { + 0x44, 0x89, 0x75, 0x20 + }; + copy_block(op_store_T2_GPR4_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR5 +{ + static const uint8 op_store_T2_GPR5_code[] = { + 0x44, 0x89, 0x75, 0x24 + }; + copy_block(op_store_T2_GPR5_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR6 +{ + static const uint8 op_store_T2_GPR6_code[] = { + 0x44, 0x89, 0x75, 0x28 + }; + copy_block(op_store_T2_GPR6_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR7 +{ + static const uint8 op_store_T2_GPR7_code[] = { + 0x44, 0x89, 0x75, 0x2c + }; + copy_block(op_store_T2_GPR7_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR8 +{ + static const uint8 op_store_T2_GPR8_code[] = { + 0x44, 0x89, 0x75, 0x30 + }; + copy_block(op_store_T2_GPR8_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR9 +{ + static const uint8 op_store_T2_GPR9_code[] = { + 0x44, 0x89, 0x75, 0x34 + }; + copy_block(op_store_T2_GPR9_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_vand_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vand_VD_V0_V1 +{ + static const uint8 op_vand_VD_V0_V1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x49, 0x23, 0x04, 0x24, 0x49, 0x89, 0x07, 0x49, + 0x8b, 0x45, 0x08, 0x49, 0x23, 0x44, 0x24, 0x08, 0x49, 0x89, 0x47, 0x08 + }; + copy_block(op_vand_VD_V0_V1_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_vnor_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vnor_VD_V0_V1 +{ + static const uint8 op_vnor_VD_V0_V1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x49, 0x0b, 0x04, 0x24, 0x48, 0xf7, 0xd0, 0x49, + 0x89, 0x07, 0x49, 0x8b, 0x45, 0x08, 0x49, 0x0b, 0x44, 0x24, 0x08, 0x48, + 0xf7, 0xd0, 0x49, 0x89, 0x47, 0x08 + }; + copy_block(op_vnor_VD_V0_V1_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_vxor_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vxor_VD_V0_V1 +{ + static const uint8 op_vxor_VD_V0_V1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x49, 0x33, 0x04, 0x24, 0x49, 0x89, 0x07, 0x49, + 0x8b, 0x45, 0x08, 0x49, 0x33, 0x44, 0x24, 0x08, 0x49, 0x89, 0x47, 0x08 + }; + copy_block(op_vxor_VD_V0_V1_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_branch_2_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_2_T0_im +{ + static const uint8 op_branch_2_T0_im_code[] = { + 0x45, 0x85, 0xed, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0x45, + 0xc4, 0x89, 0x85, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_2_T0_im_code, 19); + *(uint32_t *)(code_ptr() + 5) = (int32_t)((long)param1 - (long)(code_ptr() + 5 + 4)) + 0; + inc_code_ptr(19); +} +#endif + +DEFINE_GEN(gen_op_branch_2_im_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_2_im_im +{ + static const uint8 op_branch_2_im_im_code[] = { + 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x45, 0x85, 0xed, 0x8d, 0x15, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x45, 0xc2, 0x89, 0x85, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_2_im_im_code, 24); + *(uint32_t *)(code_ptr() + 11) = (int32_t)((long)param1 - (long)(code_ptr() + 11 + 4)) + 0; + *(uint32_t *)(code_ptr() + 2) = (int32_t)((long)param2 - (long)(code_ptr() + 2 + 4)) + 0; + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_branch_chain_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_chain_1 +{ + static const uint8 op_branch_chain_1_code[] = { + 0xe9, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_branch_chain_1_code, 5); + jmp_addr[0] = code_ptr() + 1; + *(uint32_t *)(code_ptr() + 1) = 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_branch_chain_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_chain_2 +{ + static const uint8 op_branch_chain_2_code[] = { + 0x45, 0x85, 0xed, 0x74, 0x07, 0xe9, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x05, + 0xe9, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_branch_chain_2_code, 17); + jmp_addr[1] = code_ptr() + 13; + *(uint32_t *)(code_ptr() + 13) = 0; + jmp_addr[0] = code_ptr() + 6; + *(uint32_t *)(code_ptr() + 6) = 0; + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_fadds_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fadds_FD_F0_F1 +{ + static const uint8 op_fadds_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x58, 0x45, 0x00, + 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x85, + 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fadds_FD_F0_F1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_fdivs_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fdivs_FD_F0_F1 +{ + static const uint8 op_fdivs_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x5e, 0x45, 0x00, + 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x85, + 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fdivs_FD_F0_F1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_fmuls_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmuls_FD_F0_F1 +{ + static const uint8 op_fmuls_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x85, + 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmuls_FD_F0_F1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_fsubs_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fsubs_FD_F0_F1 +{ + static const uint8 op_fsubs_FD_F0_F1_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x5c, 0x45, 0x00, + 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x85, + 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fsubs_FD_F0_F1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_VRSAVE,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_VRSAVE +{ + static const uint8 op_load_T0_VRSAVE_code[] = { + 0x44, 0x8b, 0xa5, 0x9c, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_VRSAVE_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR0 +{ + static const uint8 op_load_ad_V0_VR0_code[] = { + 0x4c, 0x8d, 0xa5, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR1 +{ + static const uint8 op_load_ad_V0_VR1_code[] = { + 0x4c, 0x8d, 0xa5, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR2 +{ + static const uint8 op_load_ad_V0_VR2_code[] = { + 0x4c, 0x8d, 0xa5, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR3 +{ + static const uint8 op_load_ad_V0_VR3_code[] = { + 0x4c, 0x8d, 0xa5, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR4 +{ + static const uint8 op_load_ad_V0_VR4_code[] = { + 0x4c, 0x8d, 0xa5, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR5 +{ + static const uint8 op_load_ad_V0_VR5_code[] = { + 0x4c, 0x8d, 0xa5, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR6 +{ + static const uint8 op_load_ad_V0_VR6_code[] = { + 0x4c, 0x8d, 0xa5, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR7 +{ + static const uint8 op_load_ad_V0_VR7_code[] = { + 0x4c, 0x8d, 0xa5, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR8 +{ + static const uint8 op_load_ad_V0_VR8_code[] = { + 0x4c, 0x8d, 0xa5, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR9 +{ + static const uint8 op_load_ad_V0_VR9_code[] = { + 0x4c, 0x8d, 0xa5, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR0 +{ + static const uint8 op_load_ad_V1_VR0_code[] = { + 0x4c, 0x8d, 0xad, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR1 +{ + static const uint8 op_load_ad_V1_VR1_code[] = { + 0x4c, 0x8d, 0xad, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR2 +{ + static const uint8 op_load_ad_V1_VR2_code[] = { + 0x4c, 0x8d, 0xad, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR3 +{ + static const uint8 op_load_ad_V1_VR3_code[] = { + 0x4c, 0x8d, 0xad, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR4 +{ + static const uint8 op_load_ad_V1_VR4_code[] = { + 0x4c, 0x8d, 0xad, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR5 +{ + static const uint8 op_load_ad_V1_VR5_code[] = { + 0x4c, 0x8d, 0xad, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR6 +{ + static const uint8 op_load_ad_V1_VR6_code[] = { + 0x4c, 0x8d, 0xad, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR7 +{ + static const uint8 op_load_ad_V1_VR7_code[] = { + 0x4c, 0x8d, 0xad, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR8 +{ + static const uint8 op_load_ad_V1_VR8_code[] = { + 0x4c, 0x8d, 0xad, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR9 +{ + static const uint8 op_load_ad_V1_VR9_code[] = { + 0x4c, 0x8d, 0xad, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR0 +{ + static const uint8 op_load_ad_V2_VR0_code[] = { + 0x4c, 0x8d, 0xb5, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR1 +{ + static const uint8 op_load_ad_V2_VR1_code[] = { + 0x4c, 0x8d, 0xb5, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR2 +{ + static const uint8 op_load_ad_V2_VR2_code[] = { + 0x4c, 0x8d, 0xb5, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR3 +{ + static const uint8 op_load_ad_V2_VR3_code[] = { + 0x4c, 0x8d, 0xb5, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR4 +{ + static const uint8 op_load_ad_V2_VR4_code[] = { + 0x4c, 0x8d, 0xb5, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR5 +{ + static const uint8 op_load_ad_V2_VR5_code[] = { + 0x4c, 0x8d, 0xb5, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR6 +{ + static const uint8 op_load_ad_V2_VR6_code[] = { + 0x4c, 0x8d, 0xb5, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR7 +{ + static const uint8 op_load_ad_V2_VR7_code[] = { + 0x4c, 0x8d, 0xb5, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR8 +{ + static const uint8 op_load_ad_V2_VR8_code[] = { + 0x4c, 0x8d, 0xb5, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR9 +{ + static const uint8 op_load_ad_V2_VR9_code[] = { + 0x4c, 0x8d, 0xb5, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR0 +{ + static const uint8 op_load_ad_VD_VR0_code[] = { + 0x4c, 0x8d, 0xbd, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR1 +{ + static const uint8 op_load_ad_VD_VR1_code[] = { + 0x4c, 0x8d, 0xbd, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR2 +{ + static const uint8 op_load_ad_VD_VR2_code[] = { + 0x4c, 0x8d, 0xbd, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR3 +{ + static const uint8 op_load_ad_VD_VR3_code[] = { + 0x4c, 0x8d, 0xbd, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR3_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR4 +{ + static const uint8 op_load_ad_VD_VR4_code[] = { + 0x4c, 0x8d, 0xbd, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR4_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR5 +{ + static const uint8 op_load_ad_VD_VR5_code[] = { + 0x4c, 0x8d, 0xbd, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR5_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR6 +{ + static const uint8 op_load_ad_VD_VR6_code[] = { + 0x4c, 0x8d, 0xbd, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR6_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR7 +{ + static const uint8 op_load_ad_VD_VR7_code[] = { + 0x4c, 0x8d, 0xbd, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR7_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR8 +{ + static const uint8 op_load_ad_VD_VR8_code[] = { + 0x4c, 0x8d, 0xbd, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR8_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR9 +{ + static const uint8 op_load_ad_VD_VR9_code[] = { + 0x4c, 0x8d, 0xbd, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR9_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_spcflags_check,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_check +{ + static const uint8 op_spcflags_check_code[] = { + 0x8b, 0x85, 0xb0, 0x03, 0x00, 0x00, 0x85, 0xc0, 0x0f, 0x84, 0x00, 0x00, + 0x00, 0x00 + }; + copy_block(op_spcflags_check_code, 14); + jmp_addr[0] = code_ptr() + 10; + *(uint32_t *)(code_ptr() + 10) = 0; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_spcflags_clear,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_clear +{ + static const uint8 op_spcflags_clear_code[] = { + 0x48, 0x8d, 0x8d, 0xb0, 0x03, 0x00, 0x00, 0x48, 0x8d, 0x95, 0xb4, 0x03, + 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x87, 0x02, 0x85, 0xc0, 0x75, + 0xf5, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xd0, 0x21, 0x01, + 0xc7, 0x41, 0x04, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_spcflags_clear_code, 43); + *(uint32_t *)(code_ptr() + 28) = (int32_t)((long)param1 - (long)(code_ptr() + 28 + 4)) + 0; + inc_code_ptr(43); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR10 +{ + static const uint8 op_store_F0_FPR10_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR10_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR11 +{ + static const uint8 op_store_F0_FPR11_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR11_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR12 +{ + static const uint8 op_store_F0_FPR12_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR12_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR13 +{ + static const uint8 op_store_F0_FPR13_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR13_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR14 +{ + static const uint8 op_store_F0_FPR14_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR14_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR15 +{ + static const uint8 op_store_F0_FPR15_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR15_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR16 +{ + static const uint8 op_store_F0_FPR16_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR16_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR17 +{ + static const uint8 op_store_F0_FPR17_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR17_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR18 +{ + static const uint8 op_store_F0_FPR18_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR18_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR19 +{ + static const uint8 op_store_F0_FPR19_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR19_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR20 +{ + static const uint8 op_store_F0_FPR20_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR20_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR21 +{ + static const uint8 op_store_F0_FPR21_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR21_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR22 +{ + static const uint8 op_store_F0_FPR22_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR22_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR23 +{ + static const uint8 op_store_F0_FPR23_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR23_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR24 +{ + static const uint8 op_store_F0_FPR24_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR24_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR25 +{ + static const uint8 op_store_F0_FPR25_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR25_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR26 +{ + static const uint8 op_store_F0_FPR26_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR26_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR27 +{ + static const uint8 op_store_F0_FPR27_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR27_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR28 +{ + static const uint8 op_store_F0_FPR28_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR28_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR29 +{ + static const uint8 op_store_F0_FPR29_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR29_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR30 +{ + static const uint8 op_store_F0_FPR30_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR30_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR31 +{ + static const uint8 op_store_F0_FPR31_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x48, 0x89, 0x85, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR31_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR10 +{ + static const uint8 op_store_F1_FPR10_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR10_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR11 +{ + static const uint8 op_store_F1_FPR11_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR11_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR12 +{ + static const uint8 op_store_F1_FPR12_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR12_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR13 +{ + static const uint8 op_store_F1_FPR13_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR13_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR14 +{ + static const uint8 op_store_F1_FPR14_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR14_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR15 +{ + static const uint8 op_store_F1_FPR15_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR15_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR16 +{ + static const uint8 op_store_F1_FPR16_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR16_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR17 +{ + static const uint8 op_store_F1_FPR17_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR17_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR18 +{ + static const uint8 op_store_F1_FPR18_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR18_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR19 +{ + static const uint8 op_store_F1_FPR19_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR19_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR20 +{ + static const uint8 op_store_F1_FPR20_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR20_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR21 +{ + static const uint8 op_store_F1_FPR21_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR21_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR22 +{ + static const uint8 op_store_F1_FPR22_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR22_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR23 +{ + static const uint8 op_store_F1_FPR23_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR23_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR24 +{ + static const uint8 op_store_F1_FPR24_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR24_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR25 +{ + static const uint8 op_store_F1_FPR25_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR25_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR26 +{ + static const uint8 op_store_F1_FPR26_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR26_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR27 +{ + static const uint8 op_store_F1_FPR27_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR27_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR28 +{ + static const uint8 op_store_F1_FPR28_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR28_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR29 +{ + static const uint8 op_store_F1_FPR29_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR29_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR30 +{ + static const uint8 op_store_F1_FPR30_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR30_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR31 +{ + static const uint8 op_store_F1_FPR31_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0x89, 0x85, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR31_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR10 +{ + static const uint8 op_store_F2_FPR10_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR10_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR11 +{ + static const uint8 op_store_F2_FPR11_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR11_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR12 +{ + static const uint8 op_store_F2_FPR12_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR12_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR13 +{ + static const uint8 op_store_F2_FPR13_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR13_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR14 +{ + static const uint8 op_store_F2_FPR14_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR14_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR15 +{ + static const uint8 op_store_F2_FPR15_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR15_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR16 +{ + static const uint8 op_store_F2_FPR16_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR16_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR17 +{ + static const uint8 op_store_F2_FPR17_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR17_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR18 +{ + static const uint8 op_store_F2_FPR18_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR18_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR19 +{ + static const uint8 op_store_F2_FPR19_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR19_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR20 +{ + static const uint8 op_store_F2_FPR20_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR20_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR21 +{ + static const uint8 op_store_F2_FPR21_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR21_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR22 +{ + static const uint8 op_store_F2_FPR22_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR22_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR23 +{ + static const uint8 op_store_F2_FPR23_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR23_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR24 +{ + static const uint8 op_store_F2_FPR24_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR24_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR25 +{ + static const uint8 op_store_F2_FPR25_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR25_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR26 +{ + static const uint8 op_store_F2_FPR26_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR26_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR27 +{ + static const uint8 op_store_F2_FPR27_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR27_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR28 +{ + static const uint8 op_store_F2_FPR28_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR28_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR29 +{ + static const uint8 op_store_F2_FPR29_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR29_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR30 +{ + static const uint8 op_store_F2_FPR30_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR30_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR31 +{ + static const uint8 op_store_F2_FPR31_code[] = { + 0x49, 0x8b, 0x06, 0x48, 0x89, 0x85, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR31_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR10 +{ + static const uint8 op_store_FD_FPR10_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xe0, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR10_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR11 +{ + static const uint8 op_store_FD_FPR11_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xe8, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR11_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR12 +{ + static const uint8 op_store_FD_FPR12_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xf0, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR12_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR13 +{ + static const uint8 op_store_FD_FPR13_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0xf8, 0x00, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR13_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR14 +{ + static const uint8 op_store_FD_FPR14_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x00, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR14_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR15 +{ + static const uint8 op_store_FD_FPR15_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x08, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR15_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR16 +{ + static const uint8 op_store_FD_FPR16_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x10, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR16_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR17 +{ + static const uint8 op_store_FD_FPR17_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x18, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR17_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR18 +{ + static const uint8 op_store_FD_FPR18_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x20, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR18_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR19 +{ + static const uint8 op_store_FD_FPR19_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x28, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR19_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR20 +{ + static const uint8 op_store_FD_FPR20_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x30, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR20_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR21 +{ + static const uint8 op_store_FD_FPR21_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x38, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR21_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR22 +{ + static const uint8 op_store_FD_FPR22_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x40, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR22_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR23 +{ + static const uint8 op_store_FD_FPR23_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x48, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR23_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR24 +{ + static const uint8 op_store_FD_FPR24_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x50, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR24_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR25 +{ + static const uint8 op_store_FD_FPR25_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x58, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR25_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR26 +{ + static const uint8 op_store_FD_FPR26_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x60, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR26_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR27 +{ + static const uint8 op_store_FD_FPR27_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x68, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR27_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR28 +{ + static const uint8 op_store_FD_FPR28_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x70, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR28_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR29 +{ + static const uint8 op_store_FD_FPR29_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x78, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR29_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR30 +{ + static const uint8 op_store_FD_FPR30_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x80, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR30_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR31 +{ + static const uint8 op_store_FD_FPR31_code[] = { + 0x48, 0x8b, 0x85, 0xa8, 0x08, 0x10, 0x00, 0x48, 0x89, 0x85, 0x88, 0x01, + 0x00, 0x00 + }; + copy_block(op_store_FD_FPR31_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR10 +{ + static const uint8 op_store_T0_GPR10_code[] = { + 0x44, 0x89, 0x65, 0x38 + }; + copy_block(op_store_T0_GPR10_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR11 +{ + static const uint8 op_store_T0_GPR11_code[] = { + 0x44, 0x89, 0x65, 0x3c + }; + copy_block(op_store_T0_GPR11_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR12 +{ + static const uint8 op_store_T0_GPR12_code[] = { + 0x44, 0x89, 0x65, 0x40 + }; + copy_block(op_store_T0_GPR12_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR13 +{ + static const uint8 op_store_T0_GPR13_code[] = { + 0x44, 0x89, 0x65, 0x44 + }; + copy_block(op_store_T0_GPR13_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR14 +{ + static const uint8 op_store_T0_GPR14_code[] = { + 0x44, 0x89, 0x65, 0x48 + }; + copy_block(op_store_T0_GPR14_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR15 +{ + static const uint8 op_store_T0_GPR15_code[] = { + 0x44, 0x89, 0x65, 0x4c + }; + copy_block(op_store_T0_GPR15_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR16 +{ + static const uint8 op_store_T0_GPR16_code[] = { + 0x44, 0x89, 0x65, 0x50 + }; + copy_block(op_store_T0_GPR16_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR17 +{ + static const uint8 op_store_T0_GPR17_code[] = { + 0x44, 0x89, 0x65, 0x54 + }; + copy_block(op_store_T0_GPR17_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR18 +{ + static const uint8 op_store_T0_GPR18_code[] = { + 0x44, 0x89, 0x65, 0x58 + }; + copy_block(op_store_T0_GPR18_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR19 +{ + static const uint8 op_store_T0_GPR19_code[] = { + 0x44, 0x89, 0x65, 0x5c + }; + copy_block(op_store_T0_GPR19_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR20 +{ + static const uint8 op_store_T0_GPR20_code[] = { + 0x44, 0x89, 0x65, 0x60 + }; + copy_block(op_store_T0_GPR20_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR21 +{ + static const uint8 op_store_T0_GPR21_code[] = { + 0x44, 0x89, 0x65, 0x64 + }; + copy_block(op_store_T0_GPR21_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR22 +{ + static const uint8 op_store_T0_GPR22_code[] = { + 0x44, 0x89, 0x65, 0x68 + }; + copy_block(op_store_T0_GPR22_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR23 +{ + static const uint8 op_store_T0_GPR23_code[] = { + 0x44, 0x89, 0x65, 0x6c + }; + copy_block(op_store_T0_GPR23_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR24 +{ + static const uint8 op_store_T0_GPR24_code[] = { + 0x44, 0x89, 0x65, 0x70 + }; + copy_block(op_store_T0_GPR24_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR25 +{ + static const uint8 op_store_T0_GPR25_code[] = { + 0x44, 0x89, 0x65, 0x74 + }; + copy_block(op_store_T0_GPR25_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR26 +{ + static const uint8 op_store_T0_GPR26_code[] = { + 0x44, 0x89, 0x65, 0x78 + }; + copy_block(op_store_T0_GPR26_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR27 +{ + static const uint8 op_store_T0_GPR27_code[] = { + 0x44, 0x89, 0x65, 0x7c + }; + copy_block(op_store_T0_GPR27_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR28 +{ + static const uint8 op_store_T0_GPR28_code[] = { + 0x44, 0x89, 0xa5, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR29 +{ + static const uint8 op_store_T0_GPR29_code[] = { + 0x44, 0x89, 0xa5, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR30 +{ + static const uint8 op_store_T0_GPR30_code[] = { + 0x44, 0x89, 0xa5, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR31 +{ + static const uint8 op_store_T0_GPR31_code[] = { + 0x44, 0x89, 0xa5, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb10 +{ + static const uint8 op_store_T0_crb10_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xdf, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x15, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb10_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb11 +{ + static const uint8 op_store_T0_crb11_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xef, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x14, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb11_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb12 +{ + static const uint8 op_store_T0_crb12_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xf7, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x13, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb12_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb13 +{ + static const uint8 op_store_T0_crb13_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xfb, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x12, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb13_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb14 +{ + static const uint8 op_store_T0_crb14_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xfd, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x11, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb14_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb15 +{ + static const uint8 op_store_T0_crb15_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xfe, 0xff, + 0x44, 0x89, 0xe0, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x10, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb15_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb16 +{ + static const uint8 op_store_T0_crb16_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0x7f, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0f, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb16_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb17 +{ + static const uint8 op_store_T0_crb17_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xbf, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0e, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb17_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb18 +{ + static const uint8 op_store_T0_crb18_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xdf, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0d, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb18_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb19 +{ + static const uint8 op_store_T0_crb19_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xef, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0c, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb19_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb20 +{ + static const uint8 op_store_T0_crb20_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xf7, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0b, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb20_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb21 +{ + static const uint8 op_store_T0_crb21_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xfb, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0a, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb21_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb22 +{ + static const uint8 op_store_T0_crb22_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xfd, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x09, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb22_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb23 +{ + static const uint8 op_store_T0_crb23_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xfe, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x08, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb23_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb24 +{ + static const uint8 op_store_T0_crb24_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe2, 0x7f, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x07, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb24_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb25 +{ + static const uint8 op_store_T0_crb25_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xbf, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x06, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb25_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb26 +{ + static const uint8 op_store_T0_crb26_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xdf, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x05, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb26_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb27 +{ + static const uint8 op_store_T0_crb27_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xef, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x04, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb27_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb28 +{ + static const uint8 op_store_T0_crb28_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xf7, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x03, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb28_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb29 +{ + static const uint8 op_store_T0_crb29_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xfb, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x02, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T0_crb29_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb30 +{ + static const uint8 op_store_T0_crb30_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xfd, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0x01, 0xc0, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_crb30_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb31 +{ + static const uint8 op_store_T0_crb31_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xfe, 0x44, 0x89, 0xe0, + 0x83, 0xe0, 0x01, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb31_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR10 +{ + static const uint8 op_store_T1_GPR10_code[] = { + 0x44, 0x89, 0x6d, 0x38 + }; + copy_block(op_store_T1_GPR10_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR11 +{ + static const uint8 op_store_T1_GPR11_code[] = { + 0x44, 0x89, 0x6d, 0x3c + }; + copy_block(op_store_T1_GPR11_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR12 +{ + static const uint8 op_store_T1_GPR12_code[] = { + 0x44, 0x89, 0x6d, 0x40 + }; + copy_block(op_store_T1_GPR12_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR13 +{ + static const uint8 op_store_T1_GPR13_code[] = { + 0x44, 0x89, 0x6d, 0x44 + }; + copy_block(op_store_T1_GPR13_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR14 +{ + static const uint8 op_store_T1_GPR14_code[] = { + 0x44, 0x89, 0x6d, 0x48 + }; + copy_block(op_store_T1_GPR14_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR15 +{ + static const uint8 op_store_T1_GPR15_code[] = { + 0x44, 0x89, 0x6d, 0x4c + }; + copy_block(op_store_T1_GPR15_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR16 +{ + static const uint8 op_store_T1_GPR16_code[] = { + 0x44, 0x89, 0x6d, 0x50 + }; + copy_block(op_store_T1_GPR16_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR17 +{ + static const uint8 op_store_T1_GPR17_code[] = { + 0x44, 0x89, 0x6d, 0x54 + }; + copy_block(op_store_T1_GPR17_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR18 +{ + static const uint8 op_store_T1_GPR18_code[] = { + 0x44, 0x89, 0x6d, 0x58 + }; + copy_block(op_store_T1_GPR18_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR19 +{ + static const uint8 op_store_T1_GPR19_code[] = { + 0x44, 0x89, 0x6d, 0x5c + }; + copy_block(op_store_T1_GPR19_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR20 +{ + static const uint8 op_store_T1_GPR20_code[] = { + 0x44, 0x89, 0x6d, 0x60 + }; + copy_block(op_store_T1_GPR20_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR21 +{ + static const uint8 op_store_T1_GPR21_code[] = { + 0x44, 0x89, 0x6d, 0x64 + }; + copy_block(op_store_T1_GPR21_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR22 +{ + static const uint8 op_store_T1_GPR22_code[] = { + 0x44, 0x89, 0x6d, 0x68 + }; + copy_block(op_store_T1_GPR22_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR23 +{ + static const uint8 op_store_T1_GPR23_code[] = { + 0x44, 0x89, 0x6d, 0x6c + }; + copy_block(op_store_T1_GPR23_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR24 +{ + static const uint8 op_store_T1_GPR24_code[] = { + 0x44, 0x89, 0x6d, 0x70 + }; + copy_block(op_store_T1_GPR24_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR25 +{ + static const uint8 op_store_T1_GPR25_code[] = { + 0x44, 0x89, 0x6d, 0x74 + }; + copy_block(op_store_T1_GPR25_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR26 +{ + static const uint8 op_store_T1_GPR26_code[] = { + 0x44, 0x89, 0x6d, 0x78 + }; + copy_block(op_store_T1_GPR26_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR27 +{ + static const uint8 op_store_T1_GPR27_code[] = { + 0x44, 0x89, 0x6d, 0x7c + }; + copy_block(op_store_T1_GPR27_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR28 +{ + static const uint8 op_store_T1_GPR28_code[] = { + 0x44, 0x89, 0xad, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR29 +{ + static const uint8 op_store_T1_GPR29_code[] = { + 0x44, 0x89, 0xad, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR30 +{ + static const uint8 op_store_T1_GPR30_code[] = { + 0x44, 0x89, 0xad, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR31 +{ + static const uint8 op_store_T1_GPR31_code[] = { + 0x44, 0x89, 0xad, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb10 +{ + static const uint8 op_store_T1_crb10_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xdf, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x15, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb10_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb11 +{ + static const uint8 op_store_T1_crb11_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xef, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x14, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb11_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb12 +{ + static const uint8 op_store_T1_crb12_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xf7, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x13, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb12_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb13 +{ + static const uint8 op_store_T1_crb13_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xfb, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x12, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb13_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb14 +{ + static const uint8 op_store_T1_crb14_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xfd, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x11, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb14_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb15 +{ + static const uint8 op_store_T1_crb15_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x81, 0xe2, 0xff, 0xff, 0xfe, 0xff, + 0x44, 0x89, 0xe8, 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x10, 0x09, 0xd0, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb15_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb16 +{ + static const uint8 op_store_T1_crb16_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0x7f, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0f, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb16_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb17 +{ + static const uint8 op_store_T1_crb17_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xbf, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0e, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb17_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb18 +{ + static const uint8 op_store_T1_crb18_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xdf, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0d, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb18_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb19 +{ + static const uint8 op_store_T1_crb19_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xef, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0c, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb19_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb20 +{ + static const uint8 op_store_T1_crb20_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xf7, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0b, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb20_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb21 +{ + static const uint8 op_store_T1_crb21_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xfb, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x0a, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb21_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb22 +{ + static const uint8 op_store_T1_crb22_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xfd, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x09, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb22_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb23 +{ + static const uint8 op_store_T1_crb23_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe6, 0xfe, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x08, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb23_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb24 +{ + static const uint8 op_store_T1_crb24_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x80, 0xe2, 0x7f, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x07, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb24_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb25 +{ + static const uint8 op_store_T1_crb25_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xbf, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x06, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb25_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb26 +{ + static const uint8 op_store_T1_crb26_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xdf, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x05, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb26_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb27 +{ + static const uint8 op_store_T1_crb27_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xef, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x04, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb27_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb28 +{ + static const uint8 op_store_T1_crb28_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xf7, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x03, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb28_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb29 +{ + static const uint8 op_store_T1_crb29_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xfb, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0xc1, 0xe0, 0x02, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_store_T1_crb29_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb30 +{ + static const uint8 op_store_T1_crb30_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xfd, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0x01, 0xc0, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T1_crb30_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb31 +{ + static const uint8 op_store_T1_crb31_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe2, 0xfe, 0x44, 0x89, 0xe8, + 0x83, 0xe0, 0x01, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb31_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR10 +{ + static const uint8 op_store_T2_GPR10_code[] = { + 0x44, 0x89, 0x75, 0x38 + }; + copy_block(op_store_T2_GPR10_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR11 +{ + static const uint8 op_store_T2_GPR11_code[] = { + 0x44, 0x89, 0x75, 0x3c + }; + copy_block(op_store_T2_GPR11_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR12 +{ + static const uint8 op_store_T2_GPR12_code[] = { + 0x44, 0x89, 0x75, 0x40 + }; + copy_block(op_store_T2_GPR12_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR13 +{ + static const uint8 op_store_T2_GPR13_code[] = { + 0x44, 0x89, 0x75, 0x44 + }; + copy_block(op_store_T2_GPR13_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR14 +{ + static const uint8 op_store_T2_GPR14_code[] = { + 0x44, 0x89, 0x75, 0x48 + }; + copy_block(op_store_T2_GPR14_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR15 +{ + static const uint8 op_store_T2_GPR15_code[] = { + 0x44, 0x89, 0x75, 0x4c + }; + copy_block(op_store_T2_GPR15_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR16 +{ + static const uint8 op_store_T2_GPR16_code[] = { + 0x44, 0x89, 0x75, 0x50 + }; + copy_block(op_store_T2_GPR16_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR17 +{ + static const uint8 op_store_T2_GPR17_code[] = { + 0x44, 0x89, 0x75, 0x54 + }; + copy_block(op_store_T2_GPR17_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR18 +{ + static const uint8 op_store_T2_GPR18_code[] = { + 0x44, 0x89, 0x75, 0x58 + }; + copy_block(op_store_T2_GPR18_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR19 +{ + static const uint8 op_store_T2_GPR19_code[] = { + 0x44, 0x89, 0x75, 0x5c + }; + copy_block(op_store_T2_GPR19_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR20 +{ + static const uint8 op_store_T2_GPR20_code[] = { + 0x44, 0x89, 0x75, 0x60 + }; + copy_block(op_store_T2_GPR20_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR21 +{ + static const uint8 op_store_T2_GPR21_code[] = { + 0x44, 0x89, 0x75, 0x64 + }; + copy_block(op_store_T2_GPR21_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR22 +{ + static const uint8 op_store_T2_GPR22_code[] = { + 0x44, 0x89, 0x75, 0x68 + }; + copy_block(op_store_T2_GPR22_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR23 +{ + static const uint8 op_store_T2_GPR23_code[] = { + 0x44, 0x89, 0x75, 0x6c + }; + copy_block(op_store_T2_GPR23_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR24 +{ + static const uint8 op_store_T2_GPR24_code[] = { + 0x44, 0x89, 0x75, 0x70 + }; + copy_block(op_store_T2_GPR24_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR25 +{ + static const uint8 op_store_T2_GPR25_code[] = { + 0x44, 0x89, 0x75, 0x74 + }; + copy_block(op_store_T2_GPR25_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR26 +{ + static const uint8 op_store_T2_GPR26_code[] = { + 0x44, 0x89, 0x75, 0x78 + }; + copy_block(op_store_T2_GPR26_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR27 +{ + static const uint8 op_store_T2_GPR27_code[] = { + 0x44, 0x89, 0x75, 0x7c + }; + copy_block(op_store_T2_GPR27_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR28 +{ + static const uint8 op_store_T2_GPR28_code[] = { + 0x44, 0x89, 0xb5, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR29 +{ + static const uint8 op_store_T2_GPR29_code[] = { + 0x44, 0x89, 0xb5, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR30 +{ + static const uint8 op_store_T2_GPR30_code[] = { + 0x44, 0x89, 0xb5, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR31 +{ + static const uint8 op_store_T2_GPR31_code[] = { + 0x44, 0x89, 0xb5, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_vandc_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vandc_VD_V0_V1 +{ + static const uint8 op_vandc_VD_V0_V1_code[] = { + 0x49, 0x8b, 0x45, 0x00, 0x48, 0xf7, 0xd0, 0x49, 0x23, 0x04, 0x24, 0x49, + 0x89, 0x07, 0x49, 0x8b, 0x45, 0x08, 0x48, 0xf7, 0xd0, 0x49, 0x23, 0x44, + 0x24, 0x08, 0x49, 0x89, 0x47, 0x08 + }; + copy_block(op_vandc_VD_V0_V1_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR10 +{ + static const uint8 op_load_ad_V0_VR10_code[] = { + 0x4c, 0x8d, 0xa5, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR11 +{ + static const uint8 op_load_ad_V0_VR11_code[] = { + 0x4c, 0x8d, 0xa5, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR12 +{ + static const uint8 op_load_ad_V0_VR12_code[] = { + 0x4c, 0x8d, 0xa5, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR13 +{ + static const uint8 op_load_ad_V0_VR13_code[] = { + 0x4c, 0x8d, 0xa5, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR14 +{ + static const uint8 op_load_ad_V0_VR14_code[] = { + 0x4c, 0x8d, 0xa5, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR15 +{ + static const uint8 op_load_ad_V0_VR15_code[] = { + 0x4c, 0x8d, 0xa5, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR16 +{ + static const uint8 op_load_ad_V0_VR16_code[] = { + 0x4c, 0x8d, 0xa5, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR17 +{ + static const uint8 op_load_ad_V0_VR17_code[] = { + 0x4c, 0x8d, 0xa5, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR18 +{ + static const uint8 op_load_ad_V0_VR18_code[] = { + 0x4c, 0x8d, 0xa5, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR19 +{ + static const uint8 op_load_ad_V0_VR19_code[] = { + 0x4c, 0x8d, 0xa5, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR20 +{ + static const uint8 op_load_ad_V0_VR20_code[] = { + 0x4c, 0x8d, 0xa5, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR21 +{ + static const uint8 op_load_ad_V0_VR21_code[] = { + 0x4c, 0x8d, 0xa5, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR22 +{ + static const uint8 op_load_ad_V0_VR22_code[] = { + 0x4c, 0x8d, 0xa5, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR23 +{ + static const uint8 op_load_ad_V0_VR23_code[] = { + 0x4c, 0x8d, 0xa5, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR24 +{ + static const uint8 op_load_ad_V0_VR24_code[] = { + 0x4c, 0x8d, 0xa5, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR25 +{ + static const uint8 op_load_ad_V0_VR25_code[] = { + 0x4c, 0x8d, 0xa5, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR26 +{ + static const uint8 op_load_ad_V0_VR26_code[] = { + 0x4c, 0x8d, 0xa5, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR27 +{ + static const uint8 op_load_ad_V0_VR27_code[] = { + 0x4c, 0x8d, 0xa5, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR28 +{ + static const uint8 op_load_ad_V0_VR28_code[] = { + 0x4c, 0x8d, 0xa5, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR29 +{ + static const uint8 op_load_ad_V0_VR29_code[] = { + 0x4c, 0x8d, 0xa5, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR30 +{ + static const uint8 op_load_ad_V0_VR30_code[] = { + 0x4c, 0x8d, 0xa5, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR31 +{ + static const uint8 op_load_ad_V0_VR31_code[] = { + 0x4c, 0x8d, 0xa5, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR10 +{ + static const uint8 op_load_ad_V1_VR10_code[] = { + 0x4c, 0x8d, 0xad, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR11 +{ + static const uint8 op_load_ad_V1_VR11_code[] = { + 0x4c, 0x8d, 0xad, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR12 +{ + static const uint8 op_load_ad_V1_VR12_code[] = { + 0x4c, 0x8d, 0xad, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR13 +{ + static const uint8 op_load_ad_V1_VR13_code[] = { + 0x4c, 0x8d, 0xad, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR14 +{ + static const uint8 op_load_ad_V1_VR14_code[] = { + 0x4c, 0x8d, 0xad, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR15 +{ + static const uint8 op_load_ad_V1_VR15_code[] = { + 0x4c, 0x8d, 0xad, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR16 +{ + static const uint8 op_load_ad_V1_VR16_code[] = { + 0x4c, 0x8d, 0xad, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR17 +{ + static const uint8 op_load_ad_V1_VR17_code[] = { + 0x4c, 0x8d, 0xad, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR18 +{ + static const uint8 op_load_ad_V1_VR18_code[] = { + 0x4c, 0x8d, 0xad, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR19 +{ + static const uint8 op_load_ad_V1_VR19_code[] = { + 0x4c, 0x8d, 0xad, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR20 +{ + static const uint8 op_load_ad_V1_VR20_code[] = { + 0x4c, 0x8d, 0xad, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR21 +{ + static const uint8 op_load_ad_V1_VR21_code[] = { + 0x4c, 0x8d, 0xad, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR22 +{ + static const uint8 op_load_ad_V1_VR22_code[] = { + 0x4c, 0x8d, 0xad, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR23 +{ + static const uint8 op_load_ad_V1_VR23_code[] = { + 0x4c, 0x8d, 0xad, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR24 +{ + static const uint8 op_load_ad_V1_VR24_code[] = { + 0x4c, 0x8d, 0xad, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR25 +{ + static const uint8 op_load_ad_V1_VR25_code[] = { + 0x4c, 0x8d, 0xad, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR26 +{ + static const uint8 op_load_ad_V1_VR26_code[] = { + 0x4c, 0x8d, 0xad, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR27 +{ + static const uint8 op_load_ad_V1_VR27_code[] = { + 0x4c, 0x8d, 0xad, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR28 +{ + static const uint8 op_load_ad_V1_VR28_code[] = { + 0x4c, 0x8d, 0xad, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR29 +{ + static const uint8 op_load_ad_V1_VR29_code[] = { + 0x4c, 0x8d, 0xad, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR30 +{ + static const uint8 op_load_ad_V1_VR30_code[] = { + 0x4c, 0x8d, 0xad, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR31 +{ + static const uint8 op_load_ad_V1_VR31_code[] = { + 0x4c, 0x8d, 0xad, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR10 +{ + static const uint8 op_load_ad_V2_VR10_code[] = { + 0x4c, 0x8d, 0xb5, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR11 +{ + static const uint8 op_load_ad_V2_VR11_code[] = { + 0x4c, 0x8d, 0xb5, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR12 +{ + static const uint8 op_load_ad_V2_VR12_code[] = { + 0x4c, 0x8d, 0xb5, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR13 +{ + static const uint8 op_load_ad_V2_VR13_code[] = { + 0x4c, 0x8d, 0xb5, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR14 +{ + static const uint8 op_load_ad_V2_VR14_code[] = { + 0x4c, 0x8d, 0xb5, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR15 +{ + static const uint8 op_load_ad_V2_VR15_code[] = { + 0x4c, 0x8d, 0xb5, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR16 +{ + static const uint8 op_load_ad_V2_VR16_code[] = { + 0x4c, 0x8d, 0xb5, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR17 +{ + static const uint8 op_load_ad_V2_VR17_code[] = { + 0x4c, 0x8d, 0xb5, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR18 +{ + static const uint8 op_load_ad_V2_VR18_code[] = { + 0x4c, 0x8d, 0xb5, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR19 +{ + static const uint8 op_load_ad_V2_VR19_code[] = { + 0x4c, 0x8d, 0xb5, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR20 +{ + static const uint8 op_load_ad_V2_VR20_code[] = { + 0x4c, 0x8d, 0xb5, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR21 +{ + static const uint8 op_load_ad_V2_VR21_code[] = { + 0x4c, 0x8d, 0xb5, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR22 +{ + static const uint8 op_load_ad_V2_VR22_code[] = { + 0x4c, 0x8d, 0xb5, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR23 +{ + static const uint8 op_load_ad_V2_VR23_code[] = { + 0x4c, 0x8d, 0xb5, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR24 +{ + static const uint8 op_load_ad_V2_VR24_code[] = { + 0x4c, 0x8d, 0xb5, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR25 +{ + static const uint8 op_load_ad_V2_VR25_code[] = { + 0x4c, 0x8d, 0xb5, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR26 +{ + static const uint8 op_load_ad_V2_VR26_code[] = { + 0x4c, 0x8d, 0xb5, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR27 +{ + static const uint8 op_load_ad_V2_VR27_code[] = { + 0x4c, 0x8d, 0xb5, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR28 +{ + static const uint8 op_load_ad_V2_VR28_code[] = { + 0x4c, 0x8d, 0xb5, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR29 +{ + static const uint8 op_load_ad_V2_VR29_code[] = { + 0x4c, 0x8d, 0xb5, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR30 +{ + static const uint8 op_load_ad_V2_VR30_code[] = { + 0x4c, 0x8d, 0xb5, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR31 +{ + static const uint8 op_load_ad_V2_VR31_code[] = { + 0x4c, 0x8d, 0xb5, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR10 +{ + static const uint8 op_load_ad_VD_VR10_code[] = { + 0x4c, 0x8d, 0xbd, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR10_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR11 +{ + static const uint8 op_load_ad_VD_VR11_code[] = { + 0x4c, 0x8d, 0xbd, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR11_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR12 +{ + static const uint8 op_load_ad_VD_VR12_code[] = { + 0x4c, 0x8d, 0xbd, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR12_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR13 +{ + static const uint8 op_load_ad_VD_VR13_code[] = { + 0x4c, 0x8d, 0xbd, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR13_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR14 +{ + static const uint8 op_load_ad_VD_VR14_code[] = { + 0x4c, 0x8d, 0xbd, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR14_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR15 +{ + static const uint8 op_load_ad_VD_VR15_code[] = { + 0x4c, 0x8d, 0xbd, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR15_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR16 +{ + static const uint8 op_load_ad_VD_VR16_code[] = { + 0x4c, 0x8d, 0xbd, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR16_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR17 +{ + static const uint8 op_load_ad_VD_VR17_code[] = { + 0x4c, 0x8d, 0xbd, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR17_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR18 +{ + static const uint8 op_load_ad_VD_VR18_code[] = { + 0x4c, 0x8d, 0xbd, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR18_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR19 +{ + static const uint8 op_load_ad_VD_VR19_code[] = { + 0x4c, 0x8d, 0xbd, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR19_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR20 +{ + static const uint8 op_load_ad_VD_VR20_code[] = { + 0x4c, 0x8d, 0xbd, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR20_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR21 +{ + static const uint8 op_load_ad_VD_VR21_code[] = { + 0x4c, 0x8d, 0xbd, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR21_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR22 +{ + static const uint8 op_load_ad_VD_VR22_code[] = { + 0x4c, 0x8d, 0xbd, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR22_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR23 +{ + static const uint8 op_load_ad_VD_VR23_code[] = { + 0x4c, 0x8d, 0xbd, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR23_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR24 +{ + static const uint8 op_load_ad_VD_VR24_code[] = { + 0x4c, 0x8d, 0xbd, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR24_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR25 +{ + static const uint8 op_load_ad_VD_VR25_code[] = { + 0x4c, 0x8d, 0xbd, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR25_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR26 +{ + static const uint8 op_load_ad_VD_VR26_code[] = { + 0x4c, 0x8d, 0xbd, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR26_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR27 +{ + static const uint8 op_load_ad_VD_VR27_code[] = { + 0x4c, 0x8d, 0xbd, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR27_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR28 +{ + static const uint8 op_load_ad_VD_VR28_code[] = { + 0x4c, 0x8d, 0xbd, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR28_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR29 +{ + static const uint8 op_load_ad_VD_VR29_code[] = { + 0x4c, 0x8d, 0xbd, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR29_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR30 +{ + static const uint8 op_load_ad_VD_VR30_code[] = { + 0x4c, 0x8d, 0xbd, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR30_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR31 +{ + static const uint8 op_load_ad_VD_VR31_code[] = { + 0x4c, 0x8d, 0xbd, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_VD_VR31_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_vect_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_vect_VD_T0 +{ + static const uint8 op_load_vect_VD_T0_code[] = { + 0x44, 0x89, 0xe2, 0x83, 0xe2, 0xf0, 0x89, 0xd0, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0x41, 0x89, 0x07, 0x8d, 0x42, 0x04, 0x89, 0xc0, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0x41, 0x89, 0x47, 0x04, 0x8d, 0x42, 0x08, 0x89, 0xc0, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0x41, 0x89, 0x47, 0x08, 0x83, 0xc2, 0x0c, 0x89, 0xd2, 0x8b, + 0x02, 0x0f, 0xc8, 0x41, 0x89, 0x47, 0x0c + }; + copy_block(op_load_vect_VD_T0_code, 162); + *(uint32_t *)(code_ptr() + 32) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 80) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 129) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 40) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 88) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 137) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(162); +} +#endif + +DEFINE_GEN(gen_op_load_word_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_word_VD_T0 +{ + static const uint8 op_load_word_VD_T0_code[] = { + 0x44, 0x89, 0xe2, 0x48, 0x89, 0xd0, 0x83, 0xe0, 0xfc, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0xc1, 0xea, 0x02, 0x83, 0xe2, 0x03, 0x41, 0x89, 0x04, 0x97 + }; + copy_block(op_load_word_VD_T0_code, 59); + *(uint32_t *)(code_ptr() + 33) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 41) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(59); +} +#endif + +DEFINE_GEN(gen_op_store_T0_VRSAVE,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_VRSAVE +{ + static const uint8 op_store_T0_VRSAVE_code[] = { + 0x44, 0x89, 0xa5, 0x9c, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_VRSAVE_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_vaddfp_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vaddfp_VD_V0_V1 +{ + static const uint8 op_vaddfp_VD_V0_V1_code[] = { + 0xf3, 0x41, 0x0f, 0x10, 0x45, 0x00, 0xf3, 0x41, 0x0f, 0x58, 0x04, 0x24, + 0xf3, 0x41, 0x0f, 0x11, 0x07, 0xf3, 0x41, 0x0f, 0x10, 0x45, 0x04, 0xf3, + 0x41, 0x0f, 0x58, 0x44, 0x24, 0x04, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x04, + 0xf3, 0x41, 0x0f, 0x10, 0x45, 0x08, 0xf3, 0x41, 0x0f, 0x58, 0x44, 0x24, + 0x08, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x08, 0xf3, 0x41, 0x0f, 0x10, 0x45, + 0x0c, 0xf3, 0x41, 0x0f, 0x58, 0x44, 0x24, 0x0c, 0xf3, 0x41, 0x0f, 0x11, + 0x47, 0x0c + }; + copy_block(op_vaddfp_VD_V0_V1_code, 74); + inc_code_ptr(74); +} +#endif + +DEFINE_GEN(gen_op_vsubfp_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vsubfp_VD_V0_V1 +{ + static const uint8 op_vsubfp_VD_V0_V1_code[] = { + 0xf3, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf3, 0x41, 0x0f, 0x5c, 0x45, 0x00, + 0xf3, 0x41, 0x0f, 0x11, 0x07, 0xf3, 0x41, 0x0f, 0x10, 0x44, 0x24, 0x04, + 0xf3, 0x41, 0x0f, 0x5c, 0x45, 0x04, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x04, + 0xf3, 0x41, 0x0f, 0x10, 0x44, 0x24, 0x08, 0xf3, 0x41, 0x0f, 0x5c, 0x45, + 0x08, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x08, 0xf3, 0x41, 0x0f, 0x10, 0x44, + 0x24, 0x0c, 0xf3, 0x41, 0x0f, 0x5c, 0x45, 0x0c, 0xf3, 0x41, 0x0f, 0x11, + 0x47, 0x0c + }; + copy_block(op_vsubfp_VD_V0_V1_code, 74); + inc_code_ptr(74); +} +#endif + +DEFINE_GEN(gen_op_store_vect_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_vect_VD_T0 +{ + static const uint8 op_store_vect_VD_T0_code[] = { + 0x44, 0x89, 0xe1, 0x83, 0xe1, 0xf0, 0x41, 0x8b, 0x07, 0x0f, 0xc8, 0x89, + 0xca, + TRANS_RDX, + 0x89, 0x02, + 0x41, 0x8b, 0x57, 0x04, 0x0f, 0xca, 0x8d, 0x41, 0x04, 0x89, 0xc0, + TRANS_RAX, + 0x89, 0x10, + 0x41, 0x8b, 0x57, 0x08, 0x0f, 0xca, 0x8d, 0x41, 0x08, 0x89, 0xc0, + TRANS_RAX, + 0x89, 0x10, + 0x41, 0x8b, 0x47, 0x0c, 0x0f, 0xc8, 0x83, 0xc1, 0x0c, 0x89, 0xc9, 0x89, + 0x01 + }; + copy_block(op_store_vect_VD_T0_code, 167); + *(uint32_t *)(code_ptr() + 41) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 91) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 140) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 50) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 99) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 148) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(167); +} +#endif + +DEFINE_GEN(gen_op_store_word_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_word_VD_T0 +{ + static const uint8 op_store_word_VD_T0_code[] = { + 0x44, 0x89, 0xe0, 0x44, 0x89, 0xe2, 0xc1, 0xea, 0x02, 0x83, 0xe2, 0x03, + 0x41, 0x8b, 0x14, 0x97, 0x0f, 0xca, 0x83, 0xe0, 0xfc, + TRANS_RAX, + 0x89, 0x10, + }; + copy_block(op_store_word_VD_T0_code, 59); + *(uint32_t *)(code_ptr() + 45) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 53) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(59); +} +#endif + +DEFINE_GEN(gen_op_fmadd_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmadd_FD_F0_F1_F2 +{ + static const uint8 op_fmadd_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x58, 0x06, 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, + 0x00 + }; + copy_block(op_fmadd_FD_F0_F1_F2_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_fmsub_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmsub_FD_F0_F1_F2 +{ + static const uint8 op_fmsub_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x5c, 0x06, 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, + 0x00 + }; + copy_block(op_fmsub_FD_F0_F1_F2_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_fmadds_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmadds_FD_F0_F1_F2 +{ + static const uint8 op_fmadds_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x58, 0x06, 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x5a, + 0xc0, 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmadds_FD_F0_F1_F2_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_fmsubs_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmsubs_FD_F0_F1_F2 +{ + static const uint8 op_fmsubs_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x5c, 0x06, 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x5a, + 0xc0, 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fmsubs_FD_F0_F1_F2_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_fnmadd_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmadd_FD_F0_F1_F2 +{ + static const uint8 op_fnmadd_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x58, 0x06, 0x66, 0x0f, 0x57, 0x05, 0x0b, 0x1b, 0x00, + 0x00, 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fnmadd_FD_F0_F1_F2_code, 33); + static const uint8 literal16_1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + static uint8 *data_p_1 = NULL; + if (data_p_1 == NULL) + data_p_1 = copy_data(literal16_1, 16); + *(uint32_t *)(code_ptr() + 21) = (int32_t)((long)data_p_1 - (long)(code_ptr() + 21 + 4)); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_fnmsub_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmsub_FD_F0_F1_F2 +{ + static const uint8 op_fnmsub_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x5c, 0x06, 0x66, 0x0f, 0x57, 0x05, 0xe9, 0x1a, 0x00, + 0x00, 0xf2, 0x0f, 0x11, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fnmsub_FD_F0_F1_F2_code, 33); + static const uint8 literal16_1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + static uint8 *data_p_1 = NULL; + if (data_p_1 == NULL) + data_p_1 = copy_data(literal16_1, 16); + *(uint32_t *)(code_ptr() + 21) = (int32_t)((long)data_p_1 - (long)(code_ptr() + 21 + 4)); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_load_T0_LR_aligned,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_LR_aligned +{ + static const uint8 op_load_T0_LR_aligned_code[] = { + 0x44, 0x8b, 0xa5, 0xa4, 0x03, 0x00, 0x00, 0x41, 0x83, 0xe4, 0xfc + }; + copy_block(op_load_T0_LR_aligned_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_fnmadds_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmadds_FD_F0_F1_F2 +{ + static const uint8 op_fnmadds_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x58, 0x06, 0xf2, 0x0f, 0x5a, 0xc0, 0x0f, 0x57, 0x05, + 0xfc, 0x19, 0x00, 0x00, 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x85, + 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fnmadds_FD_F0_F1_F2_code, 40); + static const uint8 literal16_1[] = { + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + static uint8 *data_p_1 = NULL; + if (data_p_1 == NULL) + data_p_1 = copy_data(literal16_1, 16); + *(uint32_t *)(code_ptr() + 24) = (int32_t)((long)data_p_1 - (long)(code_ptr() + 24 + 4)); + inc_code_ptr(40); +} +#endif + +DEFINE_GEN(gen_op_fnmsubs_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmsubs_FD_F0_F1_F2 +{ + static const uint8 op_fnmsubs_FD_F0_F1_F2_code[] = { + 0xf2, 0x41, 0x0f, 0x10, 0x04, 0x24, 0xf2, 0x41, 0x0f, 0x59, 0x45, 0x00, + 0xf2, 0x41, 0x0f, 0x5c, 0x06, 0xf2, 0x0f, 0x5a, 0xc0, 0x0f, 0x57, 0x05, + 0x8a, 0x34, 0x00, 0x00, 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x85, + 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_fnmsubs_FD_F0_F1_F2_code, 40); + static const uint8 literal16_1[] = { + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + static uint8 *data_p_1 = NULL; + if (data_p_1 == NULL) + data_p_1 = copy_data(literal16_1, 16); + *(uint32_t *)(code_ptr() + 24) = (int32_t)((long)data_p_1 - (long)(code_ptr() + 24 + 4)); + inc_code_ptr(40); +} +#endif + +DEFINE_GEN(gen_op_load_T0_CTR_aligned,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_CTR_aligned +{ + static const uint8 op_load_T0_CTR_aligned_code[] = { + 0x44, 0x8b, 0xa5, 0xa8, 0x03, 0x00, 0x00, 0x41, 0x83, 0xe4, 0xfc + }; + copy_block(op_load_T0_CTR_aligned_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_load_double_FD_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_double_FD_T1_0 +{ + static const uint8 op_load_double_FD_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x48, 0x8b, 0x00, + 0x48, 0x0f, 0xc8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_load_double_FD_T1_0_code, 52); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(52); +} +#endif + +DEFINE_GEN(gen_op_load_single_FD_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_single_FD_T1_0 +{ + static const uint8 op_load_single_FD_T1_0_code[] = { + 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0x89, 0x44, 0x24, 0xf4, 0xf3, 0x0f, 0x10, 0x44, 0x24, 0xf4, + 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x44, 0x24, 0xf8, 0x48, 0x8b, + 0x44, 0x24, 0xf8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_load_single_FD_T1_0_code, 75); + *(uint32_t *)(code_ptr() + 27) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 35) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(75); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0000,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0000 +{ + static const uint8 op_prep_branch_bo_0000_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0xff, 0xc8, 0x41, 0x89, 0xc6, 0x89, + 0x85, 0xa8, 0x03, 0x00, 0x00, 0x31, 0xd2, 0x85, 0xc0, 0x74, 0x06, 0x45, + 0x85, 0xed, 0x0f, 0x94, 0xc2, 0x44, 0x0f, 0xb6, 0xea + }; + copy_block(op_prep_branch_bo_0000_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0001,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0001 +{ + static const uint8 op_prep_branch_bo_0001_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0xff, 0xc8, 0x41, 0x89, 0xc6, 0x89, + 0x85, 0xa8, 0x03, 0x00, 0x00, 0x31, 0xd2, 0x85, 0xc0, 0x75, 0x06, 0x45, + 0x85, 0xed, 0x0f, 0x94, 0xc2, 0x44, 0x0f, 0xb6, 0xea + }; + copy_block(op_prep_branch_bo_0001_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_001x,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_001x +{ + static const uint8 op_prep_branch_bo_001x_code[] = { + 0x45, 0x85, 0xed, 0x0f, 0x94, 0xc0, 0x44, 0x0f, 0xb6, 0xe8 + }; + copy_block(op_prep_branch_bo_001x_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0100,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0100 +{ + static const uint8 op_prep_branch_bo_0100_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0xff, 0xc8, 0x41, 0x89, 0xc6, 0x89, + 0x85, 0xa8, 0x03, 0x00, 0x00, 0x31, 0xd2, 0x85, 0xc0, 0x74, 0x06, 0x45, + 0x85, 0xed, 0x0f, 0x95, 0xc2, 0x44, 0x0f, 0xb6, 0xea + }; + copy_block(op_prep_branch_bo_0100_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0101,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0101 +{ + static const uint8 op_prep_branch_bo_0101_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0xff, 0xc8, 0x41, 0x89, 0xc6, 0x89, + 0x85, 0xa8, 0x03, 0x00, 0x00, 0x31, 0xd2, 0x85, 0xc0, 0x75, 0x06, 0x45, + 0x85, 0xed, 0x0f, 0x95, 0xc2, 0x44, 0x0f, 0xb6, 0xea + }; + copy_block(op_prep_branch_bo_0101_code, 33); + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_011x,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_011x +{ + static const uint8 op_prep_branch_bo_011x_code[] = { + 0x45, 0x85, 0xed, 0x0f, 0x95, 0xc0, 0x44, 0x0f, 0xb6, 0xe8 + }; + copy_block(op_prep_branch_bo_011x_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_1x00,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_1x00 +{ + static const uint8 op_prep_branch_bo_1x00_code[] = { + 0x8b, 0x95, 0xa8, 0x03, 0x00, 0x00, 0xff, 0xca, 0x41, 0x89, 0xd6, 0x89, + 0x95, 0xa8, 0x03, 0x00, 0x00, 0x45, 0x31, 0xed, 0x85, 0xd2, 0x41, 0x0f, + 0x95, 0xc5 + }; + copy_block(op_prep_branch_bo_1x00_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_1x01,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_1x01 +{ + static const uint8 op_prep_branch_bo_1x01_code[] = { + 0x8b, 0x95, 0xa8, 0x03, 0x00, 0x00, 0xff, 0xca, 0x41, 0x89, 0xd6, 0x89, + 0x95, 0xa8, 0x03, 0x00, 0x00, 0x45, 0x31, 0xed, 0x85, 0xd2, 0x41, 0x0f, + 0x94, 0xc5 + }; + copy_block(op_prep_branch_bo_1x01_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_1x1x,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_1x1x +{ + static const uint8 op_prep_branch_bo_1x1x_code[] = { + 0x41, 0xbd, 0x01, 0x00, 0x00, 0x00 + }; + copy_block(op_prep_branch_bo_1x1x_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_vmaddfp_VD_V0_V1_V2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vmaddfp_VD_V0_V1_V2 +{ + static const uint8 op_vmaddfp_VD_V0_V1_V2_code[] = { + 0xf3, 0x41, 0x0f, 0x10, 0x06, 0xf3, 0x41, 0x0f, 0x59, 0x04, 0x24, 0xf3, + 0x41, 0x0f, 0x58, 0x45, 0x00, 0xf3, 0x41, 0x0f, 0x11, 0x07, 0xf3, 0x41, + 0x0f, 0x10, 0x46, 0x04, 0xf3, 0x41, 0x0f, 0x59, 0x44, 0x24, 0x04, 0xf3, + 0x41, 0x0f, 0x58, 0x45, 0x04, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x04, 0xf3, + 0x41, 0x0f, 0x10, 0x46, 0x08, 0xf3, 0x41, 0x0f, 0x59, 0x44, 0x24, 0x08, + 0xf3, 0x41, 0x0f, 0x58, 0x45, 0x08, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x08, + 0xf3, 0x41, 0x0f, 0x10, 0x46, 0x0c, 0xf3, 0x41, 0x0f, 0x59, 0x44, 0x24, + 0x0c, 0xf3, 0x41, 0x0f, 0x58, 0x45, 0x0c, 0xf3, 0x41, 0x0f, 0x11, 0x47, + 0x0c + }; + copy_block(op_vmaddfp_VD_V0_V1_V2_code, 97); + inc_code_ptr(97); +} +#endif + +DEFINE_GEN(gen_op_compare_logical_T0_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_logical_T0_0 +{ + static const uint8 op_compare_logical_T0_0_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x89, 0xc2, 0x83, 0xca, 0x04, + 0x83, 0xc8, 0x02, 0x45, 0x85, 0xe4, 0x41, 0x89, 0xd4, 0x44, 0x0f, 0x44, + 0xe0 + }; + copy_block(op_compare_logical_T0_0_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_double_FD_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_double_FD_T1_T2 +{ + static const uint8 op_load_double_FD_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x48, 0x8b, 0x00, + 0x48, 0x0f, 0xc8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_load_double_FD_T1_T2_code, 53); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(53); +} +#endif + +DEFINE_GEN(gen_op_load_double_FD_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_double_FD_T1_im +{ + static const uint8 op_load_double_FD_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x48, 0x8b, 0x00, + 0x48, 0x0f, 0xc8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_load_double_FD_T1_im_code, 61); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(61); +} +#endif + +DEFINE_GEN(gen_op_load_single_FD_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_single_FD_T1_T2 +{ + static const uint8 op_load_single_FD_T1_T2_code[] = { + 0x43, 0x8d, 0x04, 0x2e, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0x89, 0x44, 0x24, 0xf4, 0xf3, 0x0f, 0x10, 0x44, 0x24, 0xf4, + 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x44, 0x24, 0xf8, 0x48, 0x8b, + 0x44, 0x24, 0xf8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_load_single_FD_T1_T2_code, 76); + *(uint32_t *)(code_ptr() + 28) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(76); +} +#endif + +DEFINE_GEN(gen_op_load_single_FD_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_single_FD_T1_im +{ + static const uint8 op_load_single_FD_T1_im_code[] = { + 0x44, 0x89, 0xea, 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x8b, 0x00, + 0x0f, 0xc8, 0x89, 0x44, 0x24, 0xf4, 0xf3, 0x0f, 0x10, 0x44, 0x24, 0xf4, + 0xf3, 0x0f, 0x5a, 0xc0, 0xf2, 0x0f, 0x11, 0x44, 0x24, 0xf8, 0x48, 0x8b, + 0x44, 0x24, 0xf8, 0x48, 0x89, 0x85, 0xa8, 0x08, 0x10, 0x00 + }; + copy_block(op_load_single_FD_T1_im_code, 84); + *(uint32_t *)(code_ptr() + 36) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 44) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 6) = (int32_t)((long)param1 - (long)(code_ptr() + 6 + 4)) + 0; + inc_code_ptr(84); +} +#endif + +DEFINE_GEN(gen_op_store_double_F0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_double_F0_T1_0 +{ + static const uint8 op_store_double_F0_T1_0_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x44, 0x89, 0xea, 0x48, 0x0f, 0xc8, + TRANS_RDX, + 0x48, 0x89, 0x02, + }; + copy_block(op_store_double_F0_T1_0_code, 54); + *(uint32_t *)(code_ptr() + 38) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 47) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(54); +} +#endif + +DEFINE_GEN(gen_op_store_single_F0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_single_F0_T1_0 +{ + static const uint8 op_store_single_F0_T1_0_code[] = { + 0x49, 0x8b, 0x0c, 0x24, 0x48, 0x89, 0xc8, 0x48, 0xc1, 0xe8, 0x34, 0x25, + 0xff, 0x07, 0x00, 0x00, 0x2d, 0x6a, 0x03, 0x00, 0x00, 0x83, 0xf8, 0x16, + 0x76, 0x1b, 0x48, 0xc1, 0xe9, 0x1d, 0x89, 0xca, 0x81, 0xe2, 0xff, 0xff, + 0xff, 0x3f, 0x48, 0xc1, 0xe9, 0x03, 0x89, 0xc8, 0x25, 0x00, 0x00, 0x00, + 0xc0, 0x09, 0xc2, 0xeb, 0x19, 0x48, 0x89, 0x4c, 0x24, 0xf0, 0xf2, 0x0f, + 0x10, 0x44, 0x24, 0xf0, 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x11, 0x44, + 0x24, 0xfc, 0x8b, 0x54, 0x24, 0xfc, 0x0f, 0xca, 0x44, 0x89, 0xe8, + TRANS_RAX, + 0x89, 0x10, + }; + copy_block(op_store_single_F0_T1_0_code, 121); + *(uint32_t *)(code_ptr() + 107) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 115) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(121); +} +#endif + +DEFINE_GEN(gen_op_vnmsubfp_VD_V0_V1_V2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vnmsubfp_VD_V0_V1_V2 +{ + static const uint8 op_vnmsubfp_VD_V0_V1_V2_code[] = { + 0xf3, 0x41, 0x0f, 0x10, 0x06, 0xf3, 0x41, 0x0f, 0x59, 0x04, 0x24, 0xf3, + 0x41, 0x0f, 0x5c, 0x45, 0x00, 0xf3, 0x0f, 0x10, 0x0d, 0xca, 0x29, 0x00, + 0x00, 0x0f, 0x57, 0xc1, 0xf3, 0x41, 0x0f, 0x11, 0x07, 0xf3, 0x41, 0x0f, + 0x10, 0x46, 0x04, 0xf3, 0x41, 0x0f, 0x59, 0x44, 0x24, 0x04, 0xf3, 0x41, + 0x0f, 0x5c, 0x45, 0x04, 0x0f, 0x57, 0xc1, 0xf3, 0x41, 0x0f, 0x11, 0x47, + 0x04, 0xf3, 0x41, 0x0f, 0x10, 0x46, 0x08, 0xf3, 0x41, 0x0f, 0x59, 0x44, + 0x24, 0x08, 0xf3, 0x41, 0x0f, 0x5c, 0x45, 0x08, 0x0f, 0x57, 0xc1, 0xf3, + 0x41, 0x0f, 0x11, 0x47, 0x08, 0xf3, 0x41, 0x0f, 0x10, 0x46, 0x0c, 0xf3, + 0x41, 0x0f, 0x59, 0x44, 0x24, 0x0c, 0xf3, 0x41, 0x0f, 0x5c, 0x45, 0x0c, + 0x0f, 0x57, 0xc1, 0xf3, 0x41, 0x0f, 0x11, 0x47, 0x0c + }; + copy_block(op_vnmsubfp_VD_V0_V1_V2_code, 117); + static const uint8 literal16_1[] = { + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + static uint8 *data_p_1 = NULL; + if (data_p_1 == NULL) + data_p_1 = copy_data(literal16_1, 16); + *(uint32_t *)(code_ptr() + 21) = (int32_t)((long)data_p_1 - (long)(code_ptr() + 21 + 4)); + inc_code_ptr(117); +} +#endif + +DEFINE_GEN(gen_op_compare_logical_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_logical_T0_T1 +{ + static const uint8 op_compare_logical_T0_T1_code[] = { + 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0x45, 0x39, 0xec, 0x73, 0x09, + 0x41, 0x89, 0xd4, 0x41, 0x83, 0xcc, 0x08, 0xeb, 0x12, 0x89, 0xd0, 0x83, + 0xc8, 0x04, 0x83, 0xca, 0x02, 0x45, 0x39, 0xec, 0x41, 0x89, 0xc4, 0x44, + 0x0f, 0x46, 0xe2 + }; + copy_block(op_compare_logical_T0_T1_code, 39); + inc_code_ptr(39); +} +#endif + +DEFINE_GEN(gen_op_compare_logical_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_logical_T0_im +{ + static const uint8 op_compare_logical_T0_im_code[] = { + 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0x8d, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x39, 0xf4, 0x73, 0x09, 0x41, 0x89, 0xd4, 0x41, 0x83, 0xcc, + 0x08, 0xeb, 0x12, 0x89, 0xd0, 0x83, 0xc8, 0x04, 0x83, 0xca, 0x02, 0x41, + 0x39, 0xf4, 0x41, 0x89, 0xc4, 0x44, 0x0f, 0x46, 0xe2 + }; + copy_block(op_compare_logical_T0_im_code, 45); + *(uint32_t *)(code_ptr() + 9) = (int32_t)((long)param1 - (long)(code_ptr() + 9 + 4)) + 0; + inc_code_ptr(45); +} +#endif + +DEFINE_GEN(gen_op_store_double_F0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_double_F0_T1_T2 +{ + static const uint8 op_store_double_F0_T1_T2_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x43, 0x8d, 0x14, 0x2e, 0x48, 0x0f, 0xc8, + TRANS_RDX, + 0x48, 0x89, 0x02, + }; + copy_block(op_store_double_F0_T1_T2_code, 55); + *(uint32_t *)(code_ptr() + 39) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 48) = (uint32_t)(uintptr)gZeroPage; + inc_code_ptr(55); +} +#endif + +DEFINE_GEN(gen_op_store_double_F0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_double_F0_T1_im +{ + static const uint8 op_store_double_F0_T1_im_code[] = { + 0x49, 0x8b, 0x04, 0x24, 0x44, 0x89, 0xe9, 0x48, 0x0f, 0xc8, 0x48, 0x8d, + 0x15, 0x00, 0x00, 0x00, 0x00, + ADD_RDX_RCX, + TRANS_RDX, + 0x48, 0x89, 0x02, + }; + copy_block(op_store_double_F0_T1_im_code, 63); + *(uint32_t *)(code_ptr() + 47) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 56) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 13) = (int32_t)((long)param1 - (long)(code_ptr() + 13 + 4)) + 0; + inc_code_ptr(63); +} +#endif + +DEFINE_GEN(gen_op_store_single_F0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_single_F0_T1_T2 +{ + static const uint8 op_store_single_F0_T1_T2_code[] = { + 0x49, 0x8b, 0x14, 0x24, 0x48, 0x89, 0xd0, 0x48, 0xc1, 0xe8, 0x34, 0x25, + 0xff, 0x07, 0x00, 0x00, 0x2d, 0x6a, 0x03, 0x00, 0x00, 0x83, 0xf8, 0x16, + 0x76, 0x1b, 0x48, 0xc1, 0xea, 0x1d, 0x89, 0xd1, 0x81, 0xe1, 0xff, 0xff, + 0xff, 0x3f, 0x48, 0xc1, 0xea, 0x03, 0x89, 0xd0, 0x25, 0x00, 0x00, 0x00, + 0xc0, 0x09, 0xc1, 0xeb, 0x19, 0x48, 0x89, 0x54, 0x24, 0xf0, 0xf2, 0x0f, + 0x10, 0x44, 0x24, 0xf0, 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x11, 0x44, + 0x24, 0xfc, 0x8b, 0x4c, 0x24, 0xfc, 0x44, 0x89, 0xf0, 0x0f, 0xc9, 0x44, + 0x01, 0xe8, 0x89, 0x08 + }; + copy_block(op_store_single_F0_T1_T2_code, 88); + inc_code_ptr(88); +} +#endif + +DEFINE_GEN(gen_op_store_single_F0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_single_F0_T1_im +{ + static const uint8 op_store_single_F0_T1_im_code[] = { + 0x49, 0x8b, 0x14, 0x24, 0x48, 0x89, 0xd0, 0x48, 0xc1, 0xe8, 0x34, 0x25, + 0xff, 0x07, 0x00, 0x00, 0x2d, 0x6a, 0x03, 0x00, 0x00, 0x83, 0xf8, 0x16, + 0x76, 0x1b, 0x48, 0xc1, 0xea, 0x1d, 0x89, 0xd1, 0x81, 0xe1, 0xff, 0xff, + 0xff, 0x3f, 0x48, 0xc1, 0xea, 0x03, 0x89, 0xd0, 0x25, 0x00, 0x00, 0x00, + 0xc0, 0x09, 0xc1, 0xeb, 0x19, 0x48, 0x89, 0x54, 0x24, 0xf0, 0xf2, 0x0f, + 0x10, 0x44, 0x24, 0xf0, 0xf2, 0x0f, 0x5a, 0xc0, 0xf3, 0x0f, 0x11, 0x44, + 0x24, 0xfc, 0x8b, 0x4c, 0x24, 0xfc, 0x0f, 0xc9, 0x44, 0x89, 0xe8, 0x48, + 0x8d, 0x15, 0x00, 0x00, 0x00, 0x00, + ADD_RAX_RDX, + TRANS_RAX, + 0x89, 0x08, + }; + copy_block(op_store_single_F0_T1_im_code, 130); + *(uint32_t *)(code_ptr() + 116) = (uint32_t)(uintptr)gKernelData; + *(uint32_t *)(code_ptr() + 124) = (uint32_t)(uintptr)gZeroPage; + *(uint32_t *)(code_ptr() + 86) = (int32_t)((long)param1 - (long)(code_ptr() + 86 + 4)) + 0; + inc_code_ptr(130); +} +#endif + +DEFINE_GEN(gen_op_emms,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_emms +{ + static const uint8 op_emms_code[] = { + 0x0f, 0x77 + }; + copy_block(op_emms_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_inc_PC,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_inc_PC +{ + static const uint8 op_inc_PC_code[] = { + 0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x85, 0xac, 0x03, 0x00, + 0x00 + }; + copy_block(op_inc_PC_code, 13); + *(uint32_t *)(code_ptr() + 3) = (int32_t)((long)param1 - (long)(code_ptr() + 3 + 4)) + 0; + inc_code_ptr(13); +} +#endif + +#undef DEFINE_CST +#undef DEFINE_GEN diff --git a/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops.hpp b/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops.hpp index 22791f3d8..5ea317c56 100644 --- a/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops.hpp +++ b/SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops.hpp @@ -1,5 +1,9 @@ #if defined(__x86_64__) +#ifdef __APPLE__ + #include "ppc-dyngen-ops-x86_64_macos.hpp" +#else #include "ppc-dyngen-ops-x86_64.hpp" +#endif #elif defined(__i386__) #include "ppc-dyngen-ops-x86_32.hpp" #else diff --git a/SheepShaver/src/Unix/dyngen_precompiled/ppc-execute-impl.cpp b/SheepShaver/src/Unix/dyngen_precompiled/ppc-execute-impl.cpp index 07706ac9d..89d2c3296 100644 --- a/SheepShaver/src/Unix/dyngen_precompiled/ppc-execute-impl.cpp +++ b/SheepShaver/src/Unix/dyngen_precompiled/ppc-execute-impl.cpp @@ -57,6 +57,8 @@ template void powerpc_cpu::execute_fp_arith(uint32); template void powerpc_cpu::execute_fp_arith(uint32); template void powerpc_cpu::execute_fp_round(uint32); +template void powerpc_cpu::execute_fp_arith(uint32); +template void powerpc_cpu::execute_fp_arith(uint32); template void powerpc_cpu::execute_fp_arith(uint32); template void powerpc_cpu::execute_fp_arith(uint32); template void powerpc_cpu::execute_fp_arith(uint32); @@ -258,7 +260,7 @@ template void powerpc_cpu::execute_vector_arith, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32); template void powerpc_cpu::execute_vector_arith, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32); template void powerpc_cpu::execute_vector_arith, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32); -template void powerpc_cpu::execute_vector_arith, 0 >(uint32); +template void powerpc_cpu::execute_vector_arith, 0 >(uint32); template void powerpc_cpu::execute_vector_arith, 0 >(uint32); template void powerpc_cpu::execute_vector_shift<-1>(uint32); template void powerpc_cpu::execute_vector_arith, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32); diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp old mode 100644 new mode 100755 index b6de430bd..178c9f75e --- 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 @@ -124,22 +122,13 @@ #ifdef USE_SDL #include -#endif - -#ifndef USE_SDL_VIDEO -#include +#include #endif #ifdef ENABLE_GTK #include #endif -#ifdef ENABLE_XF86_DGA -#include -#include -#include -#endif - #ifdef ENABLE_MON #include "mon.h" #endif @@ -174,33 +163,34 @@ 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) - -// 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 +#if defined(__APPLE__) && defined(__x86_64__) +uint8 gZeroPage[0x3000], gKernelData[0x2000]; #endif +// Global variables 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 @@ -334,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 */ @@ -396,6 +381,8 @@ static void get_system_info(void) #if EMULATED_PPC PVR = 0x000c0000; // Default: 7400 (with AltiVec) + int pref_cpu_clock = PrefsFindInt32("cpuclock"); + if (pref_cpu_clock) CPUClockSpeed = 1000000 * pref_cpu_clock; #elif defined(__APPLE__) && defined(__MACH__) proc_file = popen("ioreg -c IOPlatformDevice", "r"); if (proc_file) { @@ -597,7 +584,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) { @@ -669,8 +656,10 @@ static bool install_signal_handlers(void) } #ifdef USE_SDL -static bool init_sdl() -{ + +static std::string sdl_vmdir; + +static bool init_sdl(){ int sdl_flags = 0; #ifdef USE_SDL_VIDEO sdl_flags |= SDL_INIT_VIDEO; @@ -696,6 +685,19 @@ static bool init_sdl() } atexit(SDL_Quit); +#if SDL_VERSION_ATLEAST(2,0,0) + const int SDL_EVENT_TIMEOUT = 100; + for (int i = 0; i < SDL_EVENT_TIMEOUT; i++) { + SDL_Event event; + SDL_PollEvent(&event); + if (event.type == SDL_DROPFILE) { + sdl_vmdir = event.drop.file; + break; + } + SDL_Delay(1); + } +#endif + // Don't let SDL catch SIGINT and SIGTERM signals signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); @@ -703,8 +705,7 @@ static bool init_sdl() } #endif -int main(int argc, char **argv) -{ +int main(int argc, char **argv){ char str[256]; bool memory_mapped_from_zero, ram_rom_areas_contiguous; const char *vmdir = NULL; @@ -714,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 @@ -728,16 +728,33 @@ int main(int argc, char **argv) #endif #endif +#if __MACOSX__ + extern void set_current_directory(); + set_current_directory(); +#endif + +#ifdef USE_SDL + // Initialize SDL system + if (!init_sdl()) + goto quit; +#if SDL_VERSION_ATLEAST(2,0,0) + if (valid_vmdir(sdl_vmdir.c_str())) { + vmdir = sdl_vmdir.c_str(); + printf("Using %s as vmdir.\n", vmdir); + if (chdir(vmdir)) { + printf("Failed to chdir to %s. Good bye.", vmdir); + exit(1); + } + } +#endif +#endif + // Parse command line arguments for (int i=1; ied; KernelDataAddr = KERNEL_DATA_BASE; D(bug("Kernel Data at %p (%08x)\n", kernel_data, KERNEL_DATA_BASE)); D(bug("Emulator Data at %p (%08x)\n", emulator_data, KERNEL_DATA_BASE + offsetof(KernelData, ed))); - +#if 0 // Create area for DR Cache if (vm_mac_acquire_fixed(DR_EMULATOR_BASE, DR_EMULATOR_SIZE) < 0) { sprintf(str, GetString(STR_DR_EMULATOR_MMAP_ERR), strerror(errno)); @@ -886,19 +894,16 @@ int main(int argc, char **argv) #endif DRCacheAddr = DR_CACHE_BASE; D(bug("DR Cache at %p\n", DRCacheAddr)); - - // Create area for SheepShaver data - if (!SheepMem::Init()) { - sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno)); - ErrorAlert(str); - goto quit; - } +#endif // Create area for Mac RAM RAMSize = PrefsFindInt32("ramsize"); - if (RAMSize < 8*1024*1024) { + if (RAMSize <= 1000) { + RAMSize *= 1024 * 1024; + } + if (RAMSize < 16 * 1024 * 1024) { WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 8*1024*1024; + RAMSize = 16 * 1024 * 1024; } memory_mapped_from_zero = false; ram_rom_areas_contiguous = false; @@ -923,7 +928,7 @@ int main(int argc, char **argv) #if REAL_ADDRESSING // Allocate RAM at any address. Since ROM must be higher than RAM, allocate the RAM // and ROM areas contiguously, plus a little extra to allow for ROM address alignment. - RAMBaseHost = vm_mac_acquire(RAMSize + ROM_AREA_SIZE + ROM_ALIGNMENT); + RAMBaseHost = vm_mac_acquire(RAMSize + ROM_AREA_SIZE + ROM_ALIGNMENT + SIG_STACK_SIZE); if (RAMBaseHost == VM_MAP_FAILED) { sprintf(str, GetString(STR_RAM_ROM_MMAP_ERR), strerror(errno)); ErrorAlert(str); @@ -931,7 +936,9 @@ int main(int argc, char **argv) } RAMBase = Host2MacAddr(RAMBaseHost); ROMBase = (RAMBase + RAMSize + ROM_ALIGNMENT -1) & -ROM_ALIGNMENT; - ROMBaseHost = Mac2HostAddr(ROMBase); + ROMBaseHost = RAMBaseHost + ROMBase - RAMBase; + ROMEnd = RAMBase + RAMSize + ROM_AREA_SIZE + ROM_ALIGNMENT; + ram_rom_areas_contiguous = true; #else if (vm_mac_acquire_fixed(RAM_BASE, RAMSize) < 0) { @@ -957,16 +964,17 @@ 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) < 0) { + if (vm_mac_acquire_fixed(ROM_BASE, ROM_AREA_SIZE + SIG_STACK_SIZE) < 0) { sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } ROMBase = ROM_BASE; ROMBaseHost = Mac2HostAddr(ROMBase); + ROMEnd = ROMBase + ROM_AREA_SIZE; } #if !EMULATED_PPC if (vm_protect(ROMBaseHost, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) { @@ -983,6 +991,23 @@ 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)); + ErrorAlert(str); + goto quit; + } + // Load Mac ROM if (!load_mac_rom()) goto quit; @@ -1121,6 +1146,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); @@ -1136,12 +1165,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) @@ -1442,7 +1465,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); @@ -1468,7 +1491,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 -- @@ -1485,7 +1508,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); @@ -1634,8 +1657,8 @@ void sigusr2_handler(int sig, siginfo_t *sip, void *scp) switch (ReadMacInt32(XLM_RUN_MODE)) { case MODE_68K: // 68k emulator active, trigger 68k interrupt level 1 - WriteMacInt16(ntohl(kernel_data->v[0x67c >> 2]), 1); - r->cr() |= ntohl(kernel_data->v[0x674 >> 2]); + WriteMacInt16(ReadMacInt32(0x67c), 1); + r->cr() |= ReadMacInt32(0x674); break; #if INTERRUPTS_IN_NATIVE_MODE @@ -1645,10 +1668,10 @@ 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(ntohl(kernel_data->v[0x67c >> 2]), 1); - WriteMacInt32(ntohl(kernel_data->v[0x658 >> 2]) + 0xdc, ReadMacInt32(ntohl(kernel_data->v[0x658 >> 2]) + 0xdc) | ntohl(kernel_data->v[0x674 >> 2])); + WriteMacInt16(ReadMacInt32(0x67c), 1); + WriteMacInt32(ReadMacInt32(0x658) + 0xdc, ReadMacInt32(ReadMacInt32(0x658) + 0xdc) | ReadMacInt32(0x674)); // Execute nanokernel interrupt routine (this will activate the 68k emulator) DisableInterrupt(); @@ -1716,7 +1739,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); @@ -1747,19 +1770,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; @@ -1767,7 +1790,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; @@ -1838,7 +1861,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 @@ -1894,7 +1917,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) || @@ -2144,6 +2167,7 @@ rti:; } #endif +extern int vm_init_reserved(void *hostAddress); /* * Helpers to share 32-bit addressable data with MacOS @@ -2155,10 +2179,18 @@ bool SheepMem::Init(void) page_size = getpagesize(); // Allocate SheepShaver globals - proc = base; - if (vm_mac_acquire_fixed(base, size) < 0) +#ifdef NATMEM_OFFSET + if (vm_mac_acquire_fixed(ROM_BASE + ROM_AREA_SIZE + SIG_STACK_SIZE, size) < 0) return false; - + uint8 *adr = Mac2HostAddr(ROM_BASE + ROM_AREA_SIZE + SIG_STACK_SIZE); + if (vm_init_reserved(adr + size) < 0) + return false; +#else + uint8 *adr = vm_mac_acquire(size); +#endif + if (adr == VM_MAP_FAILED) + return false; + proc = base = Host2MacAddr(adr); // Allocate page with all bits set to 0, right in the middle // This is also used to catch undesired overlaps between proc and data areas zero_page = proc + (size / 2); @@ -2167,10 +2199,7 @@ bool SheepMem::Init(void) return false; #if EMULATED_PPC - // Allocate alternate stack for PowerPC interrupt routine - sig_stack = base + size; - if (vm_mac_acquire_fixed(sig_stack, SIG_STACK_SIZE) < 0) - return false; + sig_stack = ROMEnd; #endif data = base + size; @@ -2233,20 +2262,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; } @@ -2257,20 +2284,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; } @@ -2280,7 +2305,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..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 @@ -711,9 +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; // Hide/show graphics widgets static void hide_show_graphics_widgets(void) @@ -757,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 @@ -772,8 +766,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 +777,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"); @@ -865,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 @@ -976,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/Unix/prefs_unix.cpp b/SheepShaver/src/Unix/prefs_unix.cpp index 7f89a107b..a4380d100 100644 --- a/SheepShaver/src/Unix/prefs_unix.cpp +++ b/SheepShaver/src/Unix/prefs_unix.cpp @@ -37,10 +37,10 @@ prefs_desc platform_prefs_items[] = { {"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"}, {"dsp", TYPE_STRING, false, "audio output (dsp) device name"}, {"mixer", TYPE_STRING, false, "audio mixer device name"}, -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, +#ifdef USE_SDL_VIDEO + {"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"}, +#endif {NULL, TYPE_END, false, NULL} // End of list }; @@ -132,9 +132,6 @@ void AddPlatformPrefsDefaults(void) #else PrefsReplaceString("dsp", "/dev/dsp"); PrefsReplaceString("mixer", "/dev/mixer"); -#endif -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - PrefsAddBool("ignoresegv", false); #endif PrefsAddBool("idlewait", true); } diff --git a/SheepShaver/src/Unix/sysdeps.h b/SheepShaver/src/Unix/sysdeps.h index a3cb32782..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 @@ -149,7 +145,7 @@ typedef long int32; #error "No 4 byte type, you lose." #endif #if SIZEOF_LONG == 8 -typedef unsigned long uint64; +typedef uint64_t uint64; typedef long int64; #define VAL64(a) (a ## l) #define UVAL64(a) (a ## ul) @@ -429,7 +425,7 @@ typedef struct timeval tm_time_t; // Timing functions extern uint64 GetTicks_usec(void); -extern void Delay_usec(uint32 usec); +extern void Delay_usec(uint64 usec); #ifdef HAVE_PTHREADS // Setup pthread attributes 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 -} diff --git a/SheepShaver/src/Windows/Makefile.in b/SheepShaver/src/Windows/Makefile.in index edd28f596..9ca6f762d 100755 --- a/SheepShaver/src/Windows/Makefile.in +++ b/SheepShaver/src/Windows/Makefile.in @@ -29,6 +29,8 @@ SLIRP_SRCS = \ ../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=$(OBJ_DIR)/slirp-%.o) +USE_BINCUE = @USE_BINCUE@ + LN_S = @LN_S@ WINDRES = @WINDRES@ CC = @CC@ @@ -37,12 +39,15 @@ CFLAGS = @CFLAGS@ $(SDL_CFLAGS) CXXFLAGS = @CXXFLAGS@ $(SDL_CFLAGS) CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../slirp DEFS = @DEFS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -lwsock32 -liphlpapi +LDFLAGS = @LDFLAGS@ -Wl,-Bstatic +#TODO remove pthread part of that if irrelevant +LIBS = @LIBS@ -lws2_32 -lwsock32 -liphlpapi CPUSRCS = @CPUSRCS@ +EXTRASRCS = @EXTRASRCS@ PERL = @PERL@ USE_DYNGEN = @USE_DYNGEN@ +USE_PREGENERATED_DYNGEN = @USE_PREGENERATED_DYNGEN@ DYNGENSRCS = @DYNGENSRCS@ DYNGEN_CC = $(CXX) DYNGEN_OP_FLAGS = @DYNGEN_OP_FLAGS@ @@ -54,7 +59,7 @@ HOST_CXXFLAGS = -O2 HOST_LDFLAGS = ## Files -UNIXSRCS = vm_alloc.cpp vm_alloc.h sigsegv.cpp sigsegv.h video_vosf.h video_blit.cpp video_blit.h +XPLATSRCS = vm_alloc.cpp vm_alloc.h sigsegv.cpp sigsegv.h video_vosf.h video_blit.cpp video_blit.h ROUTERSRCS = router/arp.cpp router/dump.cpp router/dynsockets.cpp router/ftp.cpp \ router/icmp.cpp router/mib/interfaces.cpp router/iphelp.cpp router/ipsocket.cpp \ @@ -65,16 +70,17 @@ 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 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 \ - ../dummy/prefs_editor_dummy.cpp clip_windows.cpp util_windows.cpp kernel_windows.cpp \ + ../dummy/prefs_editor_dummy.cpp clip_windows.cpp util_windows.cpp \ vm_alloc.cpp sigsegv.cpp posix_emu.cpp SheepShaver.rc \ - $(CPUSRCS) $(ROUTERSRCS) $(SLIRP_OBJS) + $(CPUSRCS) $(ROUTERSRCS) $(EXTRASRCS) $(SLIRP_OBJS) UI_SRCS = ../prefs.cpp prefs_windows.cpp prefs_editor_gtk.cpp xpram_windows.cpp \ ../prefs_items.cpp ../user_strings.cpp user_strings_windows.cpp util_windows.cpp \ + ../dummy/prefs_dummy.cpp \ b2ether/packet32.cpp SheepShaverGUI.rc UI_APP = SheepShaverGUI.exe @@ -94,7 +100,7 @@ endif all: $(PROGS) -$(UNIXSRCS): %: ../Unix/% +$(XPLATSRCS): %: ../CrossPlatform/% $(LN_S) $< $@ OBJ_DIR = obj @@ -123,18 +129,19 @@ SRC_PATHS += $(sort $(foreach file, $(SRCS), $(dir $(file)))) VPATH := VPATH += $(addprefix :, $(subst ,:, $(filter-out $($(subst, :, ,$(VPATH))), $(SRC_PATHS)))) -$(APP): $(UNIXSRCS) $(OBJ_DIR) $(OBJS) +$(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS) $(CXX) -o $(APP) $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS) -$(UI_APP): $(UNIXSRCS) $(OBJ_DIR) $(UI_OBJS) - $(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin +$(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS) + $(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) -Wl,-Bdynamic $(GTK_LIBS) -Wl,-Bstatic -mwindows -static-libgcc mostlyclean: rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak -clean: mostlyclean - rm -f $(UNIXSRCS) - rm -f dyngen basic-dyngen-ops.hpp ppc-dyngen-ops.hpp ppc-execute-impl.cpp +clean: mostlyclean dyngenclean + rm -f $(XPLATSRCS) +dyngenclean: + rm -f $(DYNGEN) basic-dyngen-ops.hpp ppc-dyngen-ops.hpp ppc-execute-impl.cpp distclean: clean rm -rf $(OBJ_DIR) @@ -162,7 +169,7 @@ $(OBJ_DIR)/%.o : %.S $(AS) $(ASFLAGS) -o $@ $*.out.s rm $*.out.s $(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp - $(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@ + $(CXX) -O2 -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@ # Windows resources $(OBJ_DIR)/%.o: %.rc @@ -175,21 +182,35 @@ DYNGEN = dyngen.exe ifeq ($(USE_DYNGEN),yes) DYNGENDEPS = basic-dyngen-ops.hpp ppc-dyngen-ops.hpp +dyngendeps: $(DYNGENDEPS) + +### + +$(OBJ_DIR)/basic-dyngen.o: basic-dyngen-ops.hpp +$(OBJ_DIR)/ppc-dyngen.o: ppc-dyngen-ops.hpp +ifeq ($(USE_PREGENERATED_DYNGEN),yes) + +basic-dyngen-ops.hpp: cygwin_precompiled_dyngen/basic-dyngen-ops.hpp + cp -f $< $@ +ppc-dyngen-ops.hpp: cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp + cp -f $< $@ + +else +# Only GCC is supported for generating synthetic opcodes $(DYNGEN): $(DYNGENOBJS) $(HOST_CXX) -o $@ $(LDFLAGS) $(DYNGENOBJS) -$(OBJ_DIR)/basic-dyngen.o: basic-dyngen-ops.hpp $(OBJ_DIR)/basic-dyngen-ops.o: $(kpxsrcdir)/cpu/jit/basic-dyngen-ops.cpp $(DYNGEN_CC) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(DYNGEN_OP_FLAGS) -c $< -o $@ basic-dyngen-ops.hpp: $(OBJ_DIR)/basic-dyngen-ops.o $(DYNGEN) ./$(DYNGEN) -o $@ $< -$(OBJ_DIR)/ppc-dyngen.o: ppc-dyngen-ops.hpp $(OBJ_DIR)/ppc-dyngen-ops.o: $(kpxsrcdir)/cpu/ppc/ppc-dyngen-ops.cpp basic-dyngen-ops.hpp $(DYNGEN_CC) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) $(DYNGEN_OP_FLAGS) -c $< -o $@ ppc-dyngen-ops.hpp: $(OBJ_DIR)/ppc-dyngen-ops.o $(DYNGEN) ./$(DYNGEN) -o $@ $< +endif $(OBJ_DIR)/sheepshaver_glue.o $(OBJ_DIR)/ppc-cpu.o $(OBJ_DIR)/ppc-decode.o $(OBJ_DIR)/ppc-translate.o $(OBJ_DIR)/ppc-jit.o: basic-dyngen-ops.hpp ppc-dyngen-ops.hpp endif diff --git a/SheepShaver/src/Windows/configure.ac b/SheepShaver/src/Windows/configure.ac old mode 100755 new mode 100644 index dcb4bfe03..b45dc2876 --- 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) @@ -14,6 +14,10 @@ AC_CANONICAL_TARGET dnl Options. AC_ARG_ENABLE(jit, [ --enable-jit enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes]) AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes]) +AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=yes]) + +AC_ARG_WITH(bincue, + AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode])) dnl Checks for programs. AC_PROG_CC @@ -84,7 +88,7 @@ AC_CACHE_CHECK([whether VirtualProtect works], #define HAVE_WIN32_VM 1 #define CONFIGURE_TEST_VM_MAP #define TEST_VM_PROT_$test_def - #include "../Unix/vm_alloc.cpp" + #include "../CrossPlatform/vm_alloc.cpp" ], ac_cv_VirtualProtect_works=no, rm -f core, dnl When cross-compiling, assume it works ac_cv_VirtualProtect_works="yes" @@ -94,7 +98,7 @@ AC_CACHE_CHECK([whether VirtualProtect works], #define HAVE_WIN32_VM 1 #define CONFIGURE_TEST_VM_MAP #define TEST_VM_PROT_RDWR_WRITE - #include "../Unix/vm_alloc.cpp" + #include "../CrossPlatform/vm_alloc.cpp" ], , ac_cv_VirtualProtect_works=no, dnl When cross-compiling, assume it works ac_cv_VirtualProtect_works="yes" @@ -116,8 +120,8 @@ AC_CACHE_CHECK([whether your system supports Windows exceptions], AC_TRY_RUN([ #define HAVE_WIN32_EXCEPTIONS 1 #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../Unix/vm_alloc.cpp" - #include "../Unix/sigsegv.cpp" + #include "../CrossPlatform/vm_alloc.cpp" + #include "../CrossPlatform/sigsegv.cpp" ], ac_cv_have_win32_exceptions=yes, ac_cv_have_win32_exceptions=no, @@ -141,8 +145,8 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler], AC_TRY_RUN([ #define HAVE_SIGSEGV_SKIP_INSTRUCTION 1 #define CONFIGURE_TEST_SIGSEGV_RECOVERY - #include "../Unix/vm_alloc.cpp" - #include "../Unix/sigsegv.cpp" + #include "../CrossPlatform/vm_alloc.cpp" + #include "../CrossPlatform/sigsegv.cpp" ], ac_cv_have_skip_instruction=yes, ac_cv_have_skip_instruction=no, dnl When cross-compiling, assume it works ac_cv_have_skip_instruction="yes" @@ -153,8 +157,12 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler], AC_TRANSLATE_DEFINE(HAVE_SIGSEGV_SKIP_INSTRUCTION, "$ac_cv_have_skip_instruction", [Define if we can ignore the fault (instruction skipping in SIGSEGV handler).]) -dnl We really want VOSF (Video on SEGV Signals) screen updates acceleration -AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.]) +dnl Enable VOSF screen updates with this feature is requested +if [[ "x$WANT_VOSF" = "xyes" ]]; then + AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.]) +else + WANT_VOSF=no +fi dnl Check for GCC 2.7 or higher. HAVE_GCC27=no @@ -181,10 +189,33 @@ if [[ "x$HAVE_GCC30" = "xyes" ]]; then AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing], ac_cv_gcc_no_strict_aliasing, [ AC_TRY_COMPILE([],[], - [ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")], + [ac_cv_gcc_no_strict_aliasing=yes], [ac_cv_gcc_no_strict_aliasing=no]) ]) CFLAGS="$SAVED_CFLAGS" + if test "x$ac_cv_gcc_no_strict_aliasing" = xyes; then + AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing") + fi +fi + +case $host_os in +cygwin) + CFLAGS="$CFLAGS -mwin32" + CXXFLAGS="$CXXFLAGS -mwin32" + ;; +esac + +dnl BINCUE +AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no]) +AS_IF([test "x$have_bincue" = "xyes" ], [ + DEFINES="$DEFINES -DBINCUE" + CPPFLAGS="$CPPFLAGS -DBINCUE" + AC_SUBST(USE_BINCUE, yes) +], [AC_SUBST(USE_BINCUE, no)]) + +dnl BINCUE overrides +if [[ "x$have_bincue" = "xyes" ]]; then + EXTRASRCS="$EXTRASRCS bincue.cpp" fi dnl CPU emulator sources @@ -200,6 +231,7 @@ CPPFLAGS="$CPPFLAGS -I../kpx_cpu/include -I../kpx_cpu/src" dnl Enable JIT compiler, if possible USE_DYNGEN="no" +USE_PREGENERATED_DYNGEN="no" if [[ "x$WANT_JIT" = "xyes" ]]; then case $host_cpu in i?86) @@ -211,6 +243,16 @@ if [[ "x$WANT_JIT" = "xyes" ]]; then fi ;; esac + + case $host_os in + cygwin) + USE_PREGENERATED_DYNGEN="no" + ;; + *) + USE_PREGENERATED_DYNGEN="yes" + ;; + esac + USE_DYNGEN="yes" DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -finline-limit=10000 -g0" if [[ "x$HAVE_GCC30" = "xyes" ]]; then @@ -233,10 +275,11 @@ dnl Use the dummy prefs file. CPUSRCS="$CPUSRCS ../dummy/prefs_dummy.cpp" dnl We really want SDL for now -AC_CHECK_TOOL(sdl_config, sdl-config, [AC_MSG_ERROR([Sorry, you currently need SDL for this port])]) +AC_CHECK_TOOL(sdl_config, sdl2-config, no) +AS_IF([test "x$sdl_config" = xno], [AC_MSG_ERROR([Sorry, you currently need SDL for this port])]) SDL_CFLAGS=`$sdl_config --cflags` AC_SUBST(SDL_CFLAGS) -SDL_LIBS=`$sdl_config --libs` +SDL_LIBS=`$sdl_config --static-libs` AC_SUBST(SDL_LIBS) AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support]) @@ -251,9 +294,11 @@ fi dnl Generate Makefile. AC_SUBST(PERL) AC_SUBST(USE_DYNGEN) +AC_SUBST(USE_PREGENERATED_DYNGEN) AC_SUBST(DYNGENSRCS) AC_SUBST(DYNGEN_OP_FLAGS) AC_SUBST(CPUSRCS) +AC_SUBST(EXTRASRCS) AC_OUTPUT([Makefile]) dnl Print summary. @@ -262,5 +307,7 @@ echo SheepShaver configuration summary: echo echo Enable JIT compiler .............. : $WANT_JIT echo GTK user interface ............... : $WANT_GTK +echo BINCUE support ......................... : $have_bincue +echo Enable VOSF ...................... : $WANT_VOSF echo echo "Configuration done. Now type \"make\"." diff --git a/SheepShaver/src/Windows/cygwin_precompiled_dyngen/basic-dyngen-ops.hpp b/SheepShaver/src/Windows/cygwin_precompiled_dyngen/basic-dyngen-ops.hpp new file mode 100644 index 000000000..de8b740f4 --- /dev/null +++ b/SheepShaver/src/Windows/cygwin_precompiled_dyngen/basic-dyngen-ops.hpp @@ -0,0 +1,1684 @@ +#ifndef DEFINE_CST +#define DEFINE_CST(NAME, VALUE) +#endif +DEFINE_GEN(gen_op_mov_ad_A0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_ad_A0_im +{ + static const uint8 op_mov_ad_A0_im_code[] = { + 0xbb, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_ad_A0_im_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_mov_ad_A1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_ad_A1_im +{ + static const uint8 op_mov_ad_A1_im_code[] = { + 0xbe, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_ad_A1_im_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_mov_ad_A2_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_ad_A2_im +{ + static const uint8 op_mov_ad_A2_im_code[] = { + 0xbf, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_ad_A2_im_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_im +{ + static const uint8 op_mov_32_T0_im_code[] = { + 0xbb, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_32_T0_im_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_T1 +{ + static const uint8 op_mov_32_T0_T1_code[] = { + 0x89, 0xf3 + }; + copy_block(op_mov_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_T2 +{ + static const uint8 op_mov_32_T0_T2_code[] = { + 0x89, 0xfb + }; + copy_block(op_mov_32_T0_T2_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_im +{ + static const uint8 op_mov_32_T1_im_code[] = { + 0xbe, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_32_T1_im_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_T0 +{ + static const uint8 op_mov_32_T1_T0_code[] = { + 0x89, 0xde + }; + copy_block(op_mov_32_T1_T0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_T2 +{ + static const uint8 op_mov_32_T1_T2_code[] = { + 0x89, 0xfe + }; + copy_block(op_mov_32_T1_T2_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_im +{ + static const uint8 op_mov_32_T2_im_code[] = { + 0xbf, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mov_32_T2_im_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_T1 +{ + static const uint8 op_mov_32_T2_T1_code[] = { + 0x89, 0xf7 + }; + copy_block(op_mov_32_T2_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_T0 +{ + static const uint8 op_mov_32_T2_T0_code[] = { + 0x89, 0xdf + }; + copy_block(op_mov_32_T2_T0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T0_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T0_0 +{ + static const uint8 op_mov_32_T0_0_code[] = { + 0x31, 0xdb + }; + copy_block(op_mov_32_T0_0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T1_0 +{ + static const uint8 op_mov_32_T1_0_code[] = { + 0x31, 0xf6 + }; + copy_block(op_mov_32_T1_0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mov_32_T2_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mov_32_T2_0 +{ + static const uint8 op_mov_32_T2_0_code[] = { + 0x31, 0xff + }; + copy_block(op_mov_32_T2_0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_T2 +{ + static const uint8 op_add_32_T0_T2_code[] = { + 0x01, 0xfb + }; + copy_block(op_add_32_T0_T2_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_T1 +{ + static const uint8 op_add_32_T0_T1_code[] = { + 0x01, 0xf3 + }; + copy_block(op_add_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_im +{ + static const uint8 op_add_32_T0_im_code[] = { + 0x81, 0xc3, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_add_32_T0_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_1 +{ + static const uint8 op_add_32_T0_1_code[] = { + 0x43 + }; + copy_block(op_add_32_T0_1_code, 1); + inc_code_ptr(1); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_2 +{ + static const uint8 op_add_32_T0_2_code[] = { + 0x83, 0xc3, 0x02 + }; + copy_block(op_add_32_T0_2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_4 +{ + static const uint8 op_add_32_T0_4_code[] = { + 0x83, 0xc3, 0x04 + }; + copy_block(op_add_32_T0_4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T0_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T0_8 +{ + static const uint8 op_add_32_T0_8_code[] = { + 0x83, 0xc3, 0x08 + }; + copy_block(op_add_32_T0_8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_T2 +{ + static const uint8 op_sub_32_T0_T2_code[] = { + 0x29, 0xfb + }; + copy_block(op_sub_32_T0_T2_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_T1 +{ + static const uint8 op_sub_32_T0_T1_code[] = { + 0x29, 0xf3 + }; + copy_block(op_sub_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_im +{ + static const uint8 op_sub_32_T0_im_code[] = { + 0x81, 0xeb, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_sub_32_T0_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_1 +{ + static const uint8 op_sub_32_T0_1_code[] = { + 0x4b + }; + copy_block(op_sub_32_T0_1_code, 1); + inc_code_ptr(1); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_2 +{ + static const uint8 op_sub_32_T0_2_code[] = { + 0x83, 0xeb, 0x02 + }; + copy_block(op_sub_32_T0_2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_4 +{ + static const uint8 op_sub_32_T0_4_code[] = { + 0x83, 0xeb, 0x04 + }; + copy_block(op_sub_32_T0_4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T0_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T0_8 +{ + static const uint8 op_sub_32_T0_8_code[] = { + 0x83, 0xeb, 0x08 + }; + copy_block(op_sub_32_T0_8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_T2 +{ + static const uint8 op_add_32_T1_T2_code[] = { + 0x01, 0xfe + }; + copy_block(op_add_32_T1_T2_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_T0 +{ + static const uint8 op_add_32_T1_T0_code[] = { + 0x01, 0xde + }; + copy_block(op_add_32_T1_T0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_im +{ + static const uint8 op_add_32_T1_im_code[] = { + 0x81, 0xc6, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_add_32_T1_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_1 +{ + static const uint8 op_add_32_T1_1_code[] = { + 0x46 + }; + copy_block(op_add_32_T1_1_code, 1); + inc_code_ptr(1); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_2 +{ + static const uint8 op_add_32_T1_2_code[] = { + 0x83, 0xc6, 0x02 + }; + copy_block(op_add_32_T1_2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_4 +{ + static const uint8 op_add_32_T1_4_code[] = { + 0x83, 0xc6, 0x04 + }; + copy_block(op_add_32_T1_4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_add_32_T1_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_add_32_T1_8 +{ + static const uint8 op_add_32_T1_8_code[] = { + 0x83, 0xc6, 0x08 + }; + copy_block(op_add_32_T1_8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_T2 +{ + static const uint8 op_sub_32_T1_T2_code[] = { + 0x29, 0xfe + }; + copy_block(op_sub_32_T1_T2_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_T0 +{ + static const uint8 op_sub_32_T1_T0_code[] = { + 0x29, 0xde + }; + copy_block(op_sub_32_T1_T0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_im +{ + static const uint8 op_sub_32_T1_im_code[] = { + 0x81, 0xee, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_sub_32_T1_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_1 +{ + static const uint8 op_sub_32_T1_1_code[] = { + 0x4e + }; + copy_block(op_sub_32_T1_1_code, 1); + inc_code_ptr(1); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_2 +{ + static const uint8 op_sub_32_T1_2_code[] = { + 0x83, 0xee, 0x02 + }; + copy_block(op_sub_32_T1_2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_4 +{ + static const uint8 op_sub_32_T1_4_code[] = { + 0x83, 0xee, 0x04 + }; + copy_block(op_sub_32_T1_4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_sub_32_T1_8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sub_32_T1_8 +{ + static const uint8 op_sub_32_T1_8_code[] = { + 0x83, 0xee, 0x08 + }; + copy_block(op_sub_32_T1_8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_umul_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_umul_32_T0_T1 +{ + static const uint8 op_umul_32_T0_T1_code[] = { + 0x0f, 0xaf, 0xde + }; + copy_block(op_umul_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_smul_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_smul_32_T0_T1 +{ + static const uint8 op_smul_32_T0_T1_code[] = { + 0x0f, 0xaf, 0xde + }; + copy_block(op_smul_32_T0_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_udiv_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_udiv_32_T0_T1 +{ + static const uint8 op_udiv_32_T0_T1_code[] = { + 0x89, 0xd8, 0x31, 0xd2, 0xf7, 0xf6, 0x89, 0xc3 + }; + copy_block(op_udiv_32_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_sdiv_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sdiv_32_T0_T1 +{ + static const uint8 op_sdiv_32_T0_T1_code[] = { + 0x89, 0xd8, 0x99, 0xf7, 0xfe, 0x89, 0xc3 + }; + copy_block(op_sdiv_32_T0_T1_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_xchg_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_xchg_32_T0_T1 +{ + static const uint8 op_xchg_32_T0_T1_code[] = { + 0x87, 0xde + }; + copy_block(op_xchg_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_bswap_16_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_bswap_16_T0 +{ + static const uint8 op_bswap_16_T0_code[] = { + 0x0f, 0xb7, 0xc3, 0x66, 0xc1, 0xc0, 0x08, 0x0f, 0xb7, 0xd8 + }; + copy_block(op_bswap_16_T0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_bswap_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_bswap_32_T0 +{ + static const uint8 op_bswap_32_T0_code[] = { + 0x0f, 0xcb + }; + copy_block(op_bswap_32_T0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_neg_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_neg_32_T0 +{ + static const uint8 op_neg_32_T0_code[] = { + 0xf7, 0xdb + }; + copy_block(op_neg_32_T0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_not_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_not_32_T0 +{ + static const uint8 op_not_32_T0_code[] = { + 0x85, 0xdb, 0x0f, 0x94, 0xc0, 0x0f, 0xb6, 0xd8 + }; + copy_block(op_not_32_T0_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_not_32_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_not_32_T1 +{ + static const uint8 op_not_32_T1_code[] = { + 0x85, 0xf6, 0x0f, 0x94, 0xc0, 0x0f, 0xb6, 0xf0 + }; + copy_block(op_not_32_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_and_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_and_32_T0_T1 +{ + static const uint8 op_and_32_T0_T1_code[] = { + 0x21, 0xf3 + }; + copy_block(op_and_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_and_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_and_32_T0_im +{ + static const uint8 op_and_32_T0_im_code[] = { + 0x81, 0xe3, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_and_32_T0_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_or_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_or_32_T0_T1 +{ + static const uint8 op_or_32_T0_T1_code[] = { + 0x09, 0xf3 + }; + copy_block(op_or_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_or_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_or_32_T0_im +{ + static const uint8 op_or_32_T0_im_code[] = { + 0x81, 0xcb, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_or_32_T0_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_xor_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_xor_32_T0_T1 +{ + static const uint8 op_xor_32_T0_T1_code[] = { + 0x31, 0xf3 + }; + copy_block(op_xor_32_T0_T1_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_xor_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_xor_32_T0_im +{ + static const uint8 op_xor_32_T0_im_code[] = { + 0x81, 0xf3, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_xor_32_T0_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_orc_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_orc_32_T0_T1 +{ + static const uint8 op_orc_32_T0_T1_code[] = { + 0x89, 0xf0, 0xf7, 0xd0, 0x09, 0xc3 + }; + copy_block(op_orc_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_andc_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_andc_32_T0_T1 +{ + static const uint8 op_andc_32_T0_T1_code[] = { + 0x89, 0xf0, 0xf7, 0xd0, 0x21, 0xc3 + }; + copy_block(op_andc_32_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_nand_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_nand_32_T0_T1 +{ + static const uint8 op_nand_32_T0_T1_code[] = { + 0x89, 0xd8, 0x21, 0xf0, 0x89, 0xc3, 0xf7, 0xd3 + }; + copy_block(op_nand_32_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_nor_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_nor_32_T0_T1 +{ + static const uint8 op_nor_32_T0_T1_code[] = { + 0x89, 0xd8, 0x09, 0xf0, 0x89, 0xc3, 0xf7, 0xd3 + }; + copy_block(op_nor_32_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_eqv_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_eqv_32_T0_T1 +{ + static const uint8 op_eqv_32_T0_T1_code[] = { + 0x89, 0xd8, 0x31, 0xf0, 0x89, 0xc3, 0xf7, 0xd3 + }; + copy_block(op_eqv_32_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_lsl_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsl_32_T0_T1 +{ + static const uint8 op_lsl_32_T0_T1_code[] = { + 0x89, 0xf1, 0xd3, 0xe3 + }; + copy_block(op_lsl_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_lsl_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsl_32_T0_im +{ + static const uint8 op_lsl_32_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc1, 0xd3, 0xe3 + }; + copy_block(op_lsl_32_T0_im_code, 9); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_lsr_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsr_32_T0_T1 +{ + static const uint8 op_lsr_32_T0_T1_code[] = { + 0x89, 0xf1, 0xd3, 0xeb + }; + copy_block(op_lsr_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_lsr_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lsr_32_T0_im +{ + static const uint8 op_lsr_32_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc1, 0xd3, 0xeb + }; + copy_block(op_lsr_32_T0_im_code, 9); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_asr_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_asr_32_T0_T1 +{ + static const uint8 op_asr_32_T0_T1_code[] = { + 0x89, 0xf1, 0xd3, 0xfb + }; + copy_block(op_asr_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_asr_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_asr_32_T0_im +{ + static const uint8 op_asr_32_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc1, 0xd3, 0xfb + }; + copy_block(op_asr_32_T0_im_code, 9); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_rol_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rol_32_T0_T1 +{ + static const uint8 op_rol_32_T0_T1_code[] = { + 0x89, 0xf1, 0xd3, 0xc3 + }; + copy_block(op_rol_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_rol_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rol_32_T0_im +{ + static const uint8 op_rol_32_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc1, 0xd3, 0xc3 + }; + copy_block(op_rol_32_T0_im_code, 9); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_ror_32_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ror_32_T0_T1 +{ + static const uint8 op_ror_32_T0_T1_code[] = { + 0x89, 0xf1, 0xd3, 0xcb + }; + copy_block(op_ror_32_T0_T1_code, 4); + inc_code_ptr(4); +} +#endif + +DEFINE_GEN(gen_op_ror_32_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ror_32_T0_im +{ + static const uint8 op_ror_32_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc1, 0xd3, 0xcb + }; + copy_block(op_ror_32_T0_im_code, 9); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_se_16_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_se_16_32_T0 +{ + static const uint8 op_se_16_32_T0_code[] = { + 0x0f, 0xbf, 0xdb + }; + copy_block(op_se_16_32_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_se_16_32_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_se_16_32_T1 +{ + static const uint8 op_se_16_32_T1_code[] = { + 0x0f, 0xbf, 0xf6 + }; + copy_block(op_se_16_32_T1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_ze_16_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ze_16_32_T0 +{ + static const uint8 op_ze_16_32_T0_code[] = { + 0x0f, 0xb7, 0xdb + }; + copy_block(op_ze_16_32_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_se_8_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_se_8_32_T0 +{ + static const uint8 op_se_8_32_T0_code[] = { + 0x0f, 0xbe, 0xdb + }; + copy_block(op_se_8_32_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_ze_8_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_ze_8_32_T0 +{ + static const uint8 op_ze_8_32_T0_code[] = { + 0x0f, 0xb6, 0xdb + }; + copy_block(op_ze_8_32_T0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_u32_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u32_T0_T1_0 +{ + static const uint8 op_load_u32_T0_T1_0_code[] = { + 0x8b, 0x86, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb + }; + copy_block(op_load_u32_T0_T1_0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_load_s32_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s32_T0_T1_0 +{ + static const uint8 op_load_s32_T0_T1_0_code[] = { + 0x8b, 0x86, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb + }; + copy_block(op_load_s32_T0_T1_0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_32_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_32_T0_T1_0 +{ + static const uint8 op_store_32_T0_T1_0_code[] = { + 0x89, 0xd8, 0x0f, 0xc8, 0x89, 0x86, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_32_T0_T1_0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_load_u32_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u32_T0_T1_im +{ + static const uint8 op_load_u32_T0_T1_im_code[] = { + 0x8b, 0x86, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb + }; + copy_block(op_load_u32_T0_T1_im_code, 10); + *(uint32_t *)(code_ptr() + 2) = param1 + 285212672; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_load_s32_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s32_T0_T1_im +{ + static const uint8 op_load_s32_T0_T1_im_code[] = { + 0x8b, 0x86, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb + }; + copy_block(op_load_s32_T0_T1_im_code, 10); + *(uint32_t *)(code_ptr() + 2) = param1 + 285212672; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_store_32_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_32_T0_T1_im +{ + static const uint8 op_store_32_T0_T1_im_code[] = { + 0x8d, 0x96, 0x00, 0x00, 0x00, 0x00, 0x89, 0xd8, 0x0f, 0xc8, 0x89, 0x82, + 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_32_T0_T1_im_code, 16); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_load_u32_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u32_T0_T1_T2 +{ + static const uint8 op_load_u32_T0_T1_T2_code[] = { + 0x8b, 0x84, 0x3e, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb + }; + copy_block(op_load_u32_T0_T1_T2_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_load_s32_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s32_T0_T1_T2 +{ + static const uint8 op_load_s32_T0_T1_T2_code[] = { + 0x8b, 0x84, 0x3e, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb + }; + copy_block(op_load_s32_T0_T1_T2_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_32_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_32_T0_T1_T2 +{ + static const uint8 op_store_32_T0_T1_T2_code[] = { + 0x8d, 0x14, 0x3e, 0x89, 0xd8, 0x0f, 0xc8, 0x89, 0x82, 0x00, 0x00, 0x00, + 0x11 + }; + copy_block(op_store_32_T0_T1_T2_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_load_u16_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u16_T0_T1_0 +{ + static const uint8 op_load_u16_T0_T1_0_code[] = { + 0x0f, 0xb7, 0x86, 0x00, 0x00, 0x00, 0x11, 0x66, 0xc1, 0xc0, 0x08, 0x0f, + 0xb7, 0xd8 + }; + copy_block(op_load_u16_T0_T1_0_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_s16_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s16_T0_T1_0 +{ + static const uint8 op_load_s16_T0_T1_0_code[] = { + 0x0f, 0xb7, 0x86, 0x00, 0x00, 0x00, 0x11, 0x66, 0xc1, 0xc0, 0x08, 0x0f, + 0xbf, 0xd8 + }; + copy_block(op_load_s16_T0_T1_0_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_16_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_16_T0_T1_0 +{ + static const uint8 op_store_16_T0_T1_0_code[] = { + 0x0f, 0xb7, 0xc3, 0x66, 0xc1, 0xc0, 0x08, 0x66, 0x89, 0x86, 0x00, 0x00, + 0x00, 0x11 + }; + copy_block(op_store_16_T0_T1_0_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_u16_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u16_T0_T1_im +{ + static const uint8 op_load_u16_T0_T1_im_code[] = { + 0x0f, 0xb7, 0x86, 0x00, 0x00, 0x00, 0x11, 0x66, 0xc1, 0xc0, 0x08, 0x0f, + 0xb7, 0xd8 + }; + copy_block(op_load_u16_T0_T1_im_code, 14); + *(uint32_t *)(code_ptr() + 3) = param1 + 285212672; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_s16_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s16_T0_T1_im +{ + static const uint8 op_load_s16_T0_T1_im_code[] = { + 0x0f, 0xb7, 0x86, 0x00, 0x00, 0x00, 0x11, 0x66, 0xc1, 0xc0, 0x08, 0x0f, + 0xbf, 0xd8 + }; + copy_block(op_load_s16_T0_T1_im_code, 14); + *(uint32_t *)(code_ptr() + 3) = param1 + 285212672; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_16_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_16_T0_T1_im +{ + static const uint8 op_store_16_T0_T1_im_code[] = { + 0x8d, 0x96, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xb7, 0xc3, 0x66, 0xc1, 0xc0, + 0x08, 0x66, 0x89, 0x82, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_16_T0_T1_im_code, 20); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_load_u16_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u16_T0_T1_T2 +{ + static const uint8 op_load_u16_T0_T1_T2_code[] = { + 0x0f, 0xb7, 0x84, 0x3e, 0x00, 0x00, 0x00, 0x11, 0x66, 0xc1, 0xc0, 0x08, + 0x0f, 0xb7, 0xd8 + }; + copy_block(op_load_u16_T0_T1_T2_code, 15); + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_load_s16_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s16_T0_T1_T2 +{ + static const uint8 op_load_s16_T0_T1_T2_code[] = { + 0x0f, 0xb7, 0x84, 0x3e, 0x00, 0x00, 0x00, 0x11, 0x66, 0xc1, 0xc0, 0x08, + 0x0f, 0xbf, 0xd8 + }; + copy_block(op_load_s16_T0_T1_T2_code, 15); + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_store_16_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_16_T0_T1_T2 +{ + static const uint8 op_store_16_T0_T1_T2_code[] = { + 0x8d, 0x14, 0x3e, 0x0f, 0xb7, 0xc3, 0x66, 0xc1, 0xc0, 0x08, 0x66, 0x89, + 0x82, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_16_T0_T1_T2_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_u8_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u8_T0_T1_0 +{ + static const uint8 op_load_u8_T0_T1_0_code[] = { + 0x0f, 0xb6, 0x9e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_load_u8_T0_T1_0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_s8_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s8_T0_T1_0 +{ + static const uint8 op_load_s8_T0_T1_0_code[] = { + 0x0f, 0xbe, 0x9e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_load_s8_T0_T1_0_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_8_T0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_8_T0_T1_0 +{ + static const uint8 op_store_8_T0_T1_0_code[] = { + 0x88, 0x9e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_8_T0_T1_0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_u8_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u8_T0_T1_im +{ + static const uint8 op_load_u8_T0_T1_im_code[] = { + 0x0f, 0xb6, 0x9e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_load_u8_T0_T1_im_code, 7); + *(uint32_t *)(code_ptr() + 3) = param1 + 285212672; + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_load_s8_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s8_T0_T1_im +{ + static const uint8 op_load_s8_T0_T1_im_code[] = { + 0x0f, 0xbe, 0x9e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_load_s8_T0_T1_im_code, 7); + *(uint32_t *)(code_ptr() + 3) = param1 + 285212672; + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_store_8_T0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_8_T0_T1_im +{ + static const uint8 op_store_8_T0_T1_im_code[] = { + 0x88, 0x9e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_8_T0_T1_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 285212672; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_u8_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_u8_T0_T1_T2 +{ + static const uint8 op_load_u8_T0_T1_T2_code[] = { + 0x0f, 0xb6, 0x9c, 0x3e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_load_u8_T0_T1_T2_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_load_s8_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_s8_T0_T1_T2 +{ + static const uint8 op_load_s8_T0_T1_T2_code[] = { + 0x0f, 0xbe, 0x9c, 0x3e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_load_s8_T0_T1_T2_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_store_8_T0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_8_T0_T1_T2 +{ + static const uint8 op_store_8_T0_T1_T2_code[] = { + 0x88, 0x9c, 0x3e, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_8_T0_T1_T2_code, 7); + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_execute,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_execute +{ + static const uint8 op_execute_code[] = { + 0x83, 0xec, 0x50, 0x89, 0x6c, 0x24, 0x4c, 0x8b, 0x6c, 0x24, 0x58, 0x89, + 0x5c, 0x24, 0x48, 0x89, 0x74, 0x24, 0x44, 0x89, 0x7c, 0x24, 0x40, 0xff, + 0x64, 0x24, 0x54, 0x90, 0x8d, 0x74, 0x26, 0x00, 0xff, 0x54, 0x24, 0x54, + 0x8b, 0x7c, 0x24, 0x40, 0x8b, 0x74, 0x24, 0x44, 0x8b, 0x5c, 0x24, 0x48, + 0x8b, 0x6c, 0x24, 0x4c, 0x83, 0xc4, 0x50, 0xc3, 0x90, 0x8d, 0xb4, 0x26, + 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_execute_code, 64); + inc_code_ptr(64); +} +#endif + +DEFINE_GEN(gen_op_jmp_slow,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jmp_slow +{ + static const uint8 op_jmp_slow_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0 + }; + copy_block(op_jmp_slow_code, 7); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(7); +} +#endif + +DEFINE_GEN(gen_op_jmp_fast,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jmp_fast +{ + static const uint8 op_jmp_fast_code[] = { + 0xe9, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_jmp_fast_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 - (long)(code_ptr() + 1) + 0 -4; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_jmp_A0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jmp_A0 +{ + static const uint8 op_jmp_A0_code[] = { + 0xff, 0xe3 + }; + copy_block(op_jmp_A0_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_invoke,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke +{ + static const uint8 helper_op_invoke_code[] = { + 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 - (long)(code_ptr() + 1) + 0 -4; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0 +{ + static const uint8 helper_op_invoke_T0_code[] = { + 0x83, 0xec, 0x04, 0x89, 0x1c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58 + }; + copy_block(helper_op_invoke_T0_code, 12); + *(uint32_t *)(code_ptr() + 7) = param1 - (long)(code_ptr() + 7) + 0 -4; + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0_T1,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0_T1 +{ + static const uint8 helper_op_invoke_T0_T1_code[] = { + 0x83, 0xec, 0x08, 0x89, 0x74, 0x24, 0x04, 0x89, 0x1c, 0x24, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_T0_T1_code, 18); + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0_T1_T2,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0_T1_T2 +{ + static const uint8 helper_op_invoke_T0_T1_T2_code[] = { + 0x83, 0xec, 0x0c, 0x89, 0x7c, 0x24, 0x08, 0x89, 0x74, 0x24, 0x04, 0x89, + 0x1c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c + }; + copy_block(helper_op_invoke_T0_T1_T2_code, 22); + *(uint32_t *)(code_ptr() + 15) = param1 - (long)(code_ptr() + 15) + 0 -4; + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_invoke_T0_ret_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_T0_ret_T0 +{ + static const uint8 helper_op_invoke_T0_ret_T0_code[] = { + 0x83, 0xec, 0x04, 0x89, 0x1c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5a, + 0x89, 0xc3 + }; + copy_block(helper_op_invoke_T0_ret_T0_code, 14); + *(uint32_t *)(code_ptr() + 7) = param1 - (long)(code_ptr() + 7) + 0 -4; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_invoke_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_im +{ + static const uint8 helper_op_invoke_im_code[] = { + 0x83, 0xec, 0x04, 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x59 + }; + copy_block(helper_op_invoke_im_code, 16); + *(uint32_t *)(code_ptr() + 6) = param2 + 0; + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU +{ + static const uint8 helper_op_invoke_CPU_code[] = { + 0x83, 0xec, 0x04, 0x89, 0x2c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58 + }; + copy_block(helper_op_invoke_CPU_code, 12); + *(uint32_t *)(code_ptr() + 7) = param1 - (long)(code_ptr() + 7) + 0 -4; + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_T0 +{ + static const uint8 helper_op_invoke_CPU_T0_code[] = { + 0x83, 0xec, 0x08, 0x89, 0x5c, 0x24, 0x04, 0x89, 0x2c, 0x24, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_CPU_T0_code, 18); + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_im +{ + static const uint8 helper_op_invoke_CPU_im_code[] = { + 0x83, 0xec, 0x08, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x04, + 0x89, 0x2c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_CPU_im_code, 23); + *(uint32_t *)(code_ptr() + 4) = param2 + 0; + *(uint32_t *)(code_ptr() + 16) = param1 - (long)(code_ptr() + 16) + 0 -4; + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_im_im,void,(long param1, long param2, long param3)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_im_im +{ + static const uint8 helper_op_invoke_CPU_im_im_code[] = { + 0x83, 0xec, 0x0c, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x08, + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x04, 0x89, 0x2c, 0x24, + 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c + }; + copy_block(helper_op_invoke_CPU_im_im_code, 32); + *(uint32_t *)(code_ptr() + 4) = param3 + 0; + *(uint32_t *)(code_ptr() + 13) = param2 + 0; + *(uint32_t *)(code_ptr() + 25) = param1 - (long)(code_ptr() + 25) + 0 -4; + inc_code_ptr(32); +} +#endif + +DEFINE_GEN(gen_op_invoke_CPU_A0_ret_A0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_CPU_A0_ret_A0 +{ + static const uint8 helper_op_invoke_CPU_A0_ret_A0_code[] = { + 0x83, 0xec, 0x08, 0x89, 0x5c, 0x24, 0x04, 0x89, 0x2c, 0x24, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x89, 0xc3, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_CPU_A0_ret_A0_code, 20); + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct +{ + static const uint8 helper_op_invoke_direct_code[] = { + 0xe8, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(helper_op_invoke_direct_code, 5); + *(uint32_t *)(code_ptr() + 1) = param1 - (long)(code_ptr() + 1) + 0 -4; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0 +{ + static const uint8 helper_op_invoke_direct_T0_code[] = { + 0x83, 0xec, 0x04, 0x89, 0x1c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58 + }; + copy_block(helper_op_invoke_direct_T0_code, 12); + *(uint32_t *)(code_ptr() + 7) = param1 - (long)(code_ptr() + 7) + 0 -4; + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0_T1,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0_T1 +{ + static const uint8 helper_op_invoke_direct_T0_T1_code[] = { + 0x83, 0xec, 0x08, 0x89, 0x74, 0x24, 0x04, 0x89, 0x1c, 0x24, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_direct_T0_T1_code, 18); + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0_T1_T2,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0_T1_T2 +{ + static const uint8 helper_op_invoke_direct_T0_T1_T2_code[] = { + 0x83, 0xec, 0x0c, 0x89, 0x7c, 0x24, 0x08, 0x89, 0x74, 0x24, 0x04, 0x89, + 0x1c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c + }; + copy_block(helper_op_invoke_direct_T0_T1_T2_code, 22); + *(uint32_t *)(code_ptr() + 15) = param1 - (long)(code_ptr() + 15) + 0 -4; + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_T0_ret_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_T0_ret_T0 +{ + static const uint8 helper_op_invoke_direct_T0_ret_T0_code[] = { + 0x83, 0xec, 0x04, 0x89, 0x1c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x89, + 0xc3, 0x58 + }; + copy_block(helper_op_invoke_direct_T0_ret_T0_code, 14); + *(uint32_t *)(code_ptr() + 7) = param1 - (long)(code_ptr() + 7) + 0 -4; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_im +{ + static const uint8 helper_op_invoke_direct_im_code[] = { + 0x83, 0xec, 0x04, 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x5a + }; + copy_block(helper_op_invoke_direct_im_code, 16); + *(uint32_t *)(code_ptr() + 6) = param2 + 0; + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU +{ + static const uint8 helper_op_invoke_direct_CPU_code[] = { + 0x83, 0xec, 0x04, 0x89, 0x2c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x59 + }; + copy_block(helper_op_invoke_direct_CPU_code, 12); + *(uint32_t *)(code_ptr() + 7) = param1 - (long)(code_ptr() + 7) + 0 -4; + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_T0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_T0 +{ + static const uint8 helper_op_invoke_direct_CPU_T0_code[] = { + 0x83, 0xec, 0x08, 0x89, 0x5c, 0x24, 0x04, 0x89, 0x2c, 0x24, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_direct_CPU_T0_code, 18); + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(18); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_im +{ + static const uint8 helper_op_invoke_direct_CPU_im_code[] = { + 0x83, 0xec, 0x08, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x04, + 0x89, 0x2c, 0x24, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_direct_CPU_im_code, 23); + *(uint32_t *)(code_ptr() + 4) = param2 + 0; + *(uint32_t *)(code_ptr() + 16) = param1 - (long)(code_ptr() + 16) + 0 -4; + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_im_im,void,(long param1, long param2, long param3)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_im_im +{ + static const uint8 helper_op_invoke_direct_CPU_im_im_code[] = { + 0x83, 0xec, 0x0c, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x08, + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x04, 0x89, 0x2c, 0x24, + 0xe8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xc4, 0x0c + }; + copy_block(helper_op_invoke_direct_CPU_im_im_code, 32); + *(uint32_t *)(code_ptr() + 4) = param3 + 0; + *(uint32_t *)(code_ptr() + 13) = param2 + 0; + *(uint32_t *)(code_ptr() + 25) = param1 - (long)(code_ptr() + 25) + 0 -4; + inc_code_ptr(32); +} +#endif + +DEFINE_GEN(gen_op_invoke_direct_CPU_A0_ret_A0,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_invoke_direct_CPU_A0_ret_A0 +{ + static const uint8 helper_op_invoke_direct_CPU_A0_ret_A0_code[] = { + 0x83, 0xec, 0x08, 0x89, 0x5c, 0x24, 0x04, 0x89, 0x2c, 0x24, 0xe8, 0x00, + 0x00, 0x00, 0x00, 0x89, 0xc3, 0x83, 0xc4, 0x08 + }; + copy_block(helper_op_invoke_direct_CPU_A0_ret_A0_code, 20); + *(uint32_t *)(code_ptr() + 11) = param1 - (long)(code_ptr() + 11) + 0 -4; + inc_code_ptr(20); +} +#endif + +DEFINE_CST(op_exec_return_offset,0x24L) + +#undef DEFINE_CST +#undef DEFINE_GEN diff --git a/SheepShaver/src/Windows/cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp b/SheepShaver/src/Windows/cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp new file mode 100644 index 000000000..9f2e1f3fd --- /dev/null +++ b/SheepShaver/src/Windows/cygwin_precompiled_dyngen/ppc-dyngen-ops.hpp @@ -0,0 +1,11173 @@ +#ifndef DEFINE_CST +#define DEFINE_CST(NAME, VALUE) +#endif +DEFINE_GEN(gen_op_load_T0_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR0 +{ + static const uint8 op_load_T0_GPR0_code[] = { + 0x8b, 0x5d, 0x10 + }; + copy_block(op_load_T0_GPR0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR0 +{ + static const uint8 op_store_T0_GPR0_code[] = { + 0x89, 0x5d, 0x10 + }; + copy_block(op_store_T0_GPR0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR0 +{ + static const uint8 op_load_T1_GPR0_code[] = { + 0x8b, 0x75, 0x10 + }; + copy_block(op_load_T1_GPR0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR0 +{ + static const uint8 op_store_T1_GPR0_code[] = { + 0x89, 0x75, 0x10 + }; + copy_block(op_store_T1_GPR0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR0 +{ + static const uint8 op_load_T2_GPR0_code[] = { + 0x8b, 0x7d, 0x10 + }; + copy_block(op_load_T2_GPR0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR0 +{ + static const uint8 op_store_T2_GPR0_code[] = { + 0x89, 0x7d, 0x10 + }; + copy_block(op_store_T2_GPR0_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR1 +{ + static const uint8 op_load_T0_GPR1_code[] = { + 0x8b, 0x5d, 0x14 + }; + copy_block(op_load_T0_GPR1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR1 +{ + static const uint8 op_store_T0_GPR1_code[] = { + 0x89, 0x5d, 0x14 + }; + copy_block(op_store_T0_GPR1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR1 +{ + static const uint8 op_load_T1_GPR1_code[] = { + 0x8b, 0x75, 0x14 + }; + copy_block(op_load_T1_GPR1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR1 +{ + static const uint8 op_store_T1_GPR1_code[] = { + 0x89, 0x75, 0x14 + }; + copy_block(op_store_T1_GPR1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR1 +{ + static const uint8 op_load_T2_GPR1_code[] = { + 0x8b, 0x7d, 0x14 + }; + copy_block(op_load_T2_GPR1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR1 +{ + static const uint8 op_store_T2_GPR1_code[] = { + 0x89, 0x7d, 0x14 + }; + copy_block(op_store_T2_GPR1_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR2 +{ + static const uint8 op_load_T0_GPR2_code[] = { + 0x8b, 0x5d, 0x18 + }; + copy_block(op_load_T0_GPR2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR2 +{ + static const uint8 op_store_T0_GPR2_code[] = { + 0x89, 0x5d, 0x18 + }; + copy_block(op_store_T0_GPR2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR2 +{ + static const uint8 op_load_T1_GPR2_code[] = { + 0x8b, 0x75, 0x18 + }; + copy_block(op_load_T1_GPR2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR2 +{ + static const uint8 op_store_T1_GPR2_code[] = { + 0x89, 0x75, 0x18 + }; + copy_block(op_store_T1_GPR2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR2 +{ + static const uint8 op_load_T2_GPR2_code[] = { + 0x8b, 0x7d, 0x18 + }; + copy_block(op_load_T2_GPR2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR2 +{ + static const uint8 op_store_T2_GPR2_code[] = { + 0x89, 0x7d, 0x18 + }; + copy_block(op_store_T2_GPR2_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR3 +{ + static const uint8 op_load_T0_GPR3_code[] = { + 0x8b, 0x5d, 0x1c + }; + copy_block(op_load_T0_GPR3_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR3 +{ + static const uint8 op_store_T0_GPR3_code[] = { + 0x89, 0x5d, 0x1c + }; + copy_block(op_store_T0_GPR3_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR3 +{ + static const uint8 op_load_T1_GPR3_code[] = { + 0x8b, 0x75, 0x1c + }; + copy_block(op_load_T1_GPR3_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR3 +{ + static const uint8 op_store_T1_GPR3_code[] = { + 0x89, 0x75, 0x1c + }; + copy_block(op_store_T1_GPR3_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR3 +{ + static const uint8 op_load_T2_GPR3_code[] = { + 0x8b, 0x7d, 0x1c + }; + copy_block(op_load_T2_GPR3_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR3 +{ + static const uint8 op_store_T2_GPR3_code[] = { + 0x89, 0x7d, 0x1c + }; + copy_block(op_store_T2_GPR3_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR4 +{ + static const uint8 op_load_T0_GPR4_code[] = { + 0x8b, 0x5d, 0x20 + }; + copy_block(op_load_T0_GPR4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR4 +{ + static const uint8 op_store_T0_GPR4_code[] = { + 0x89, 0x5d, 0x20 + }; + copy_block(op_store_T0_GPR4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR4 +{ + static const uint8 op_load_T1_GPR4_code[] = { + 0x8b, 0x75, 0x20 + }; + copy_block(op_load_T1_GPR4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR4 +{ + static const uint8 op_store_T1_GPR4_code[] = { + 0x89, 0x75, 0x20 + }; + copy_block(op_store_T1_GPR4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR4 +{ + static const uint8 op_load_T2_GPR4_code[] = { + 0x8b, 0x7d, 0x20 + }; + copy_block(op_load_T2_GPR4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR4 +{ + static const uint8 op_store_T2_GPR4_code[] = { + 0x89, 0x7d, 0x20 + }; + copy_block(op_store_T2_GPR4_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR5 +{ + static const uint8 op_load_T0_GPR5_code[] = { + 0x8b, 0x5d, 0x24 + }; + copy_block(op_load_T0_GPR5_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR5 +{ + static const uint8 op_store_T0_GPR5_code[] = { + 0x89, 0x5d, 0x24 + }; + copy_block(op_store_T0_GPR5_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR5 +{ + static const uint8 op_load_T1_GPR5_code[] = { + 0x8b, 0x75, 0x24 + }; + copy_block(op_load_T1_GPR5_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR5 +{ + static const uint8 op_store_T1_GPR5_code[] = { + 0x89, 0x75, 0x24 + }; + copy_block(op_store_T1_GPR5_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR5 +{ + static const uint8 op_load_T2_GPR5_code[] = { + 0x8b, 0x7d, 0x24 + }; + copy_block(op_load_T2_GPR5_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR5 +{ + static const uint8 op_store_T2_GPR5_code[] = { + 0x89, 0x7d, 0x24 + }; + copy_block(op_store_T2_GPR5_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR6 +{ + static const uint8 op_load_T0_GPR6_code[] = { + 0x8b, 0x5d, 0x28 + }; + copy_block(op_load_T0_GPR6_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR6 +{ + static const uint8 op_store_T0_GPR6_code[] = { + 0x89, 0x5d, 0x28 + }; + copy_block(op_store_T0_GPR6_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR6 +{ + static const uint8 op_load_T1_GPR6_code[] = { + 0x8b, 0x75, 0x28 + }; + copy_block(op_load_T1_GPR6_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR6 +{ + static const uint8 op_store_T1_GPR6_code[] = { + 0x89, 0x75, 0x28 + }; + copy_block(op_store_T1_GPR6_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR6 +{ + static const uint8 op_load_T2_GPR6_code[] = { + 0x8b, 0x7d, 0x28 + }; + copy_block(op_load_T2_GPR6_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR6 +{ + static const uint8 op_store_T2_GPR6_code[] = { + 0x89, 0x7d, 0x28 + }; + copy_block(op_store_T2_GPR6_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR7 +{ + static const uint8 op_load_T0_GPR7_code[] = { + 0x8b, 0x5d, 0x2c + }; + copy_block(op_load_T0_GPR7_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR7 +{ + static const uint8 op_store_T0_GPR7_code[] = { + 0x89, 0x5d, 0x2c + }; + copy_block(op_store_T0_GPR7_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR7 +{ + static const uint8 op_load_T1_GPR7_code[] = { + 0x8b, 0x75, 0x2c + }; + copy_block(op_load_T1_GPR7_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR7 +{ + static const uint8 op_store_T1_GPR7_code[] = { + 0x89, 0x75, 0x2c + }; + copy_block(op_store_T1_GPR7_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR7 +{ + static const uint8 op_load_T2_GPR7_code[] = { + 0x8b, 0x7d, 0x2c + }; + copy_block(op_load_T2_GPR7_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR7 +{ + static const uint8 op_store_T2_GPR7_code[] = { + 0x89, 0x7d, 0x2c + }; + copy_block(op_store_T2_GPR7_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR8 +{ + static const uint8 op_load_T0_GPR8_code[] = { + 0x8b, 0x5d, 0x30 + }; + copy_block(op_load_T0_GPR8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR8 +{ + static const uint8 op_store_T0_GPR8_code[] = { + 0x89, 0x5d, 0x30 + }; + copy_block(op_store_T0_GPR8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR8 +{ + static const uint8 op_load_T1_GPR8_code[] = { + 0x8b, 0x75, 0x30 + }; + copy_block(op_load_T1_GPR8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR8 +{ + static const uint8 op_store_T1_GPR8_code[] = { + 0x89, 0x75, 0x30 + }; + copy_block(op_store_T1_GPR8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR8 +{ + static const uint8 op_load_T2_GPR8_code[] = { + 0x8b, 0x7d, 0x30 + }; + copy_block(op_load_T2_GPR8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR8 +{ + static const uint8 op_store_T2_GPR8_code[] = { + 0x89, 0x7d, 0x30 + }; + copy_block(op_store_T2_GPR8_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR9 +{ + static const uint8 op_load_T0_GPR9_code[] = { + 0x8b, 0x5d, 0x34 + }; + copy_block(op_load_T0_GPR9_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR9 +{ + static const uint8 op_store_T0_GPR9_code[] = { + 0x89, 0x5d, 0x34 + }; + copy_block(op_store_T0_GPR9_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR9 +{ + static const uint8 op_load_T1_GPR9_code[] = { + 0x8b, 0x75, 0x34 + }; + copy_block(op_load_T1_GPR9_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR9 +{ + static const uint8 op_store_T1_GPR9_code[] = { + 0x89, 0x75, 0x34 + }; + copy_block(op_store_T1_GPR9_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR9 +{ + static const uint8 op_load_T2_GPR9_code[] = { + 0x8b, 0x7d, 0x34 + }; + copy_block(op_load_T2_GPR9_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR9 +{ + static const uint8 op_store_T2_GPR9_code[] = { + 0x89, 0x7d, 0x34 + }; + copy_block(op_store_T2_GPR9_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR10 +{ + static const uint8 op_load_T0_GPR10_code[] = { + 0x8b, 0x5d, 0x38 + }; + copy_block(op_load_T0_GPR10_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR10 +{ + static const uint8 op_store_T0_GPR10_code[] = { + 0x89, 0x5d, 0x38 + }; + copy_block(op_store_T0_GPR10_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR10 +{ + static const uint8 op_load_T1_GPR10_code[] = { + 0x8b, 0x75, 0x38 + }; + copy_block(op_load_T1_GPR10_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR10 +{ + static const uint8 op_store_T1_GPR10_code[] = { + 0x89, 0x75, 0x38 + }; + copy_block(op_store_T1_GPR10_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR10 +{ + static const uint8 op_load_T2_GPR10_code[] = { + 0x8b, 0x7d, 0x38 + }; + copy_block(op_load_T2_GPR10_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR10 +{ + static const uint8 op_store_T2_GPR10_code[] = { + 0x89, 0x7d, 0x38 + }; + copy_block(op_store_T2_GPR10_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR11 +{ + static const uint8 op_load_T0_GPR11_code[] = { + 0x8b, 0x5d, 0x3c + }; + copy_block(op_load_T0_GPR11_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR11 +{ + static const uint8 op_store_T0_GPR11_code[] = { + 0x89, 0x5d, 0x3c + }; + copy_block(op_store_T0_GPR11_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR11 +{ + static const uint8 op_load_T1_GPR11_code[] = { + 0x8b, 0x75, 0x3c + }; + copy_block(op_load_T1_GPR11_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR11 +{ + static const uint8 op_store_T1_GPR11_code[] = { + 0x89, 0x75, 0x3c + }; + copy_block(op_store_T1_GPR11_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR11 +{ + static const uint8 op_load_T2_GPR11_code[] = { + 0x8b, 0x7d, 0x3c + }; + copy_block(op_load_T2_GPR11_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR11 +{ + static const uint8 op_store_T2_GPR11_code[] = { + 0x89, 0x7d, 0x3c + }; + copy_block(op_store_T2_GPR11_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR12 +{ + static const uint8 op_load_T0_GPR12_code[] = { + 0x8b, 0x5d, 0x40 + }; + copy_block(op_load_T0_GPR12_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR12 +{ + static const uint8 op_store_T0_GPR12_code[] = { + 0x89, 0x5d, 0x40 + }; + copy_block(op_store_T0_GPR12_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR12 +{ + static const uint8 op_load_T1_GPR12_code[] = { + 0x8b, 0x75, 0x40 + }; + copy_block(op_load_T1_GPR12_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR12 +{ + static const uint8 op_store_T1_GPR12_code[] = { + 0x89, 0x75, 0x40 + }; + copy_block(op_store_T1_GPR12_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR12 +{ + static const uint8 op_load_T2_GPR12_code[] = { + 0x8b, 0x7d, 0x40 + }; + copy_block(op_load_T2_GPR12_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR12 +{ + static const uint8 op_store_T2_GPR12_code[] = { + 0x89, 0x7d, 0x40 + }; + copy_block(op_store_T2_GPR12_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR13 +{ + static const uint8 op_load_T0_GPR13_code[] = { + 0x8b, 0x5d, 0x44 + }; + copy_block(op_load_T0_GPR13_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR13 +{ + static const uint8 op_store_T0_GPR13_code[] = { + 0x89, 0x5d, 0x44 + }; + copy_block(op_store_T0_GPR13_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR13 +{ + static const uint8 op_load_T1_GPR13_code[] = { + 0x8b, 0x75, 0x44 + }; + copy_block(op_load_T1_GPR13_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR13 +{ + static const uint8 op_store_T1_GPR13_code[] = { + 0x89, 0x75, 0x44 + }; + copy_block(op_store_T1_GPR13_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR13 +{ + static const uint8 op_load_T2_GPR13_code[] = { + 0x8b, 0x7d, 0x44 + }; + copy_block(op_load_T2_GPR13_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR13 +{ + static const uint8 op_store_T2_GPR13_code[] = { + 0x89, 0x7d, 0x44 + }; + copy_block(op_store_T2_GPR13_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR14 +{ + static const uint8 op_load_T0_GPR14_code[] = { + 0x8b, 0x5d, 0x48 + }; + copy_block(op_load_T0_GPR14_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR14 +{ + static const uint8 op_store_T0_GPR14_code[] = { + 0x89, 0x5d, 0x48 + }; + copy_block(op_store_T0_GPR14_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR14 +{ + static const uint8 op_load_T1_GPR14_code[] = { + 0x8b, 0x75, 0x48 + }; + copy_block(op_load_T1_GPR14_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR14 +{ + static const uint8 op_store_T1_GPR14_code[] = { + 0x89, 0x75, 0x48 + }; + copy_block(op_store_T1_GPR14_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR14 +{ + static const uint8 op_load_T2_GPR14_code[] = { + 0x8b, 0x7d, 0x48 + }; + copy_block(op_load_T2_GPR14_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR14 +{ + static const uint8 op_store_T2_GPR14_code[] = { + 0x89, 0x7d, 0x48 + }; + copy_block(op_store_T2_GPR14_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR15 +{ + static const uint8 op_load_T0_GPR15_code[] = { + 0x8b, 0x5d, 0x4c + }; + copy_block(op_load_T0_GPR15_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR15 +{ + static const uint8 op_store_T0_GPR15_code[] = { + 0x89, 0x5d, 0x4c + }; + copy_block(op_store_T0_GPR15_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR15 +{ + static const uint8 op_load_T1_GPR15_code[] = { + 0x8b, 0x75, 0x4c + }; + copy_block(op_load_T1_GPR15_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR15 +{ + static const uint8 op_store_T1_GPR15_code[] = { + 0x89, 0x75, 0x4c + }; + copy_block(op_store_T1_GPR15_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR15 +{ + static const uint8 op_load_T2_GPR15_code[] = { + 0x8b, 0x7d, 0x4c + }; + copy_block(op_load_T2_GPR15_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR15 +{ + static const uint8 op_store_T2_GPR15_code[] = { + 0x89, 0x7d, 0x4c + }; + copy_block(op_store_T2_GPR15_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR16 +{ + static const uint8 op_load_T0_GPR16_code[] = { + 0x8b, 0x5d, 0x50 + }; + copy_block(op_load_T0_GPR16_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR16 +{ + static const uint8 op_store_T0_GPR16_code[] = { + 0x89, 0x5d, 0x50 + }; + copy_block(op_store_T0_GPR16_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR16 +{ + static const uint8 op_load_T1_GPR16_code[] = { + 0x8b, 0x75, 0x50 + }; + copy_block(op_load_T1_GPR16_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR16 +{ + static const uint8 op_store_T1_GPR16_code[] = { + 0x89, 0x75, 0x50 + }; + copy_block(op_store_T1_GPR16_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR16 +{ + static const uint8 op_load_T2_GPR16_code[] = { + 0x8b, 0x7d, 0x50 + }; + copy_block(op_load_T2_GPR16_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR16 +{ + static const uint8 op_store_T2_GPR16_code[] = { + 0x89, 0x7d, 0x50 + }; + copy_block(op_store_T2_GPR16_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR17 +{ + static const uint8 op_load_T0_GPR17_code[] = { + 0x8b, 0x5d, 0x54 + }; + copy_block(op_load_T0_GPR17_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR17 +{ + static const uint8 op_store_T0_GPR17_code[] = { + 0x89, 0x5d, 0x54 + }; + copy_block(op_store_T0_GPR17_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR17 +{ + static const uint8 op_load_T1_GPR17_code[] = { + 0x8b, 0x75, 0x54 + }; + copy_block(op_load_T1_GPR17_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR17 +{ + static const uint8 op_store_T1_GPR17_code[] = { + 0x89, 0x75, 0x54 + }; + copy_block(op_store_T1_GPR17_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR17 +{ + static const uint8 op_load_T2_GPR17_code[] = { + 0x8b, 0x7d, 0x54 + }; + copy_block(op_load_T2_GPR17_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR17 +{ + static const uint8 op_store_T2_GPR17_code[] = { + 0x89, 0x7d, 0x54 + }; + copy_block(op_store_T2_GPR17_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR18 +{ + static const uint8 op_load_T0_GPR18_code[] = { + 0x8b, 0x5d, 0x58 + }; + copy_block(op_load_T0_GPR18_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR18 +{ + static const uint8 op_store_T0_GPR18_code[] = { + 0x89, 0x5d, 0x58 + }; + copy_block(op_store_T0_GPR18_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR18 +{ + static const uint8 op_load_T1_GPR18_code[] = { + 0x8b, 0x75, 0x58 + }; + copy_block(op_load_T1_GPR18_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR18 +{ + static const uint8 op_store_T1_GPR18_code[] = { + 0x89, 0x75, 0x58 + }; + copy_block(op_store_T1_GPR18_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR18 +{ + static const uint8 op_load_T2_GPR18_code[] = { + 0x8b, 0x7d, 0x58 + }; + copy_block(op_load_T2_GPR18_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR18 +{ + static const uint8 op_store_T2_GPR18_code[] = { + 0x89, 0x7d, 0x58 + }; + copy_block(op_store_T2_GPR18_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR19 +{ + static const uint8 op_load_T0_GPR19_code[] = { + 0x8b, 0x5d, 0x5c + }; + copy_block(op_load_T0_GPR19_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR19 +{ + static const uint8 op_store_T0_GPR19_code[] = { + 0x89, 0x5d, 0x5c + }; + copy_block(op_store_T0_GPR19_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR19 +{ + static const uint8 op_load_T1_GPR19_code[] = { + 0x8b, 0x75, 0x5c + }; + copy_block(op_load_T1_GPR19_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR19 +{ + static const uint8 op_store_T1_GPR19_code[] = { + 0x89, 0x75, 0x5c + }; + copy_block(op_store_T1_GPR19_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR19 +{ + static const uint8 op_load_T2_GPR19_code[] = { + 0x8b, 0x7d, 0x5c + }; + copy_block(op_load_T2_GPR19_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR19 +{ + static const uint8 op_store_T2_GPR19_code[] = { + 0x89, 0x7d, 0x5c + }; + copy_block(op_store_T2_GPR19_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR20 +{ + static const uint8 op_load_T0_GPR20_code[] = { + 0x8b, 0x5d, 0x60 + }; + copy_block(op_load_T0_GPR20_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR20 +{ + static const uint8 op_store_T0_GPR20_code[] = { + 0x89, 0x5d, 0x60 + }; + copy_block(op_store_T0_GPR20_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR20 +{ + static const uint8 op_load_T1_GPR20_code[] = { + 0x8b, 0x75, 0x60 + }; + copy_block(op_load_T1_GPR20_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR20 +{ + static const uint8 op_store_T1_GPR20_code[] = { + 0x89, 0x75, 0x60 + }; + copy_block(op_store_T1_GPR20_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR20 +{ + static const uint8 op_load_T2_GPR20_code[] = { + 0x8b, 0x7d, 0x60 + }; + copy_block(op_load_T2_GPR20_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR20 +{ + static const uint8 op_store_T2_GPR20_code[] = { + 0x89, 0x7d, 0x60 + }; + copy_block(op_store_T2_GPR20_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR21 +{ + static const uint8 op_load_T0_GPR21_code[] = { + 0x8b, 0x5d, 0x64 + }; + copy_block(op_load_T0_GPR21_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR21 +{ + static const uint8 op_store_T0_GPR21_code[] = { + 0x89, 0x5d, 0x64 + }; + copy_block(op_store_T0_GPR21_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR21 +{ + static const uint8 op_load_T1_GPR21_code[] = { + 0x8b, 0x75, 0x64 + }; + copy_block(op_load_T1_GPR21_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR21 +{ + static const uint8 op_store_T1_GPR21_code[] = { + 0x89, 0x75, 0x64 + }; + copy_block(op_store_T1_GPR21_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR21 +{ + static const uint8 op_load_T2_GPR21_code[] = { + 0x8b, 0x7d, 0x64 + }; + copy_block(op_load_T2_GPR21_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR21 +{ + static const uint8 op_store_T2_GPR21_code[] = { + 0x89, 0x7d, 0x64 + }; + copy_block(op_store_T2_GPR21_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR22 +{ + static const uint8 op_load_T0_GPR22_code[] = { + 0x8b, 0x5d, 0x68 + }; + copy_block(op_load_T0_GPR22_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR22 +{ + static const uint8 op_store_T0_GPR22_code[] = { + 0x89, 0x5d, 0x68 + }; + copy_block(op_store_T0_GPR22_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR22 +{ + static const uint8 op_load_T1_GPR22_code[] = { + 0x8b, 0x75, 0x68 + }; + copy_block(op_load_T1_GPR22_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR22 +{ + static const uint8 op_store_T1_GPR22_code[] = { + 0x89, 0x75, 0x68 + }; + copy_block(op_store_T1_GPR22_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR22 +{ + static const uint8 op_load_T2_GPR22_code[] = { + 0x8b, 0x7d, 0x68 + }; + copy_block(op_load_T2_GPR22_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR22 +{ + static const uint8 op_store_T2_GPR22_code[] = { + 0x89, 0x7d, 0x68 + }; + copy_block(op_store_T2_GPR22_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR23 +{ + static const uint8 op_load_T0_GPR23_code[] = { + 0x8b, 0x5d, 0x6c + }; + copy_block(op_load_T0_GPR23_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR23 +{ + static const uint8 op_store_T0_GPR23_code[] = { + 0x89, 0x5d, 0x6c + }; + copy_block(op_store_T0_GPR23_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR23 +{ + static const uint8 op_load_T1_GPR23_code[] = { + 0x8b, 0x75, 0x6c + }; + copy_block(op_load_T1_GPR23_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR23 +{ + static const uint8 op_store_T1_GPR23_code[] = { + 0x89, 0x75, 0x6c + }; + copy_block(op_store_T1_GPR23_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR23 +{ + static const uint8 op_load_T2_GPR23_code[] = { + 0x8b, 0x7d, 0x6c + }; + copy_block(op_load_T2_GPR23_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR23 +{ + static const uint8 op_store_T2_GPR23_code[] = { + 0x89, 0x7d, 0x6c + }; + copy_block(op_store_T2_GPR23_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR24 +{ + static const uint8 op_load_T0_GPR24_code[] = { + 0x8b, 0x5d, 0x70 + }; + copy_block(op_load_T0_GPR24_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR24 +{ + static const uint8 op_store_T0_GPR24_code[] = { + 0x89, 0x5d, 0x70 + }; + copy_block(op_store_T0_GPR24_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR24 +{ + static const uint8 op_load_T1_GPR24_code[] = { + 0x8b, 0x75, 0x70 + }; + copy_block(op_load_T1_GPR24_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR24 +{ + static const uint8 op_store_T1_GPR24_code[] = { + 0x89, 0x75, 0x70 + }; + copy_block(op_store_T1_GPR24_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR24 +{ + static const uint8 op_load_T2_GPR24_code[] = { + 0x8b, 0x7d, 0x70 + }; + copy_block(op_load_T2_GPR24_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR24 +{ + static const uint8 op_store_T2_GPR24_code[] = { + 0x89, 0x7d, 0x70 + }; + copy_block(op_store_T2_GPR24_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR25 +{ + static const uint8 op_load_T0_GPR25_code[] = { + 0x8b, 0x5d, 0x74 + }; + copy_block(op_load_T0_GPR25_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR25 +{ + static const uint8 op_store_T0_GPR25_code[] = { + 0x89, 0x5d, 0x74 + }; + copy_block(op_store_T0_GPR25_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR25 +{ + static const uint8 op_load_T1_GPR25_code[] = { + 0x8b, 0x75, 0x74 + }; + copy_block(op_load_T1_GPR25_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR25 +{ + static const uint8 op_store_T1_GPR25_code[] = { + 0x89, 0x75, 0x74 + }; + copy_block(op_store_T1_GPR25_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR25 +{ + static const uint8 op_load_T2_GPR25_code[] = { + 0x8b, 0x7d, 0x74 + }; + copy_block(op_load_T2_GPR25_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR25 +{ + static const uint8 op_store_T2_GPR25_code[] = { + 0x89, 0x7d, 0x74 + }; + copy_block(op_store_T2_GPR25_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR26 +{ + static const uint8 op_load_T0_GPR26_code[] = { + 0x8b, 0x5d, 0x78 + }; + copy_block(op_load_T0_GPR26_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR26 +{ + static const uint8 op_store_T0_GPR26_code[] = { + 0x89, 0x5d, 0x78 + }; + copy_block(op_store_T0_GPR26_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR26 +{ + static const uint8 op_load_T1_GPR26_code[] = { + 0x8b, 0x75, 0x78 + }; + copy_block(op_load_T1_GPR26_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR26 +{ + static const uint8 op_store_T1_GPR26_code[] = { + 0x89, 0x75, 0x78 + }; + copy_block(op_store_T1_GPR26_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR26 +{ + static const uint8 op_load_T2_GPR26_code[] = { + 0x8b, 0x7d, 0x78 + }; + copy_block(op_load_T2_GPR26_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR26 +{ + static const uint8 op_store_T2_GPR26_code[] = { + 0x89, 0x7d, 0x78 + }; + copy_block(op_store_T2_GPR26_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR27 +{ + static const uint8 op_load_T0_GPR27_code[] = { + 0x8b, 0x5d, 0x7c + }; + copy_block(op_load_T0_GPR27_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR27 +{ + static const uint8 op_store_T0_GPR27_code[] = { + 0x89, 0x5d, 0x7c + }; + copy_block(op_store_T0_GPR27_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR27 +{ + static const uint8 op_load_T1_GPR27_code[] = { + 0x8b, 0x75, 0x7c + }; + copy_block(op_load_T1_GPR27_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR27 +{ + static const uint8 op_store_T1_GPR27_code[] = { + 0x89, 0x75, 0x7c + }; + copy_block(op_store_T1_GPR27_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR27 +{ + static const uint8 op_load_T2_GPR27_code[] = { + 0x8b, 0x7d, 0x7c + }; + copy_block(op_load_T2_GPR27_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR27 +{ + static const uint8 op_store_T2_GPR27_code[] = { + 0x89, 0x7d, 0x7c + }; + copy_block(op_store_T2_GPR27_code, 3); + inc_code_ptr(3); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR28 +{ + static const uint8 op_load_T0_GPR28_code[] = { + 0x8b, 0x9d, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR28 +{ + static const uint8 op_store_T0_GPR28_code[] = { + 0x89, 0x9d, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR28 +{ + static const uint8 op_load_T1_GPR28_code[] = { + 0x8b, 0xb5, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR28 +{ + static const uint8 op_store_T1_GPR28_code[] = { + 0x89, 0xb5, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR28 +{ + static const uint8 op_load_T2_GPR28_code[] = { + 0x8b, 0xbd, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR28 +{ + static const uint8 op_store_T2_GPR28_code[] = { + 0x89, 0xbd, 0x80, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR29 +{ + static const uint8 op_load_T0_GPR29_code[] = { + 0x8b, 0x9d, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR29 +{ + static const uint8 op_store_T0_GPR29_code[] = { + 0x89, 0x9d, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR29 +{ + static const uint8 op_load_T1_GPR29_code[] = { + 0x8b, 0xb5, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR29 +{ + static const uint8 op_store_T1_GPR29_code[] = { + 0x89, 0xb5, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR29 +{ + static const uint8 op_load_T2_GPR29_code[] = { + 0x8b, 0xbd, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR29 +{ + static const uint8 op_store_T2_GPR29_code[] = { + 0x89, 0xbd, 0x84, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR30 +{ + static const uint8 op_load_T0_GPR30_code[] = { + 0x8b, 0x9d, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR30 +{ + static const uint8 op_store_T0_GPR30_code[] = { + 0x89, 0x9d, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR30 +{ + static const uint8 op_load_T1_GPR30_code[] = { + 0x8b, 0xb5, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR30 +{ + static const uint8 op_store_T1_GPR30_code[] = { + 0x89, 0xb5, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR30 +{ + static const uint8 op_load_T2_GPR30_code[] = { + 0x8b, 0xbd, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR30 +{ + static const uint8 op_store_T2_GPR30_code[] = { + 0x89, 0xbd, 0x88, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_GPR31 +{ + static const uint8 op_load_T0_GPR31_code[] = { + 0x8b, 0x9d, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T0_GPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_GPR31 +{ + static const uint8 op_store_T0_GPR31_code[] = { + 0x89, 0x9d, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T0_GPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T1_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_GPR31 +{ + static const uint8 op_load_T1_GPR31_code[] = { + 0x8b, 0xb5, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T1_GPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T1_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_GPR31 +{ + static const uint8 op_store_T1_GPR31_code[] = { + 0x89, 0xb5, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T1_GPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T2_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T2_GPR31 +{ + static const uint8 op_load_T2_GPR31_code[] = { + 0x8b, 0xbd, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_load_T2_GPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T2_GPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T2_GPR31 +{ + static const uint8 op_store_T2_GPR31_code[] = { + 0x89, 0xbd, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_T2_GPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR0 +{ + static const uint8 op_load_F0_FPR0_code[] = { + 0x8d, 0x9d, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR0 +{ + static const uint8 op_store_F0_FPR0_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00, 0x89, + 0x95, 0x94, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR0_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR0 +{ + static const uint8 op_load_F1_FPR0_code[] = { + 0x8d, 0xb5, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR0 +{ + static const uint8 op_store_F1_FPR0_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00, 0x89, + 0x95, 0x94, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR0_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR0 +{ + static const uint8 op_load_F2_FPR0_code[] = { + 0x8d, 0xbd, 0x90, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR0 +{ + static const uint8 op_store_F2_FPR0_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00, 0x89, + 0x95, 0x94, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR0_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR0 +{ + static const uint8 op_store_FD_FPR0_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x90, 0x00, 0x00, 0x00, 0x89, 0x95, 0x94, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR1 +{ + static const uint8 op_load_F0_FPR1_code[] = { + 0x8d, 0x9d, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR1 +{ + static const uint8 op_store_F0_FPR1_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x98, 0x00, 0x00, 0x00, 0x89, + 0x95, 0x9c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR1_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR1 +{ + static const uint8 op_load_F1_FPR1_code[] = { + 0x8d, 0xb5, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR1 +{ + static const uint8 op_store_F1_FPR1_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x98, 0x00, 0x00, 0x00, 0x89, + 0x95, 0x9c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR1_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR1 +{ + static const uint8 op_load_F2_FPR1_code[] = { + 0x8d, 0xbd, 0x98, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR1 +{ + static const uint8 op_store_F2_FPR1_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x98, 0x00, 0x00, 0x00, 0x89, + 0x95, 0x9c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR1_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR1 +{ + static const uint8 op_store_FD_FPR1_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x98, 0x00, 0x00, 0x00, 0x89, 0x95, 0x9c, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR1_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR2 +{ + static const uint8 op_load_F0_FPR2_code[] = { + 0x8d, 0x9d, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR2_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR2 +{ + static const uint8 op_store_F0_FPR2_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xa4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR2_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR2 +{ + static const uint8 op_load_F1_FPR2_code[] = { + 0x8d, 0xb5, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR2_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR2 +{ + static const uint8 op_store_F1_FPR2_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xa4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR2_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR2 +{ + static const uint8 op_load_F2_FPR2_code[] = { + 0x8d, 0xbd, 0xa0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR2_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR2 +{ + static const uint8 op_store_F2_FPR2_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xa4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR2_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR2 +{ + static const uint8 op_store_FD_FPR2_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xa0, 0x00, 0x00, 0x00, 0x89, 0x95, 0xa4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR2_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR3 +{ + static const uint8 op_load_F0_FPR3_code[] = { + 0x8d, 0x9d, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR3_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR3 +{ + static const uint8 op_store_F0_FPR3_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xac, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR3_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR3 +{ + static const uint8 op_load_F1_FPR3_code[] = { + 0x8d, 0xb5, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR3_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR3 +{ + static const uint8 op_store_F1_FPR3_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xac, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR3_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR3 +{ + static const uint8 op_load_F2_FPR3_code[] = { + 0x8d, 0xbd, 0xa8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR3_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR3 +{ + static const uint8 op_store_F2_FPR3_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xac, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR3_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR3 +{ + static const uint8 op_store_FD_FPR3_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xa8, 0x00, 0x00, 0x00, 0x89, 0x95, 0xac, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR3_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR4 +{ + static const uint8 op_load_F0_FPR4_code[] = { + 0x8d, 0x9d, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR4_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR4 +{ + static const uint8 op_store_F0_FPR4_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xb4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR4_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR4 +{ + static const uint8 op_load_F1_FPR4_code[] = { + 0x8d, 0xb5, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR4_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR4 +{ + static const uint8 op_store_F1_FPR4_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xb4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR4_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR4 +{ + static const uint8 op_load_F2_FPR4_code[] = { + 0x8d, 0xbd, 0xb0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR4_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR4 +{ + static const uint8 op_store_F2_FPR4_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xb4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR4_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR4 +{ + static const uint8 op_store_FD_FPR4_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xb0, 0x00, 0x00, 0x00, 0x89, 0x95, 0xb4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR4_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR5 +{ + static const uint8 op_load_F0_FPR5_code[] = { + 0x8d, 0x9d, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR5_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR5 +{ + static const uint8 op_store_F0_FPR5_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xbc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR5_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR5 +{ + static const uint8 op_load_F1_FPR5_code[] = { + 0x8d, 0xb5, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR5_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR5 +{ + static const uint8 op_store_F1_FPR5_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xbc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR5_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR5 +{ + static const uint8 op_load_F2_FPR5_code[] = { + 0x8d, 0xbd, 0xb8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR5_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR5 +{ + static const uint8 op_store_F2_FPR5_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xbc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR5_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR5 +{ + static const uint8 op_store_FD_FPR5_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xb8, 0x00, 0x00, 0x00, 0x89, 0x95, 0xbc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR5_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR6 +{ + static const uint8 op_load_F0_FPR6_code[] = { + 0x8d, 0x9d, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR6_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR6 +{ + static const uint8 op_store_F0_FPR6_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xc4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR6_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR6 +{ + static const uint8 op_load_F1_FPR6_code[] = { + 0x8d, 0xb5, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR6_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR6 +{ + static const uint8 op_store_F1_FPR6_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xc4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR6_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR6 +{ + static const uint8 op_load_F2_FPR6_code[] = { + 0x8d, 0xbd, 0xc0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR6_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR6 +{ + static const uint8 op_store_F2_FPR6_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xc4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR6_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR6 +{ + static const uint8 op_store_FD_FPR6_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xc0, 0x00, 0x00, 0x00, 0x89, 0x95, 0xc4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR6_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR7 +{ + static const uint8 op_load_F0_FPR7_code[] = { + 0x8d, 0x9d, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR7_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR7 +{ + static const uint8 op_store_F0_FPR7_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xcc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR7_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR7 +{ + static const uint8 op_load_F1_FPR7_code[] = { + 0x8d, 0xb5, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR7_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR7 +{ + static const uint8 op_store_F1_FPR7_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xcc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR7_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR7 +{ + static const uint8 op_load_F2_FPR7_code[] = { + 0x8d, 0xbd, 0xc8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR7_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR7 +{ + static const uint8 op_store_F2_FPR7_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xcc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR7_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR7 +{ + static const uint8 op_store_FD_FPR7_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xc8, 0x00, 0x00, 0x00, 0x89, 0x95, 0xcc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR7_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR8 +{ + static const uint8 op_load_F0_FPR8_code[] = { + 0x8d, 0x9d, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR8_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR8 +{ + static const uint8 op_store_F0_FPR8_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xd4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR8_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR8 +{ + static const uint8 op_load_F1_FPR8_code[] = { + 0x8d, 0xb5, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR8_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR8 +{ + static const uint8 op_store_F1_FPR8_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xd4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR8_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR8 +{ + static const uint8 op_load_F2_FPR8_code[] = { + 0x8d, 0xbd, 0xd0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR8_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR8 +{ + static const uint8 op_store_F2_FPR8_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xd4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR8_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR8 +{ + static const uint8 op_store_FD_FPR8_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xd0, 0x00, 0x00, 0x00, 0x89, 0x95, 0xd4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR8_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR9 +{ + static const uint8 op_load_F0_FPR9_code[] = { + 0x8d, 0x9d, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR9_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR9 +{ + static const uint8 op_store_F0_FPR9_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xdc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR9_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR9 +{ + static const uint8 op_load_F1_FPR9_code[] = { + 0x8d, 0xb5, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR9_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR9 +{ + static const uint8 op_store_F1_FPR9_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xdc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR9_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR9 +{ + static const uint8 op_load_F2_FPR9_code[] = { + 0x8d, 0xbd, 0xd8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR9_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR9 +{ + static const uint8 op_store_F2_FPR9_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xdc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR9_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR9 +{ + static const uint8 op_store_FD_FPR9_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xd8, 0x00, 0x00, 0x00, 0x89, 0x95, 0xdc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR9_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR10 +{ + static const uint8 op_load_F0_FPR10_code[] = { + 0x8d, 0x9d, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR10_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR10 +{ + static const uint8 op_store_F0_FPR10_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xe4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR10_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR10 +{ + static const uint8 op_load_F1_FPR10_code[] = { + 0x8d, 0xb5, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR10_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR10 +{ + static const uint8 op_store_F1_FPR10_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xe4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR10_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR10 +{ + static const uint8 op_load_F2_FPR10_code[] = { + 0x8d, 0xbd, 0xe0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR10_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR10 +{ + static const uint8 op_store_F2_FPR10_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xe4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR10_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR10 +{ + static const uint8 op_store_FD_FPR10_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xe0, 0x00, 0x00, 0x00, 0x89, 0x95, 0xe4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR10_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR11 +{ + static const uint8 op_load_F0_FPR11_code[] = { + 0x8d, 0x9d, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR11_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR11 +{ + static const uint8 op_store_F0_FPR11_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xec, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR11_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR11 +{ + static const uint8 op_load_F1_FPR11_code[] = { + 0x8d, 0xb5, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR11_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR11 +{ + static const uint8 op_store_F1_FPR11_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xec, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR11_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR11 +{ + static const uint8 op_load_F2_FPR11_code[] = { + 0x8d, 0xbd, 0xe8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR11_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR11 +{ + static const uint8 op_store_F2_FPR11_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xec, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR11_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR11 +{ + static const uint8 op_store_FD_FPR11_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xe8, 0x00, 0x00, 0x00, 0x89, 0x95, 0xec, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR11_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR12 +{ + static const uint8 op_load_F0_FPR12_code[] = { + 0x8d, 0x9d, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR12_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR12 +{ + static const uint8 op_store_F0_FPR12_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xf4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR12_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR12 +{ + static const uint8 op_load_F1_FPR12_code[] = { + 0x8d, 0xb5, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR12_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR12 +{ + static const uint8 op_store_F1_FPR12_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xf4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR12_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR12 +{ + static const uint8 op_load_F2_FPR12_code[] = { + 0x8d, 0xbd, 0xf0, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR12_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR12 +{ + static const uint8 op_store_F2_FPR12_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xf4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR12_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR12 +{ + static const uint8 op_store_FD_FPR12_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xf0, 0x00, 0x00, 0x00, 0x89, 0x95, 0xf4, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR12_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR13 +{ + static const uint8 op_load_F0_FPR13_code[] = { + 0x8d, 0x9d, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR13_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR13 +{ + static const uint8 op_store_F0_FPR13_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xfc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR13_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR13 +{ + static const uint8 op_load_F1_FPR13_code[] = { + 0x8d, 0xb5, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR13_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR13 +{ + static const uint8 op_store_F1_FPR13_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xfc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR13_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR13 +{ + static const uint8 op_load_F2_FPR13_code[] = { + 0x8d, 0xbd, 0xf8, 0x00, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR13_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR13 +{ + static const uint8 op_store_F2_FPR13_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00, 0x89, + 0x95, 0xfc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR13_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR13 +{ + static const uint8 op_store_FD_FPR13_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0xf8, 0x00, 0x00, 0x00, 0x89, 0x95, 0xfc, 0x00, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR13_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR14 +{ + static const uint8 op_load_F0_FPR14_code[] = { + 0x8d, 0x9d, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR14_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR14 +{ + static const uint8 op_store_F0_FPR14_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x00, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x04, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR14_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR14 +{ + static const uint8 op_load_F1_FPR14_code[] = { + 0x8d, 0xb5, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR14_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR14 +{ + static const uint8 op_store_F1_FPR14_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x00, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x04, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR14_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR14 +{ + static const uint8 op_load_F2_FPR14_code[] = { + 0x8d, 0xbd, 0x00, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR14_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR14 +{ + static const uint8 op_store_F2_FPR14_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x00, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x04, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR14_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR14 +{ + static const uint8 op_store_FD_FPR14_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x00, 0x01, 0x00, 0x00, 0x89, 0x95, 0x04, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR14_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR15 +{ + static const uint8 op_load_F0_FPR15_code[] = { + 0x8d, 0x9d, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR15_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR15 +{ + static const uint8 op_store_F0_FPR15_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x0c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR15_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR15 +{ + static const uint8 op_load_F1_FPR15_code[] = { + 0x8d, 0xb5, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR15_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR15 +{ + static const uint8 op_store_F1_FPR15_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x0c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR15_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR15 +{ + static const uint8 op_load_F2_FPR15_code[] = { + 0x8d, 0xbd, 0x08, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR15_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR15 +{ + static const uint8 op_store_F2_FPR15_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x0c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR15_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR15 +{ + static const uint8 op_store_FD_FPR15_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x08, 0x01, 0x00, 0x00, 0x89, 0x95, 0x0c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR15_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR16 +{ + static const uint8 op_load_F0_FPR16_code[] = { + 0x8d, 0x9d, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR16_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR16 +{ + static const uint8 op_store_F0_FPR16_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x10, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x14, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR16_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR16 +{ + static const uint8 op_load_F1_FPR16_code[] = { + 0x8d, 0xb5, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR16_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR16 +{ + static const uint8 op_store_F1_FPR16_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x10, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x14, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR16_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR16 +{ + static const uint8 op_load_F2_FPR16_code[] = { + 0x8d, 0xbd, 0x10, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR16_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR16 +{ + static const uint8 op_store_F2_FPR16_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x10, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x14, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR16_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR16 +{ + static const uint8 op_store_FD_FPR16_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x10, 0x01, 0x00, 0x00, 0x89, 0x95, 0x14, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR16_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR17 +{ + static const uint8 op_load_F0_FPR17_code[] = { + 0x8d, 0x9d, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR17_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR17 +{ + static const uint8 op_store_F0_FPR17_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x18, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x1c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR17_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR17 +{ + static const uint8 op_load_F1_FPR17_code[] = { + 0x8d, 0xb5, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR17_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR17 +{ + static const uint8 op_store_F1_FPR17_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x18, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x1c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR17_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR17 +{ + static const uint8 op_load_F2_FPR17_code[] = { + 0x8d, 0xbd, 0x18, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR17_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR17 +{ + static const uint8 op_store_F2_FPR17_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x18, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x1c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR17_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR17 +{ + static const uint8 op_store_FD_FPR17_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x18, 0x01, 0x00, 0x00, 0x89, 0x95, 0x1c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR17_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR18 +{ + static const uint8 op_load_F0_FPR18_code[] = { + 0x8d, 0x9d, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR18_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR18 +{ + static const uint8 op_store_F0_FPR18_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x20, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x24, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR18_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR18 +{ + static const uint8 op_load_F1_FPR18_code[] = { + 0x8d, 0xb5, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR18_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR18 +{ + static const uint8 op_store_F1_FPR18_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x20, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x24, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR18_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR18 +{ + static const uint8 op_load_F2_FPR18_code[] = { + 0x8d, 0xbd, 0x20, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR18_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR18 +{ + static const uint8 op_store_F2_FPR18_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x20, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x24, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR18_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR18 +{ + static const uint8 op_store_FD_FPR18_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x20, 0x01, 0x00, 0x00, 0x89, 0x95, 0x24, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR18_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR19 +{ + static const uint8 op_load_F0_FPR19_code[] = { + 0x8d, 0x9d, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR19_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR19 +{ + static const uint8 op_store_F0_FPR19_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x28, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x2c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR19_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR19 +{ + static const uint8 op_load_F1_FPR19_code[] = { + 0x8d, 0xb5, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR19_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR19 +{ + static const uint8 op_store_F1_FPR19_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x28, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x2c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR19_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR19 +{ + static const uint8 op_load_F2_FPR19_code[] = { + 0x8d, 0xbd, 0x28, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR19_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR19 +{ + static const uint8 op_store_F2_FPR19_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x28, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x2c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR19_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR19 +{ + static const uint8 op_store_FD_FPR19_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x28, 0x01, 0x00, 0x00, 0x89, 0x95, 0x2c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR19_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR20 +{ + static const uint8 op_load_F0_FPR20_code[] = { + 0x8d, 0x9d, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR20_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR20 +{ + static const uint8 op_store_F0_FPR20_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x34, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR20_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR20 +{ + static const uint8 op_load_F1_FPR20_code[] = { + 0x8d, 0xb5, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR20_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR20 +{ + static const uint8 op_store_F1_FPR20_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x34, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR20_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR20 +{ + static const uint8 op_load_F2_FPR20_code[] = { + 0x8d, 0xbd, 0x30, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR20_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR20 +{ + static const uint8 op_store_F2_FPR20_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x34, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR20_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR20 +{ + static const uint8 op_store_FD_FPR20_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x30, 0x01, 0x00, 0x00, 0x89, 0x95, 0x34, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR20_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR21 +{ + static const uint8 op_load_F0_FPR21_code[] = { + 0x8d, 0x9d, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR21_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR21 +{ + static const uint8 op_store_F0_FPR21_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x3c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR21_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR21 +{ + static const uint8 op_load_F1_FPR21_code[] = { + 0x8d, 0xb5, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR21_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR21 +{ + static const uint8 op_store_F1_FPR21_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x3c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR21_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR21 +{ + static const uint8 op_load_F2_FPR21_code[] = { + 0x8d, 0xbd, 0x38, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR21_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR21 +{ + static const uint8 op_store_F2_FPR21_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x3c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR21_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR21 +{ + static const uint8 op_store_FD_FPR21_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x38, 0x01, 0x00, 0x00, 0x89, 0x95, 0x3c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR21_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR22 +{ + static const uint8 op_load_F0_FPR22_code[] = { + 0x8d, 0x9d, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR22_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR22 +{ + static const uint8 op_store_F0_FPR22_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x44, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR22_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR22 +{ + static const uint8 op_load_F1_FPR22_code[] = { + 0x8d, 0xb5, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR22_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR22 +{ + static const uint8 op_store_F1_FPR22_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x44, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR22_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR22 +{ + static const uint8 op_load_F2_FPR22_code[] = { + 0x8d, 0xbd, 0x40, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR22_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR22 +{ + static const uint8 op_store_F2_FPR22_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x44, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR22_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR22 +{ + static const uint8 op_store_FD_FPR22_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x89, 0x95, 0x44, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR22_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR23 +{ + static const uint8 op_load_F0_FPR23_code[] = { + 0x8d, 0x9d, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR23_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR23 +{ + static const uint8 op_store_F0_FPR23_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x4c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR23_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR23 +{ + static const uint8 op_load_F1_FPR23_code[] = { + 0x8d, 0xb5, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR23_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR23 +{ + static const uint8 op_store_F1_FPR23_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x4c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR23_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR23 +{ + static const uint8 op_load_F2_FPR23_code[] = { + 0x8d, 0xbd, 0x48, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR23_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR23 +{ + static const uint8 op_store_F2_FPR23_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x4c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR23_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR23 +{ + static const uint8 op_store_FD_FPR23_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x48, 0x01, 0x00, 0x00, 0x89, 0x95, 0x4c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR23_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR24 +{ + static const uint8 op_load_F0_FPR24_code[] = { + 0x8d, 0x9d, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR24_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR24 +{ + static const uint8 op_store_F0_FPR24_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x54, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR24_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR24 +{ + static const uint8 op_load_F1_FPR24_code[] = { + 0x8d, 0xb5, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR24_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR24 +{ + static const uint8 op_store_F1_FPR24_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x54, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR24_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR24 +{ + static const uint8 op_load_F2_FPR24_code[] = { + 0x8d, 0xbd, 0x50, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR24_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR24 +{ + static const uint8 op_store_F2_FPR24_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x54, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR24_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR24 +{ + static const uint8 op_store_FD_FPR24_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x50, 0x01, 0x00, 0x00, 0x89, 0x95, 0x54, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR24_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR25 +{ + static const uint8 op_load_F0_FPR25_code[] = { + 0x8d, 0x9d, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR25_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR25 +{ + static const uint8 op_store_F0_FPR25_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x5c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR25_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR25 +{ + static const uint8 op_load_F1_FPR25_code[] = { + 0x8d, 0xb5, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR25_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR25 +{ + static const uint8 op_store_F1_FPR25_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x5c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR25_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR25 +{ + static const uint8 op_load_F2_FPR25_code[] = { + 0x8d, 0xbd, 0x58, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR25_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR25 +{ + static const uint8 op_store_F2_FPR25_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x5c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR25_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR25 +{ + static const uint8 op_store_FD_FPR25_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x58, 0x01, 0x00, 0x00, 0x89, 0x95, 0x5c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR25_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR26 +{ + static const uint8 op_load_F0_FPR26_code[] = { + 0x8d, 0x9d, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR26_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR26 +{ + static const uint8 op_store_F0_FPR26_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x60, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x64, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR26_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR26 +{ + static const uint8 op_load_F1_FPR26_code[] = { + 0x8d, 0xb5, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR26_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR26 +{ + static const uint8 op_store_F1_FPR26_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x60, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x64, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR26_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR26 +{ + static const uint8 op_load_F2_FPR26_code[] = { + 0x8d, 0xbd, 0x60, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR26_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR26 +{ + static const uint8 op_store_F2_FPR26_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x60, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x64, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR26_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR26 +{ + static const uint8 op_store_FD_FPR26_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x60, 0x01, 0x00, 0x00, 0x89, 0x95, 0x64, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR26_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR27 +{ + static const uint8 op_load_F0_FPR27_code[] = { + 0x8d, 0x9d, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR27_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR27 +{ + static const uint8 op_store_F0_FPR27_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x6c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR27_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR27 +{ + static const uint8 op_load_F1_FPR27_code[] = { + 0x8d, 0xb5, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR27_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR27 +{ + static const uint8 op_store_F1_FPR27_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x6c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR27_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR27 +{ + static const uint8 op_load_F2_FPR27_code[] = { + 0x8d, 0xbd, 0x68, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR27_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR27 +{ + static const uint8 op_store_F2_FPR27_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x6c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR27_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR27 +{ + static const uint8 op_store_FD_FPR27_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x68, 0x01, 0x00, 0x00, 0x89, 0x95, 0x6c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR27_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR28 +{ + static const uint8 op_load_F0_FPR28_code[] = { + 0x8d, 0x9d, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR28 +{ + static const uint8 op_store_F0_FPR28_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x70, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x74, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR28_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR28 +{ + static const uint8 op_load_F1_FPR28_code[] = { + 0x8d, 0xb5, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR28 +{ + static const uint8 op_store_F1_FPR28_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x70, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x74, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR28_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR28 +{ + static const uint8 op_load_F2_FPR28_code[] = { + 0x8d, 0xbd, 0x70, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR28 +{ + static const uint8 op_store_F2_FPR28_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x70, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x74, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR28_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR28 +{ + static const uint8 op_store_FD_FPR28_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x70, 0x01, 0x00, 0x00, 0x89, 0x95, 0x74, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR28_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR29 +{ + static const uint8 op_load_F0_FPR29_code[] = { + 0x8d, 0x9d, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR29 +{ + static const uint8 op_store_F0_FPR29_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x7c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR29_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR29 +{ + static const uint8 op_load_F1_FPR29_code[] = { + 0x8d, 0xb5, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR29 +{ + static const uint8 op_store_F1_FPR29_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x7c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR29_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR29 +{ + static const uint8 op_load_F2_FPR29_code[] = { + 0x8d, 0xbd, 0x78, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR29 +{ + static const uint8 op_store_F2_FPR29_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x7c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR29_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR29 +{ + static const uint8 op_store_FD_FPR29_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x78, 0x01, 0x00, 0x00, 0x89, 0x95, 0x7c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR29_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR30 +{ + static const uint8 op_load_F0_FPR30_code[] = { + 0x8d, 0x9d, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR30 +{ + static const uint8 op_store_F0_FPR30_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x80, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x84, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR30_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR30 +{ + static const uint8 op_load_F1_FPR30_code[] = { + 0x8d, 0xb5, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR30 +{ + static const uint8 op_store_F1_FPR30_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x80, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x84, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR30_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR30 +{ + static const uint8 op_load_F2_FPR30_code[] = { + 0x8d, 0xbd, 0x80, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR30 +{ + static const uint8 op_store_F2_FPR30_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x80, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x84, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR30_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR30 +{ + static const uint8 op_store_FD_FPR30_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x80, 0x01, 0x00, 0x00, 0x89, 0x95, 0x84, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR30_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_F0_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F0_FPR31 +{ + static const uint8 op_load_F0_FPR31_code[] = { + 0x8d, 0x9d, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F0_FPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F0_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F0_FPR31 +{ + static const uint8 op_store_F0_FPR31_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x88, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x8c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F0_FPR31_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F1_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F1_FPR31 +{ + static const uint8 op_load_F1_FPR31_code[] = { + 0x8d, 0xb5, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F1_FPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F1_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F1_FPR31 +{ + static const uint8 op_store_F1_FPR31_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x88, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x8c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F1_FPR31_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_load_F2_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_F2_FPR31 +{ + static const uint8 op_load_F2_FPR31_code[] = { + 0x8d, 0xbd, 0x88, 0x01, 0x00, 0x00 + }; + copy_block(op_load_F2_FPR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_F2_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_F2_FPR31 +{ + static const uint8 op_store_F2_FPR31_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x88, 0x01, 0x00, 0x00, 0x89, + 0x95, 0x8c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_F2_FPR31_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_store_FD_FPR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_FD_FPR31 +{ + static const uint8 op_store_FD_FPR31_code[] = { + 0x8b, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x95, 0x44, 0x08, 0x0e, 0x00, + 0x89, 0x85, 0x88, 0x01, 0x00, 0x00, 0x89, 0x95, 0x8c, 0x01, 0x00, 0x00 + }; + copy_block(op_store_FD_FPR31_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_double_FD_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_double_FD_T1_0 +{ + static const uint8 op_load_double_FD_T1_0_code[] = { + 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x96, 0x00, 0x00, 0x00, 0x11, + 0x0f, 0xca, 0x89, 0x50, 0x04, 0x8b, 0x96, 0x04, 0x00, 0x00, 0x11, 0x0f, + 0xca, 0x89, 0x10 + }; + copy_block(op_load_double_FD_T1_0_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_load_single_FD_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_single_FD_T1_0 +{ + static const uint8 op_load_single_FD_T1_0_code[] = { + 0x83, 0xec, 0x08, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x96, 0x00, + 0x00, 0x00, 0x11, 0x0f, 0xca, 0x89, 0x14, 0x24, 0x31, 0xc9, 0xd9, 0x04, + 0x24, 0x89, 0x4c, 0x24, 0x04, 0xdd, 0x1c, 0x24, 0x8b, 0x14, 0x24, 0x8b, + 0x4c, 0x24, 0x04, 0x89, 0x10, 0x89, 0x48, 0x04, 0x83, 0xc4, 0x08 + }; + copy_block(op_load_single_FD_T1_0_code, 47); + inc_code_ptr(47); +} +#endif + +DEFINE_GEN(gen_op_store_double_F0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_double_F0_T1_0 +{ + static const uint8 op_store_double_F0_T1_0_code[] = { + 0x8b, 0x43, 0x04, 0x0f, 0xc8, 0x89, 0x86, 0x00, 0x00, 0x00, 0x11, 0x8d, + 0x56, 0x04, 0x8b, 0x03, 0x0f, 0xc8, 0x89, 0x82, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_double_F0_T1_0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_store_single_F0_T1_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_single_F0_T1_0 +{ + static const uint8 op_store_single_F0_T1_0_code[] = { + 0x83, 0xec, 0x18, 0x89, 0xf1, 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x44, + 0x24, 0x0c, 0x89, 0xd0, 0xc1, 0xe8, 0x14, 0x89, 0x54, 0x24, 0x10, 0x25, + 0xff, 0x07, 0x00, 0x00, 0x2d, 0x6a, 0x03, 0x00, 0x00, 0x83, 0xf8, 0x16, + 0x76, 0x3a, 0x8b, 0x54, 0x24, 0x10, 0x89, 0xd0, 0x25, 0x00, 0x00, 0x00, + 0xc0, 0x89, 0x04, 0x24, 0x8b, 0x54, 0x24, 0x10, 0x8b, 0x44, 0x24, 0x0c, + 0x0f, 0xac, 0xd0, 0x1d, 0xc1, 0xea, 0x1d, 0x89, 0x44, 0x24, 0x0c, 0x8b, + 0x44, 0x24, 0x0c, 0x89, 0x54, 0x24, 0x10, 0x25, 0xff, 0xff, 0xff, 0x3f, + 0x09, 0x04, 0x24, 0xeb, 0x26, 0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x8b, 0x44, 0x24, 0x0c, 0x8b, 0x54, 0x24, 0x10, 0x89, 0x44, 0x24, 0x04, + 0x89, 0x54, 0x24, 0x08, 0xdd, 0x44, 0x24, 0x04, 0xd9, 0x5c, 0x24, 0x14, + 0x8b, 0x44, 0x24, 0x14, 0x89, 0x04, 0x24, 0x8b, 0x04, 0x24, 0x0f, 0xc8, + 0x89, 0x81, 0x00, 0x00, 0x00, 0x11, 0x83, 0xc4, 0x18 + }; + copy_block(op_store_single_F0_T1_0_code, 141); + inc_code_ptr(141); +} +#endif + +DEFINE_GEN(gen_op_load_double_FD_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_double_FD_T1_im +{ + static const uint8 op_load_double_FD_T1_im_code[] = { + 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x96, 0x00, 0x00, 0x00, 0x11, + 0x0f, 0xca, 0x89, 0x50, 0x04, 0x8b, 0x96, 0x04, 0x00, 0x00, 0x11, 0x0f, + 0xca, 0x89, 0x10 + }; + copy_block(op_load_double_FD_T1_im_code, 27); + *(uint32_t *)(code_ptr() + 8) = param1 + 285212672; + *(uint32_t *)(code_ptr() + 19) = param1 + 285212676; + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_load_single_FD_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_single_FD_T1_im +{ + static const uint8 op_load_single_FD_T1_im_code[] = { + 0x83, 0xec, 0x08, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x96, 0x00, + 0x00, 0x00, 0x11, 0x0f, 0xca, 0x89, 0x14, 0x24, 0x31, 0xc9, 0xd9, 0x04, + 0x24, 0x89, 0x4c, 0x24, 0x04, 0xdd, 0x1c, 0x24, 0x8b, 0x14, 0x24, 0x8b, + 0x4c, 0x24, 0x04, 0x89, 0x10, 0x89, 0x48, 0x04, 0x83, 0xc4, 0x08 + }; + copy_block(op_load_single_FD_T1_im_code, 47); + *(uint32_t *)(code_ptr() + 11) = param1 + 285212672; + inc_code_ptr(47); +} +#endif + +DEFINE_GEN(gen_op_store_double_F0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_double_F0_T1_im +{ + static const uint8 op_store_double_F0_T1_im_code[] = { + 0x8d, 0x96, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x43, 0x04, 0x0f, 0xc8, 0x89, + 0x82, 0x00, 0x00, 0x00, 0x11, 0x8b, 0x03, 0x8d, 0x96, 0x04, 0x00, 0x00, + 0x00, 0x0f, 0xc8, 0x89, 0x82, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_double_F0_T1_im_code, 33); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + *(uint32_t *)(code_ptr() + 21) = param1 + 4; + inc_code_ptr(33); +} +#endif + +DEFINE_GEN(gen_op_store_single_F0_T1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_single_F0_T1_im +{ + static const uint8 op_store_single_F0_T1_im_code[] = { + 0x83, 0xec, 0x18, 0x8d, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x03, 0x8b, + 0x53, 0x04, 0x89, 0x44, 0x24, 0x0c, 0x89, 0xd0, 0xc1, 0xe8, 0x14, 0x89, + 0x54, 0x24, 0x10, 0x25, 0xff, 0x07, 0x00, 0x00, 0x2d, 0x6a, 0x03, 0x00, + 0x00, 0x83, 0xf8, 0x16, 0x76, 0x36, 0x8b, 0x54, 0x24, 0x10, 0x89, 0xd0, + 0x25, 0x00, 0x00, 0x00, 0xc0, 0x89, 0x04, 0x24, 0x8b, 0x54, 0x24, 0x10, + 0x8b, 0x44, 0x24, 0x0c, 0x0f, 0xac, 0xd0, 0x1d, 0xc1, 0xea, 0x1d, 0x89, + 0x44, 0x24, 0x0c, 0x8b, 0x44, 0x24, 0x0c, 0x89, 0x54, 0x24, 0x10, 0x25, + 0xff, 0xff, 0xff, 0x3f, 0x09, 0x04, 0x24, 0xeb, 0x22, 0x8d, 0x76, 0x00, + 0x8b, 0x44, 0x24, 0x0c, 0x8b, 0x54, 0x24, 0x10, 0x89, 0x44, 0x24, 0x04, + 0x89, 0x54, 0x24, 0x08, 0xdd, 0x44, 0x24, 0x04, 0xd9, 0x5c, 0x24, 0x14, + 0x8b, 0x44, 0x24, 0x14, 0x89, 0x04, 0x24, 0x8b, 0x04, 0x24, 0x0f, 0xc8, + 0x89, 0x81, 0x00, 0x00, 0x00, 0x11, 0x83, 0xc4, 0x18 + }; + copy_block(op_store_single_F0_T1_im_code, 141); + *(uint32_t *)(code_ptr() + 5) = param1 + 0; + inc_code_ptr(141); +} +#endif + +DEFINE_GEN(gen_op_load_double_FD_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_double_FD_T1_T2 +{ + static const uint8 op_load_double_FD_T1_T2_code[] = { + 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x94, 0x3e, 0x00, 0x00, 0x00, + 0x11, 0x0f, 0xca, 0x89, 0x50, 0x04, 0x8b, 0x94, 0x3e, 0x04, 0x00, 0x00, + 0x11, 0x0f, 0xca, 0x89, 0x10 + }; + copy_block(op_load_double_FD_T1_T2_code, 29); + inc_code_ptr(29); +} +#endif + +DEFINE_GEN(gen_op_load_single_FD_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_single_FD_T1_T2 +{ + static const uint8 op_load_single_FD_T1_T2_code[] = { + 0x83, 0xec, 0x08, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x8b, 0x94, 0x3e, + 0x00, 0x00, 0x00, 0x11, 0x0f, 0xca, 0x89, 0x14, 0x24, 0x31, 0xc9, 0xd9, + 0x04, 0x24, 0x89, 0x4c, 0x24, 0x04, 0xdd, 0x1c, 0x24, 0x8b, 0x14, 0x24, + 0x8b, 0x4c, 0x24, 0x04, 0x89, 0x10, 0x89, 0x48, 0x04, 0x83, 0xc4, 0x08 + }; + copy_block(op_load_single_FD_T1_T2_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_store_double_F0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_double_F0_T1_T2 +{ + static const uint8 op_store_double_F0_T1_T2_code[] = { + 0x8d, 0x14, 0x3e, 0x8b, 0x43, 0x04, 0x0f, 0xc8, 0x89, 0x82, 0x00, 0x00, + 0x00, 0x11, 0x8b, 0x03, 0x0f, 0xc8, 0x89, 0x82, 0x04, 0x00, 0x00, 0x11 + }; + copy_block(op_store_double_F0_T1_T2_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_store_single_F0_T1_T2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_single_F0_T1_T2 +{ + static const uint8 op_store_single_F0_T1_T2_code[] = { + 0x83, 0xec, 0x18, 0x8d, 0x0c, 0x3e, 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, + 0x44, 0x24, 0x0c, 0x89, 0xd0, 0xc1, 0xe8, 0x14, 0x89, 0x54, 0x24, 0x10, + 0x25, 0xff, 0x07, 0x00, 0x00, 0x2d, 0x6a, 0x03, 0x00, 0x00, 0x83, 0xf8, + 0x16, 0x76, 0x39, 0x8b, 0x54, 0x24, 0x10, 0x89, 0xd0, 0x25, 0x00, 0x00, + 0x00, 0xc0, 0x89, 0x04, 0x24, 0x8b, 0x54, 0x24, 0x10, 0x8b, 0x44, 0x24, + 0x0c, 0x0f, 0xac, 0xd0, 0x1d, 0xc1, 0xea, 0x1d, 0x89, 0x44, 0x24, 0x0c, + 0x8b, 0x44, 0x24, 0x0c, 0x89, 0x54, 0x24, 0x10, 0x25, 0xff, 0xff, 0xff, + 0x3f, 0x09, 0x04, 0x24, 0xeb, 0x25, 0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00, + 0x8b, 0x44, 0x24, 0x0c, 0x8b, 0x54, 0x24, 0x10, 0x89, 0x44, 0x24, 0x04, + 0x89, 0x54, 0x24, 0x08, 0xdd, 0x44, 0x24, 0x04, 0xd9, 0x5c, 0x24, 0x14, + 0x8b, 0x44, 0x24, 0x14, 0x89, 0x04, 0x24, 0x8b, 0x04, 0x24, 0x0f, 0xc8, + 0x89, 0x81, 0x00, 0x00, 0x00, 0x11, 0x83, 0xc4, 0x18 + }; + copy_block(op_store_single_F0_T1_T2_code, 141); + inc_code_ptr(141); +} +#endif + +DEFINE_GEN(gen_op_lwarx_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lwarx_T0_T1 +{ + static const uint8 op_lwarx_T0_T1_code[] = { + 0x8b, 0x86, 0x00, 0x00, 0x00, 0x11, 0x89, 0xc3, 0x0f, 0xcb, 0x89, 0xb5, + 0xbc, 0x03, 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x89, 0x85, 0xb8, + 0x03, 0x00, 0x00 + }; + copy_block(op_lwarx_T0_T1_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_stwcx_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stwcx_T0_T1 +{ + static const uint8 op_stwcx_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x8b, 0x8d, 0x90, 0x03, 0x00, + 0x00, 0xc1, 0xe0, 0x1c, 0x81, 0xe1, 0xff, 0xff, 0xff, 0x0f, 0x09, 0xc1, + 0x8d, 0x45, 0x10, 0x8b, 0x90, 0xa8, 0x03, 0x00, 0x00, 0x85, 0xd2, 0x74, + 0x2b, 0x31, 0xd2, 0x39, 0xb0, 0xac, 0x03, 0x00, 0x00, 0x89, 0x90, 0xa8, + 0x03, 0x00, 0x00, 0x75, 0x1b, 0x89, 0xd8, 0x0f, 0xc8, 0x89, 0x86, 0x00, + 0x00, 0x00, 0x11, 0x81, 0xc9, 0x00, 0x00, 0x00, 0x20, 0x8d, 0x74, 0x26, + 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, 0x89, 0x8d, 0x90, 0x03, + 0x00, 0x00 + }; + copy_block(op_stwcx_T0_T1_code, 86); + inc_code_ptr(86); +} +#endif + +DEFINE_GEN(gen_op_load_T0_CR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_CR +{ + static const uint8 op_load_T0_CR_code[] = { + 0x8b, 0x9d, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_CR_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_CR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_CR +{ + static const uint8 op_store_T0_CR_code[] = { + 0x89, 0x9d, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_CR_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb0 +{ + static const uint8 op_load_T0_crb0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xc3, 0xc1, 0xeb, 0x1f + }; + copy_block(op_load_T0_crb0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb0 +{ + static const uint8 op_store_T0_crb0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xda, 0xc1, 0xe2, 0x1f, 0x25, + 0xff, 0xff, 0xff, 0x7f, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb0 +{ + static const uint8 op_load_T1_crb0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xc6, 0xc1, 0xee, 0x1f + }; + copy_block(op_load_T1_crb0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb0 +{ + static const uint8 op_store_T1_crb0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf2, 0xc1, 0xe2, 0x1f, 0x25, + 0xff, 0xff, 0xff, 0x7f, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb0_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb1 +{ + static const uint8 op_load_T0_crb1_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1e, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb1_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb1 +{ + static const uint8 op_store_T0_crb1_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1e, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xbf, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb1 +{ + static const uint8 op_load_T1_crb1_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1e, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb1_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb1 +{ + static const uint8 op_store_T1_crb1_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1e, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xbf, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb2 +{ + static const uint8 op_load_T0_crb2_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1d, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb2_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb2 +{ + static const uint8 op_store_T0_crb2_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1d, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xdf, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb2_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb2 +{ + static const uint8 op_load_T1_crb2_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1d, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb2_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb2 +{ + static const uint8 op_store_T1_crb2_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1d, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xdf, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb2_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb3 +{ + static const uint8 op_load_T0_crb3_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1c, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb3_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb3 +{ + static const uint8 op_store_T0_crb3_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1c, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xef, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb3_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb3 +{ + static const uint8 op_load_T1_crb3_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1c, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb3_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb3 +{ + static const uint8 op_store_T1_crb3_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1c, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xef, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb3_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb4 +{ + static const uint8 op_load_T0_crb4_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1b, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb4_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb4 +{ + static const uint8 op_store_T0_crb4_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1b, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xf7, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb4_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb4 +{ + static const uint8 op_load_T1_crb4_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1b, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb4_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb4 +{ + static const uint8 op_store_T1_crb4_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1b, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xf7, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb4_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb5 +{ + static const uint8 op_load_T0_crb5_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1a, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb5_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb5 +{ + static const uint8 op_store_T0_crb5_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1a, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfb, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb5_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb5 +{ + static const uint8 op_load_T1_crb5_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x1a, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb5_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb5 +{ + static const uint8 op_store_T1_crb5_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x1a, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfb, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb5_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb6 +{ + static const uint8 op_load_T0_crb6_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x19, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb6_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb6 +{ + static const uint8 op_store_T0_crb6_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x19, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfd, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb6_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb6 +{ + static const uint8 op_load_T1_crb6_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x19, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb6_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb6 +{ + static const uint8 op_store_T1_crb6_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x19, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfd, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb6_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb7 +{ + static const uint8 op_load_T0_crb7_code[] = { + 0x0f, 0xb6, 0x85, 0x93, 0x03, 0x00, 0x00, 0x89, 0xc3, 0x83, 0xe3, 0x01 + }; + copy_block(op_load_T0_crb7_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb7 +{ + static const uint8 op_store_T0_crb7_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x18, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfe, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb7_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb7 +{ + static const uint8 op_load_T1_crb7_code[] = { + 0x0f, 0xb6, 0x85, 0x93, 0x03, 0x00, 0x00, 0x89, 0xc6, 0x83, 0xe6, 0x01 + }; + copy_block(op_load_T1_crb7_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb7 +{ + static const uint8 op_store_T1_crb7_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x18, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xfe, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb7_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb8 +{ + static const uint8 op_load_T0_crb8_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x17, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb8_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb8 +{ + static const uint8 op_store_T0_crb8_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x17, 0x81, 0xe2, 0xff, 0xff, 0x7f, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb8_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb8 +{ + static const uint8 op_load_T1_crb8_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x17, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb8_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb8 +{ + static const uint8 op_store_T1_crb8_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x17, 0x81, 0xe2, 0xff, 0xff, 0x7f, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb8_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb9 +{ + static const uint8 op_load_T0_crb9_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x16, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb9_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb9 +{ + static const uint8 op_store_T0_crb9_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x16, 0x81, 0xe2, 0xff, 0xff, 0xbf, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb9_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb9 +{ + static const uint8 op_load_T1_crb9_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x16, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb9_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb9 +{ + static const uint8 op_store_T1_crb9_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x16, 0x81, 0xe2, 0xff, 0xff, 0xbf, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb9_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb10 +{ + static const uint8 op_load_T0_crb10_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x15, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb10_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb10 +{ + static const uint8 op_store_T0_crb10_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x15, 0x81, 0xe2, 0xff, 0xff, 0xdf, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb10_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb10 +{ + static const uint8 op_load_T1_crb10_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x15, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb10_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb10 +{ + static const uint8 op_store_T1_crb10_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x15, 0x81, 0xe2, 0xff, 0xff, 0xdf, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb10_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb11 +{ + static const uint8 op_load_T0_crb11_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x14, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb11_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb11 +{ + static const uint8 op_store_T0_crb11_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x14, 0x81, 0xe2, 0xff, 0xff, 0xef, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb11_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb11 +{ + static const uint8 op_load_T1_crb11_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x14, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb11_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb11 +{ + static const uint8 op_store_T1_crb11_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x14, 0x81, 0xe2, 0xff, 0xff, 0xef, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb11_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb12 +{ + static const uint8 op_load_T0_crb12_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x13, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb12_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb12 +{ + static const uint8 op_store_T0_crb12_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x13, 0x81, 0xe2, 0xff, 0xff, 0xf7, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb12_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb12 +{ + static const uint8 op_load_T1_crb12_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x13, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb12_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb12 +{ + static const uint8 op_store_T1_crb12_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x13, 0x81, 0xe2, 0xff, 0xff, 0xf7, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb12_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb13 +{ + static const uint8 op_load_T0_crb13_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x12, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb13_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb13 +{ + static const uint8 op_store_T0_crb13_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x12, 0x81, 0xe2, 0xff, 0xff, 0xfb, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb13_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb13 +{ + static const uint8 op_load_T1_crb13_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x12, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb13_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb13 +{ + static const uint8 op_store_T1_crb13_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x12, 0x81, 0xe2, 0xff, 0xff, 0xfb, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb13_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb14 +{ + static const uint8 op_load_T0_crb14_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x11, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb14_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb14 +{ + static const uint8 op_store_T0_crb14_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x11, 0x81, 0xe2, 0xff, 0xff, 0xfd, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb14_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb14 +{ + static const uint8 op_load_T1_crb14_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x11, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb14_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb14 +{ + static const uint8 op_store_T1_crb14_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x11, 0x81, 0xe2, 0xff, 0xff, 0xfd, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb14_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb15 +{ + static const uint8 op_load_T0_crb15_code[] = { + 0x0f, 0xb7, 0x85, 0x92, 0x03, 0x00, 0x00, 0x89, 0xc3, 0x83, 0xe3, 0x01 + }; + copy_block(op_load_T0_crb15_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb15 +{ + static const uint8 op_store_T0_crb15_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x10, 0x81, 0xe2, 0xff, 0xff, 0xfe, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb15_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb15 +{ + static const uint8 op_load_T1_crb15_code[] = { + 0x0f, 0xb7, 0x85, 0x92, 0x03, 0x00, 0x00, 0x89, 0xc6, 0x83, 0xe6, 0x01 + }; + copy_block(op_load_T1_crb15_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb15 +{ + static const uint8 op_store_T1_crb15_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x10, 0x81, 0xe2, 0xff, 0xff, 0xfe, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb15_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb16 +{ + static const uint8 op_load_T0_crb16_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0f, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb16_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb16 +{ + static const uint8 op_store_T0_crb16_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0f, 0x81, 0xe2, 0xff, 0x7f, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb16_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb16 +{ + static const uint8 op_load_T1_crb16_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0f, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb16_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb16 +{ + static const uint8 op_store_T1_crb16_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0f, 0x81, 0xe2, 0xff, 0x7f, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb16_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb17 +{ + static const uint8 op_load_T0_crb17_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0e, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb17_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb17 +{ + static const uint8 op_store_T0_crb17_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0e, 0x81, 0xe2, 0xff, 0xbf, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb17_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb17 +{ + static const uint8 op_load_T1_crb17_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0e, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb17_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb17 +{ + static const uint8 op_store_T1_crb17_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0e, 0x81, 0xe2, 0xff, 0xbf, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb17_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb18 +{ + static const uint8 op_load_T0_crb18_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0d, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb18_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb18 +{ + static const uint8 op_store_T0_crb18_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0d, 0x81, 0xe2, 0xff, 0xdf, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb18_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb18 +{ + static const uint8 op_load_T1_crb18_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0d, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb18_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb18 +{ + static const uint8 op_store_T1_crb18_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0d, 0x81, 0xe2, 0xff, 0xdf, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb18_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb19 +{ + static const uint8 op_load_T0_crb19_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0c, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb19_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb19 +{ + static const uint8 op_store_T0_crb19_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0c, 0x81, 0xe2, 0xff, 0xef, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb19_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb19 +{ + static const uint8 op_load_T1_crb19_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0c, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb19_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb19 +{ + static const uint8 op_store_T1_crb19_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0c, 0x81, 0xe2, 0xff, 0xef, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb19_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb20 +{ + static const uint8 op_load_T0_crb20_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0b, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb20_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb20 +{ + static const uint8 op_store_T0_crb20_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0b, 0x81, 0xe2, 0xff, 0xf7, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb20_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb20 +{ + static const uint8 op_load_T1_crb20_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0b, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb20_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb20 +{ + static const uint8 op_store_T1_crb20_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0b, 0x81, 0xe2, 0xff, 0xf7, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb20_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb21 +{ + static const uint8 op_load_T0_crb21_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0a, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb21_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb21 +{ + static const uint8 op_store_T0_crb21_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0a, 0x81, 0xe2, 0xff, 0xfb, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb21_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb21 +{ + static const uint8 op_load_T1_crb21_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0a, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb21_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb21 +{ + static const uint8 op_store_T1_crb21_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x0a, 0x81, 0xe2, 0xff, 0xfb, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb21_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb22 +{ + static const uint8 op_load_T0_crb22_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x09, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb22_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb22 +{ + static const uint8 op_store_T0_crb22_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x09, 0x81, 0xe2, 0xff, 0xfd, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb22_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb22 +{ + static const uint8 op_load_T1_crb22_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x09, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb22_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb22 +{ + static const uint8 op_store_T1_crb22_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x09, 0x81, 0xe2, 0xff, 0xfd, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb22_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb23 +{ + static const uint8 op_load_T0_crb23_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x08, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb23_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb23 +{ + static const uint8 op_store_T0_crb23_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x08, 0x81, 0xe2, 0xff, 0xfe, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb23_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb23 +{ + static const uint8 op_load_T1_crb23_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x08, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb23_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb23 +{ + static const uint8 op_store_T1_crb23_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x08, 0x81, 0xe2, 0xff, 0xfe, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb23_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb24 +{ + static const uint8 op_load_T0_crb24_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x07, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb24_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb24 +{ + static const uint8 op_store_T0_crb24_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x07, 0x81, 0xe2, 0x7f, 0xff, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb24_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb24 +{ + static const uint8 op_load_T1_crb24_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x07, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb24_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb24 +{ + static const uint8 op_store_T1_crb24_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x07, 0x81, 0xe2, 0x7f, 0xff, 0xff, 0xff, 0x09, 0xc2, 0x89, 0x95, + 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb24_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb25 +{ + static const uint8 op_load_T0_crb25_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x06, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb25_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb25 +{ + static const uint8 op_store_T0_crb25_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x06, 0x83, 0xe2, 0xbf, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_crb25_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb25 +{ + static const uint8 op_load_T1_crb25_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x06, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb25_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb25 +{ + static const uint8 op_store_T1_crb25_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x06, 0x83, 0xe2, 0xbf, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T1_crb25_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb26 +{ + static const uint8 op_load_T0_crb26_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x05, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb26_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb26 +{ + static const uint8 op_store_T0_crb26_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x05, 0x83, 0xe2, 0xdf, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_crb26_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb26 +{ + static const uint8 op_load_T1_crb26_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x05, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb26_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb26 +{ + static const uint8 op_store_T1_crb26_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x05, 0x83, 0xe2, 0xdf, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T1_crb26_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb27 +{ + static const uint8 op_load_T0_crb27_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x04, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb27_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb27 +{ + static const uint8 op_store_T0_crb27_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x04, 0x83, 0xe2, 0xef, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_crb27_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb27 +{ + static const uint8 op_load_T1_crb27_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x04, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb27_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb27 +{ + static const uint8 op_store_T1_crb27_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x04, 0x83, 0xe2, 0xef, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T1_crb27_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb28 +{ + static const uint8 op_load_T0_crb28_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x03, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb28_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb28 +{ + static const uint8 op_store_T0_crb28_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x03, 0x83, 0xe2, 0xf7, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_crb28_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb28 +{ + static const uint8 op_load_T1_crb28_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x03, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb28_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb28 +{ + static const uint8 op_store_T1_crb28_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x03, 0x83, 0xe2, 0xf7, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T1_crb28_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb29 +{ + static const uint8 op_load_T0_crb29_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x02, 0x89, 0xc3, 0x83, + 0xe3, 0x01 + }; + copy_block(op_load_T0_crb29_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb29 +{ + static const uint8 op_store_T0_crb29_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x02, 0x83, 0xe2, 0xfb, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_crb29_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb29 +{ + static const uint8 op_load_T1_crb29_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x02, 0x89, 0xc6, 0x83, + 0xe6, 0x01 + }; + copy_block(op_load_T1_crb29_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb29 +{ + static const uint8 op_store_T1_crb29_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0xc1, + 0xe0, 0x02, 0x83, 0xe2, 0xfb, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T1_crb29_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb30 +{ + static const uint8 op_load_T0_crb30_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xd1, 0xe8, 0x89, 0xc3, 0x83, 0xe3, + 0x01 + }; + copy_block(op_load_T0_crb30_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb30 +{ + static const uint8 op_store_T0_crb30_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x83, 0xe0, 0x01, 0x01, + 0xc0, 0x83, 0xe2, 0xfd, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb30_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb30 +{ + static const uint8 op_load_T1_crb30_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xd1, 0xe8, 0x89, 0xc6, 0x83, 0xe6, + 0x01 + }; + copy_block(op_load_T1_crb30_code, 13); + inc_code_ptr(13); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb30 +{ + static const uint8 op_store_T1_crb30_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf0, 0x83, 0xe0, 0x01, 0x01, + 0xc0, 0x83, 0xe2, 0xfd, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb30_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_T0_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_crb31 +{ + static const uint8 op_load_T0_crb31_code[] = { + 0x8b, 0x9d, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe3, 0x01 + }; + copy_block(op_load_T0_crb31_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_store_T0_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_crb31 +{ + static const uint8 op_store_T0_crb31_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xda, 0x83, 0xe2, 0x01, 0x83, + 0xe0, 0xfe, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_crb31_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_load_T1_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T1_crb31 +{ + static const uint8 op_load_T1_crb31_code[] = { + 0x8b, 0xb5, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe6, 0x01 + }; + copy_block(op_load_T1_crb31_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_store_T1_crb31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T1_crb31 +{ + static const uint8 op_store_T1_crb31_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xf2, 0x83, 0xe2, 0x01, 0x83, + 0xe0, 0xfe, 0x09, 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T1_crb31_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr0 +{ + static const uint8 op_load_T0_cr0_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x89, 0xc3, 0xc1, 0xeb, 0x1c + }; + copy_block(op_load_T0_cr0_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr0 +{ + static const uint8 op_store_T0_cr0_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x1c, 0x81, + 0xe2, 0xff, 0xff, 0xff, 0x0f, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr0_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr1 +{ + static const uint8 op_load_T0_cr1_code[] = { + 0x0f, 0xb6, 0x85, 0x93, 0x03, 0x00, 0x00, 0x89, 0xc3, 0x83, 0xe3, 0x0f + }; + copy_block(op_load_T0_cr1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr1 +{ + static const uint8 op_store_T0_cr1_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x18, 0x81, + 0xe2, 0xff, 0xff, 0xff, 0xf0, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr1_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr2 +{ + static const uint8 op_load_T0_cr2_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x14, 0x89, 0xc3, 0x83, + 0xe3, 0x0f + }; + copy_block(op_load_T0_cr2_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr2 +{ + static const uint8 op_store_T0_cr2_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x14, 0x81, + 0xe2, 0xff, 0xff, 0x0f, 0xff, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr2_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr3 +{ + static const uint8 op_load_T0_cr3_code[] = { + 0x0f, 0xb7, 0x85, 0x92, 0x03, 0x00, 0x00, 0x89, 0xc3, 0x83, 0xe3, 0x0f + }; + copy_block(op_load_T0_cr3_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr3 +{ + static const uint8 op_store_T0_cr3_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x10, 0x81, + 0xe2, 0xff, 0xff, 0xf0, 0xff, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr3_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr4 +{ + static const uint8 op_load_T0_cr4_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x0c, 0x89, 0xc3, 0x83, + 0xe3, 0x0f + }; + copy_block(op_load_T0_cr4_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr4 +{ + static const uint8 op_store_T0_cr4_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x0c, 0x81, + 0xe2, 0xff, 0x0f, 0xff, 0xff, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr4_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr5 +{ + static const uint8 op_load_T0_cr5_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x08, 0x89, 0xc3, 0x83, + 0xe3, 0x0f + }; + copy_block(op_load_T0_cr5_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr5 +{ + static const uint8 op_store_T0_cr5_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x08, 0x81, + 0xe2, 0xff, 0xf0, 0xff, 0xff, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr5_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr6 +{ + static const uint8 op_load_T0_cr6_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0xc1, 0xe8, 0x04, 0x89, 0xc3, 0x83, + 0xe3, 0x0f + }; + copy_block(op_load_T0_cr6_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr6 +{ + static const uint8 op_store_T0_cr6_code[] = { + 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, 0x89, 0xd9, 0xc1, 0xe1, 0x04, 0x81, + 0xe2, 0x0f, 0xff, 0xff, 0xff, 0x09, 0xca, 0x89, 0x95, 0x90, 0x03, 0x00, + 0x00 + }; + copy_block(op_store_T0_cr6_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_load_T0_cr7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_cr7 +{ + static const uint8 op_load_T0_cr7_code[] = { + 0x8b, 0x9d, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe3, 0x0f + }; + copy_block(op_load_T0_cr7_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_store_T0_cr7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_cr7 +{ + static const uint8 op_store_T0_cr7_code[] = { + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x83, 0xe0, 0xf0, 0x09, 0xd8, 0x89, + 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_cr7_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_mtcrf_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mtcrf_T0_im +{ + static const uint8 op_mtcrf_T0_im_code[] = { + 0x8b, 0x8d, 0x90, 0x03, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, + 0xda, 0xf7, 0xd0, 0x81, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x21, 0xc8, 0x09, + 0xd0, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_mtcrf_T0_im_code, 31); + *(uint32_t *)(code_ptr() + 7) = param1 + 0; + *(uint32_t *)(code_ptr() + 17) = param1 + 0; + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_fmov_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F0_F1 +{ + static const uint8 op_fmov_F0_F1_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x03, 0x89, 0x53, 0x04 + }; + copy_block(op_fmov_F0_F1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmov_F0_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F0_F2 +{ + static const uint8 op_fmov_F0_F2_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x03, 0x89, 0x53, 0x04 + }; + copy_block(op_fmov_F0_F2_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmov_F1_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F1_F0 +{ + static const uint8 op_fmov_F1_F0_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x06, 0x89, 0x56, 0x04 + }; + copy_block(op_fmov_F1_F0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmov_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F1_F2 +{ + static const uint8 op_fmov_F1_F2_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x06, 0x89, 0x56, 0x04 + }; + copy_block(op_fmov_F1_F2_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmov_F2_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F2_F0 +{ + static const uint8 op_fmov_F2_F0_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x07, 0x89, 0x57, 0x04 + }; + copy_block(op_fmov_F2_F0_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmov_F2_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_F2_F1 +{ + static const uint8 op_fmov_F2_F1_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x07, 0x89, 0x57, 0x04 + }; + copy_block(op_fmov_F2_F1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmov_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_FD_F0 +{ + static const uint8 op_fmov_FD_F0_code[] = { + 0x8b, 0x03, 0x8b, 0x53, 0x04, 0x89, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x89, + 0x95, 0x44, 0x08, 0x0e, 0x00 + }; + copy_block(op_fmov_FD_F0_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_fmov_FD_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_FD_F1 +{ + static const uint8 op_fmov_FD_F1_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x89, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x89, + 0x95, 0x44, 0x08, 0x0e, 0x00 + }; + copy_block(op_fmov_FD_F1_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_fmov_FD_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmov_FD_F2 +{ + static const uint8 op_fmov_FD_F2_code[] = { + 0x8b, 0x07, 0x8b, 0x57, 0x04, 0x89, 0x85, 0x40, 0x08, 0x0e, 0x00, 0x89, + 0x95, 0x44, 0x08, 0x0e, 0x00 + }; + copy_block(op_fmov_FD_F2_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_fabs_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fabs_FD_F0 +{ + static const uint8 op_fabs_FD_F0_code[] = { + 0xdd, 0x03, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0xd9, 0xe1, 0xdd, 0x18 + }; + copy_block(op_fabs_FD_F0_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_fneg_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fneg_FD_F0 +{ + static const uint8 op_fneg_FD_F0_code[] = { + 0xdd, 0x03, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0xd9, 0xe0, 0xdd, 0x18 + }; + copy_block(op_fneg_FD_F0_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_fnabs_FD_F0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnabs_FD_F0 +{ + static const uint8 op_fnabs_FD_F0_code[] = { + 0xdd, 0x03, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0xd9, 0xe1, 0xd9, 0xe0, + 0xdd, 0x18 + }; + copy_block(op_fnabs_FD_F0_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_fadd_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fadd_FD_F0_F1 +{ + static const uint8 op_fadd_FD_F0_F1_code[] = { + 0xdd, 0x06, 0xdc, 0x03, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00 + }; + copy_block(op_fadd_FD_F0_F1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fsub_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fsub_FD_F0_F1 +{ + static const uint8 op_fsub_FD_F0_F1_code[] = { + 0xdd, 0x06, 0xdc, 0x2b, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00 + }; + copy_block(op_fsub_FD_F0_F1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmul_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmul_FD_F0_F1 +{ + static const uint8 op_fmul_FD_F0_F1_code[] = { + 0xdd, 0x06, 0xdc, 0x0b, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00 + }; + copy_block(op_fmul_FD_F0_F1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fdiv_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fdiv_FD_F0_F1 +{ + static const uint8 op_fdiv_FD_F0_F1_code[] = { + 0xdd, 0x06, 0xdc, 0x3b, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00 + }; + copy_block(op_fdiv_FD_F0_F1_code, 10); + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_fmadd_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmadd_FD_F0_F1_F2 +{ + static const uint8 op_fmadd_FD_F0_F1_F2_code[] = { + 0xdd, 0x06, 0xdc, 0x0b, 0xdc, 0x07, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00 + }; + copy_block(op_fmadd_FD_F0_F1_F2_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_fmsub_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmsub_FD_F0_F1_F2 +{ + static const uint8 op_fmsub_FD_F0_F1_F2_code[] = { + 0xdd, 0x06, 0xdc, 0x0b, 0xdc, 0x27, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00 + }; + copy_block(op_fmsub_FD_F0_F1_F2_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_fnmadd_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmadd_FD_F0_F1_F2 +{ + static const uint8 op_fnmadd_FD_F0_F1_F2_code[] = { + 0xdd, 0x06, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0xdc, 0x0b, 0xdc, 0x07, + 0xd9, 0xe0, 0xdd, 0x18 + }; + copy_block(op_fnmadd_FD_F0_F1_F2_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_fnmsub_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmsub_FD_F0_F1_F2 +{ + static const uint8 op_fnmsub_FD_F0_F1_F2_code[] = { + 0xdd, 0x06, 0x8d, 0x85, 0x40, 0x08, 0x0e, 0x00, 0xdc, 0x0b, 0xdc, 0x27, + 0xd9, 0xe0, 0xdd, 0x18 + }; + copy_block(op_fnmsub_FD_F0_F1_F2_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_fadds_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fadds_FD_F0_F1 +{ + static const uint8 op_fadds_FD_F0_F1_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x03, 0xd9, 0x1c, 0x24, 0xd9, 0x04, + 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x58 + }; + copy_block(op_fadds_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fsubs_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fsubs_FD_F0_F1 +{ + static const uint8 op_fsubs_FD_F0_F1_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x2b, 0xd9, 0x1c, 0x24, 0xd9, 0x04, + 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x58 + }; + copy_block(op_fsubs_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fmuls_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmuls_FD_F0_F1 +{ + static const uint8 op_fmuls_FD_F0_F1_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x0b, 0xd9, 0x1c, 0x24, 0xd9, 0x04, + 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x58 + }; + copy_block(op_fmuls_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fdivs_FD_F0_F1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fdivs_FD_F0_F1 +{ + static const uint8 op_fdivs_FD_F0_F1_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x3b, 0xd9, 0x1c, 0x24, 0xd9, 0x04, + 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x58 + }; + copy_block(op_fdivs_FD_F0_F1_code, 20); + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_fmadds_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmadds_FD_F0_F1_F2 +{ + static const uint8 op_fmadds_FD_F0_F1_F2_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x0b, 0xdc, 0x07, 0xd9, 0x1c, 0x24, + 0xd9, 0x04, 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x58 + }; + copy_block(op_fmadds_FD_F0_F1_F2_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_fmsubs_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fmsubs_FD_F0_F1_F2 +{ + static const uint8 op_fmsubs_FD_F0_F1_F2_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x0b, 0xdc, 0x27, 0xd9, 0x1c, 0x24, + 0xd9, 0x04, 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x58 + }; + copy_block(op_fmsubs_FD_F0_F1_F2_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_fnmadds_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmadds_FD_F0_F1_F2 +{ + static const uint8 op_fnmadds_FD_F0_F1_F2_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x0b, 0xdc, 0x07, 0xd9, 0xe0, 0xd9, + 0x1c, 0x24, 0xd9, 0x04, 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x5a + }; + copy_block(op_fnmadds_FD_F0_F1_F2_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_fnmsubs_FD_F0_F1_F2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_fnmsubs_FD_F0_F1_F2 +{ + static const uint8 op_fnmsubs_FD_F0_F1_F2_code[] = { + 0x83, 0xec, 0x04, 0xdd, 0x06, 0xdc, 0x0b, 0xdc, 0x27, 0xd9, 0xe0, 0xd9, + 0x1c, 0x24, 0xd9, 0x04, 0x24, 0xdd, 0x9d, 0x40, 0x08, 0x0e, 0x00, 0x59 + }; + copy_block(op_fnmsubs_FD_F0_F1_F2_code, 24); + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_load_T0_VRSAVE,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_VRSAVE +{ + static const uint8 op_load_T0_VRSAVE_code[] = { + 0x8b, 0x9d, 0x9c, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_VRSAVE_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_VRSAVE,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_VRSAVE +{ + static const uint8 op_store_T0_VRSAVE_code[] = { + 0x89, 0x9d, 0x9c, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_VRSAVE_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_XER,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_XER +{ + static const uint8 op_load_T0_XER_code[] = { + 0x0f, 0xb6, 0x95, 0x94, 0x03, 0x00, 0x00, 0x8d, 0x8d, 0x94, 0x03, 0x00, + 0x00, 0x0f, 0xb6, 0x41, 0x01, 0xc1, 0xe2, 0x1f, 0xc1, 0xe0, 0x1e, 0x09, + 0xc2, 0x0f, 0xb6, 0x41, 0x02, 0xc1, 0xe0, 0x1d, 0x09, 0xc2, 0x0f, 0xb6, + 0x41, 0x03, 0x89, 0xd3, 0x09, 0xc3 + }; + copy_block(op_load_T0_XER_code, 42); + inc_code_ptr(42); +} +#endif + +DEFINE_GEN(gen_op_load_T0_PC,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_PC +{ + static const uint8 op_load_T0_PC_code[] = { + 0x8b, 0x9d, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_PC_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_PC,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_PC +{ + static const uint8 op_store_T0_PC_code[] = { + 0x89, 0x9d, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_PC_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_set_PC_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_set_PC_im +{ + static const uint8 op_set_PC_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x85, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_set_PC_im_code, 11); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_set_PC_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_set_PC_T0 +{ + static const uint8 op_set_PC_T0_code[] = { + 0x89, 0x9d, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_set_PC_T0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_inc_PC,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_inc_PC +{ + static const uint8 op_inc_PC_code[] = { + 0x81, 0x85, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_inc_PC_code, 10); + *(uint32_t *)(code_ptr() + 6) = param1 + 0; + inc_code_ptr(10); +} +#endif + +DEFINE_GEN(gen_op_load_T0_LR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_LR +{ + static const uint8 op_load_T0_LR_code[] = { + 0x8b, 0x9d, 0xa4, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_LR_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_LR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_LR +{ + static const uint8 op_store_T0_LR_code[] = { + 0x89, 0x9d, 0xa4, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_LR_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_T0_CTR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_CTR +{ + static const uint8 op_load_T0_CTR_code[] = { + 0x8b, 0x9d, 0xa8, 0x03, 0x00, 0x00 + }; + copy_block(op_load_T0_CTR_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_T0_CTR,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_CTR +{ + static const uint8 op_store_T0_CTR_code[] = { + 0x89, 0x9d, 0xa8, 0x03, 0x00, 0x00 + }; + copy_block(op_store_T0_CTR_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_store_im_LR,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_im_LR +{ + static const uint8 op_store_im_LR_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x85, 0xa4, 0x03, 0x00, 0x00 + }; + copy_block(op_store_im_LR_code, 11); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_load_T0_CTR_aligned,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_CTR_aligned +{ + static const uint8 op_load_T0_CTR_aligned_code[] = { + 0x8b, 0x9d, 0xa8, 0x03, 0x00, 0x00, 0x83, 0xe3, 0xfc + }; + copy_block(op_load_T0_CTR_aligned_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_load_T0_LR_aligned,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_T0_LR_aligned +{ + static const uint8 op_load_T0_LR_aligned_code[] = { + 0x8b, 0x9d, 0xa4, 0x03, 0x00, 0x00, 0x83, 0xe3, 0xfc + }; + copy_block(op_load_T0_LR_aligned_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_spcflags_init,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_init +{ + static const uint8 op_spcflags_init_code[] = { + 0x8d, 0x95, 0xb0, 0x03, 0x00, 0x00, 0x83, 0xec, 0x04, 0xb9, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x14, 0x24, 0x8d, 0x95, 0xb4, 0x03, 0x00, 0x00, 0x89, + 0xf6, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, 0x89, 0xc8, 0x87, 0x02, + 0x85, 0xc0, 0x75, 0xf8, 0x8b, 0x04, 0x24, 0x81, 0x08, 0x00, 0x00, 0x00, + 0x00, 0xc7, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x58 + }; + copy_block(op_spcflags_init_code, 57); + *(uint32_t *)(code_ptr() + 45) = param1 + 0; + inc_code_ptr(57); +} +#endif + +DEFINE_GEN(gen_op_spcflags_set,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_set +{ + static const uint8 op_spcflags_set_code[] = { + 0x8d, 0x95, 0xb0, 0x03, 0x00, 0x00, 0x83, 0xec, 0x04, 0xb9, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x14, 0x24, 0x8d, 0x95, 0xb4, 0x03, 0x00, 0x00, 0x89, + 0xf6, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, 0x89, 0xc8, 0x87, 0x02, + 0x85, 0xc0, 0x75, 0xf8, 0x8b, 0x04, 0x24, 0x81, 0x08, 0x00, 0x00, 0x00, + 0x00, 0xc7, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x58 + }; + copy_block(op_spcflags_set_code, 57); + *(uint32_t *)(code_ptr() + 45) = param1 + 0; + inc_code_ptr(57); +} +#endif + +DEFINE_GEN(gen_op_spcflags_clear,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_clear +{ + static const uint8 op_spcflags_clear_code[] = { + 0x83, 0xec, 0x08, 0x8d, 0x95, 0xb0, 0x03, 0x00, 0x00, 0xb9, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x54, 0x24, 0x04, 0x8d, 0x95, 0xb4, 0x03, 0x00, 0x00, + 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x90, 0x89, 0xc8, 0x87, 0x02, + 0x85, 0xc0, 0x75, 0xf8, 0xf7, 0x14, 0x24, 0x8b, 0x44, 0x24, 0x04, 0x8b, + 0x14, 0x24, 0x21, 0x10, 0xc7, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x83, + 0xc4, 0x08 + }; + copy_block(op_spcflags_clear_code, 62); + *(uint32_t *)(code_ptr() + 27) = param1 + 0; + inc_code_ptr(62); +} +#endif + +DEFINE_GEN(gen_op_spcflags_check,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_spcflags_check +{ + static const uint8 op_spcflags_check_code[] = { + 0x8b, 0x85, 0xb0, 0x03, 0x00, 0x00, 0x85, 0xc0, 0x75, 0x05, 0xe9, 0x00, + 0x00, 0x00, 0x00 + }; + copy_block(op_spcflags_check_code, 15); + jmp_addr[0] = code_ptr() + 11; + inc_code_ptr(15); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0000,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0000 +{ + static const uint8 op_prep_branch_bo_0000_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x85, 0xf6, 0x0f, 0x94, 0xc1, 0x31, + 0xd2, 0x48, 0x85, 0xc0, 0x89, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x89, 0xc7, + 0x74, 0x16, 0x84, 0xc9, 0x74, 0x12, 0xba, 0x01, 0x00, 0x00, 0x00, 0x8d, + 0xb6, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x89, 0xd6 + }; + copy_block(op_prep_branch_bo_0000_code, 50); + inc_code_ptr(50); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0001,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0001 +{ + static const uint8 op_prep_branch_bo_0001_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x85, 0xf6, 0x0f, 0x94, 0xc1, 0x31, + 0xd2, 0x48, 0x85, 0xc0, 0x89, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x89, 0xc7, + 0x75, 0x16, 0x84, 0xc9, 0x74, 0x12, 0xba, 0x01, 0x00, 0x00, 0x00, 0x8d, + 0xb6, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x89, 0xd6 + }; + copy_block(op_prep_branch_bo_0001_code, 50); + inc_code_ptr(50); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_001x,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_001x +{ + static const uint8 op_prep_branch_bo_001x_code[] = { + 0x31, 0xc0, 0x85, 0xf6, 0x0f, 0x94, 0xc0, 0x89, 0xc6 + }; + copy_block(op_prep_branch_bo_001x_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0100,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0100 +{ + static const uint8 op_prep_branch_bo_0100_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x85, 0xf6, 0x0f, 0x95, 0xc1, 0x31, + 0xd2, 0x48, 0x85, 0xc0, 0x89, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x89, 0xc7, + 0x74, 0x16, 0x84, 0xc9, 0x74, 0x12, 0xba, 0x01, 0x00, 0x00, 0x00, 0x8d, + 0xb6, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x89, 0xd6 + }; + copy_block(op_prep_branch_bo_0100_code, 50); + inc_code_ptr(50); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_0101,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_0101 +{ + static const uint8 op_prep_branch_bo_0101_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x85, 0xf6, 0x0f, 0x95, 0xc1, 0x31, + 0xd2, 0x48, 0x85, 0xc0, 0x89, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x89, 0xc7, + 0x75, 0x16, 0x84, 0xc9, 0x74, 0x12, 0xba, 0x01, 0x00, 0x00, 0x00, 0x8d, + 0xb6, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x89, 0xd6 + }; + copy_block(op_prep_branch_bo_0101_code, 50); + inc_code_ptr(50); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_011x,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_011x +{ + static const uint8 op_prep_branch_bo_011x_code[] = { + 0x31, 0xc0, 0x85, 0xf6, 0x0f, 0x95, 0xc0, 0x89, 0xc6 + }; + copy_block(op_prep_branch_bo_011x_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_1x00,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_1x00 +{ + static const uint8 op_prep_branch_bo_1x00_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x89, 0x85, 0xa8, + 0x03, 0x00, 0x00, 0x89, 0xc7, 0x0f, 0x95, 0xc0, 0x0f, 0xb6, 0xc0, 0x89, + 0xc6 + }; + copy_block(op_prep_branch_bo_1x00_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_1x01,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_1x01 +{ + static const uint8 op_prep_branch_bo_1x01_code[] = { + 0x8b, 0x85, 0xa8, 0x03, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x89, 0x85, 0xa8, + 0x03, 0x00, 0x00, 0x89, 0xc7, 0x0f, 0x94, 0xc0, 0x0f, 0xb6, 0xc0, 0x89, + 0xc6 + }; + copy_block(op_prep_branch_bo_1x01_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_prep_branch_bo_1x1x,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_prep_branch_bo_1x1x +{ + static const uint8 op_prep_branch_bo_1x1x_code[] = { + 0xbe, 0x01, 0x00, 0x00, 0x00 + }; + copy_block(op_prep_branch_bo_1x1x_code, 5); + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_branch_chain_1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_chain_1 +{ + static const uint8 op_branch_chain_1_code[] = { + 0xe9, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_branch_chain_1_code, 5); + jmp_addr[0] = code_ptr() + 1; + inc_code_ptr(5); +} +#endif + +DEFINE_GEN(gen_op_branch_chain_2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_chain_2 +{ + static const uint8 op_branch_chain_2_code[] = { + 0x85, 0xf6, 0x74, 0x0c, 0xe9, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x0a, 0x90, + 0x8d, 0x74, 0x26, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_branch_chain_2_code, 21); + jmp_addr[0] = code_ptr() + 5; + jmp_addr[1] = code_ptr() + 17; + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_branch_1_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_1_T0 +{ + static const uint8 op_branch_1_T0_code[] = { + 0x89, 0x9d, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_1_T0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_branch_1_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_1_im +{ + static const uint8 op_branch_1_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0x85, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_1_im_code, 11); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_branch_2_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_2_T0_im +{ + static const uint8 op_branch_2_T0_im_code[] = { + 0x85, 0xf6, 0x89, 0xd8, 0x75, 0x05, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x85, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_2_T0_im_code, 17); + *(uint32_t *)(code_ptr() + 7) = param1 + 0; + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_branch_2_im_im,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_branch_2_im_im +{ + static const uint8 op_branch_2_im_im_code[] = { + 0x85, 0xf6, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x75, 0x05, 0xb8, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x85, 0xac, 0x03, 0x00, 0x00 + }; + copy_block(op_branch_2_im_im_code, 20); + *(uint32_t *)(code_ptr() + 3) = param1 + 0; + *(uint32_t *)(code_ptr() + 10) = param2 + 0; + inc_code_ptr(20); +} +#endif + +DEFINE_GEN(gen_op_record_cr0_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_record_cr0_T0 +{ + static const uint8 op_record_cr0_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x8b, 0x95, 0x90, 0x03, 0x00, + 0x00, 0xc1, 0xe0, 0x1c, 0x81, 0xe2, 0xff, 0xff, 0xff, 0x0f, 0x09, 0xc2, + 0x85, 0xdb, 0x7d, 0x08, 0x81, 0xca, 0x00, 0x00, 0x00, 0x80, 0xeb, 0x1c, + 0x7e, 0x0a, 0x81, 0xca, 0x00, 0x00, 0x00, 0x40, 0xeb, 0x12, 0x66, 0x90, + 0x81, 0xca, 0x00, 0x00, 0x00, 0x20, 0x8d, 0x76, 0x00, 0x8d, 0xbc, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x89, 0x95, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_record_cr0_T0_code, 70); + inc_code_ptr(70); +} +#endif + +DEFINE_GEN(gen_op_record_cr1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_record_cr1 +{ + static const uint8 op_record_cr1_code[] = { + 0x8b, 0x85, 0xa0, 0x03, 0x00, 0x00, 0x8b, 0x95, 0x90, 0x03, 0x00, 0x00, + 0xc1, 0xe8, 0x04, 0x81, 0xe2, 0xff, 0xff, 0xff, 0xf0, 0x25, 0x00, 0x00, + 0x00, 0x0f, 0x09, 0xc2, 0x89, 0x95, 0x90, 0x03, 0x00, 0x00 + }; + copy_block(op_record_cr1_code, 34); + inc_code_ptr(34); +} +#endif + +DEFINE_GEN(gen_op_compare_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_T0_T1 +{ + static const uint8 op_compare_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x39, 0xf3, 0x7d, 0x07, 0x89, + 0xc3, 0x83, 0xcb, 0x08, 0xeb, 0x1e, 0x7e, 0x0c, 0x89, 0xc3, 0x83, 0xcb, + 0x04, 0xeb, 0x15, 0x90, 0x8d, 0x74, 0x26, 0x00, 0x89, 0xc3, 0x83, 0xcb, + 0x02, 0x8d, 0x74, 0x26, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_compare_T0_T1_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_compare_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_T0_im +{ + static const uint8 op_compare_T0_im_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x81, 0xfb, 0x00, 0x00, 0x00, + 0x00, 0x7d, 0x07, 0x89, 0xc3, 0x83, 0xcb, 0x08, 0xeb, 0x1a, 0x7e, 0x08, + 0x89, 0xc3, 0x83, 0xcb, 0x04, 0xeb, 0x11, 0x90, 0x89, 0xc3, 0x83, 0xcb, + 0x02, 0x8d, 0x74, 0x26, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_compare_T0_im_code, 48); + *(uint32_t *)(code_ptr() + 9) = param1 + 0; + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_compare_T0_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_T0_0 +{ + static const uint8 op_compare_T0_0_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x85, 0xdb, 0x7d, 0x07, 0x89, + 0xc3, 0x83, 0xcb, 0x08, 0xeb, 0x1e, 0x7e, 0x0c, 0x89, 0xc3, 0x83, 0xcb, + 0x04, 0xeb, 0x15, 0x90, 0x8d, 0x74, 0x26, 0x00, 0x89, 0xc3, 0x83, 0xcb, + 0x02, 0x8d, 0x74, 0x26, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_compare_T0_0_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_compare_logical_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_logical_T0_T1 +{ + static const uint8 op_compare_logical_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x39, 0xf3, 0x73, 0x07, 0x89, + 0xc3, 0x83, 0xcb, 0x08, 0xeb, 0x1e, 0x76, 0x0c, 0x89, 0xc3, 0x83, 0xcb, + 0x04, 0xeb, 0x15, 0x90, 0x8d, 0x74, 0x26, 0x00, 0x89, 0xc3, 0x83, 0xcb, + 0x02, 0x8d, 0x74, 0x26, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_compare_logical_T0_T1_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_compare_logical_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_logical_T0_im +{ + static const uint8 op_compare_logical_T0_im_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x81, 0xfb, 0x00, 0x00, 0x00, + 0x00, 0x73, 0x07, 0x89, 0xc3, 0x83, 0xcb, 0x08, 0xeb, 0x1a, 0x76, 0x08, + 0x89, 0xc3, 0x83, 0xcb, 0x04, 0xeb, 0x11, 0x90, 0x89, 0xc3, 0x83, 0xcb, + 0x02, 0x8d, 0x74, 0x26, 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_compare_logical_T0_im_code, 48); + *(uint32_t *)(code_ptr() + 9) = param1 + 0; + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_compare_logical_T0_0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_compare_logical_T0_0 +{ + static const uint8 op_compare_logical_T0_0_code[] = { + 0x0f, 0xb6, 0x85, 0x94, 0x03, 0x00, 0x00, 0x85, 0xdb, 0x74, 0x07, 0x89, + 0xc3, 0x83, 0xcb, 0x04, 0xeb, 0x05, 0x89, 0xc3, 0x83, 0xcb, 0x02 + }; + copy_block(op_compare_logical_T0_0_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_divw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divw_T0_T1 +{ + static const uint8 op_divw_T0_T1_code[] = { + 0x83, 0xec, 0x04, 0x85, 0xf6, 0x89, 0x1c, 0x24, 0x74, 0x13, 0x81, 0xfb, + 0x00, 0x00, 0x00, 0x80, 0x0f, 0x94, 0xc2, 0x83, 0xfe, 0xff, 0x0f, 0x94, + 0xc0, 0x84, 0xc2, 0x74, 0x08, 0x8b, 0x0c, 0x24, 0xc1, 0xf9, 0x1f, 0xeb, + 0x0b, 0x8b, 0x04, 0x24, 0x99, 0xf7, 0xfe, 0x89, 0xc1, 0x8d, 0x76, 0x00, + 0x5a, 0x89, 0xcb + }; + copy_block(op_divw_T0_T1_code, 51); + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_divwo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divwo_T0_T1 +{ + static const uint8 op_divwo_T0_T1_code[] = { + 0x83, 0xec, 0x04, 0x85, 0xf6, 0x89, 0x1c, 0x24, 0x74, 0x13, 0x81, 0xfb, + 0x00, 0x00, 0x00, 0x80, 0x0f, 0x94, 0xc2, 0x83, 0xfe, 0xff, 0x0f, 0x94, + 0xc0, 0x84, 0xc2, 0x74, 0x16, 0x80, 0x8d, 0x94, 0x03, 0x00, 0x00, 0x01, + 0x8b, 0x0c, 0x24, 0xc6, 0x85, 0x95, 0x03, 0x00, 0x00, 0x01, 0xc1, 0xf9, + 0x1f, 0xeb, 0x1d, 0xc6, 0x85, 0x95, 0x03, 0x00, 0x00, 0x00, 0x8b, 0x04, + 0x24, 0x99, 0xf7, 0xfe, 0x89, 0xc1, 0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, + 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, 0x89, 0xcb, 0x59 + }; + copy_block(op_divwo_T0_T1_code, 83); + inc_code_ptr(83); +} +#endif + +DEFINE_GEN(gen_op_divwu_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divwu_T0_T1 +{ + static const uint8 op_divwu_T0_T1_code[] = { + 0x83, 0xec, 0x04, 0x31, 0xc9, 0x85, 0xf6, 0x89, 0x34, 0x24, 0x74, 0x08, + 0x89, 0xd8, 0x31, 0xd2, 0xf7, 0xf6, 0x89, 0xc1, 0x58, 0x89, 0xcb + }; + copy_block(op_divwu_T0_T1_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_divwuo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_divwuo_T0_T1 +{ + static const uint8 op_divwuo_T0_T1_code[] = { + 0x85, 0xf6, 0x89, 0xf1, 0x75, 0x10, 0x80, 0x8d, 0x94, 0x03, 0x00, 0x00, + 0x01, 0xc6, 0x85, 0x95, 0x03, 0x00, 0x00, 0x01, 0xeb, 0x0f, 0xc6, 0x85, + 0x95, 0x03, 0x00, 0x00, 0x00, 0x89, 0xd8, 0x31, 0xd2, 0xf7, 0xf6, 0x89, + 0xc1, 0x89, 0xcb + }; + copy_block(op_divwuo_T0_T1_code, 39); + inc_code_ptr(39); +} +#endif + +DEFINE_GEN(gen_op_mulhw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mulhw_T0_T1 +{ + static const uint8 op_mulhw_T0_T1_code[] = { + 0x89, 0xda, 0x89, 0xf0, 0xf7, 0xea, 0x89, 0xd3 + }; + copy_block(op_mulhw_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_mulhwu_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mulhwu_T0_T1 +{ + static const uint8 op_mulhwu_T0_T1_code[] = { + 0x89, 0xda, 0x89, 0xf0, 0xf7, 0xe2, 0x89, 0xd3 + }; + copy_block(op_mulhwu_T0_T1_code, 8); + inc_code_ptr(8); +} +#endif + +DEFINE_GEN(gen_op_mulli_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mulli_T0_im +{ + static const uint8 op_mulli_T0_im_code[] = { + 0x69, 0xdb, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_mulli_T0_im_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_mullwo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mullwo_T0_T1 +{ + static const uint8 op_mullwo_T0_T1_code[] = { + 0x89, 0xd8, 0x83, 0xec, 0x08, 0xf7, 0xee, 0x89, 0x04, 0x24, 0x8b, 0x04, + 0x24, 0x89, 0x54, 0x24, 0x04, 0x8b, 0x1c, 0x24, 0x99, 0x33, 0x54, 0x24, + 0x04, 0x33, 0x04, 0x24, 0x09, 0xd0, 0x0f, 0x95, 0xc0, 0x0f, 0xb6, 0xc0, + 0x88, 0x85, 0x95, 0x03, 0x00, 0x00, 0x08, 0x85, 0x94, 0x03, 0x00, 0x00, + 0x83, 0xc4, 0x08 + }; + copy_block(op_mullwo_T0_T1_code, 51); + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_slw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_slw_T0_T1 +{ + static const uint8 op_slw_T0_T1_code[] = { + 0x89, 0xf0, 0x89, 0xf1, 0xd3, 0xe3, 0xa8, 0x20, 0x74, 0x02, 0x31, 0xdb + }; + copy_block(op_slw_T0_T1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_srw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_srw_T0_T1 +{ + static const uint8 op_srw_T0_T1_code[] = { + 0x89, 0xf0, 0x89, 0xf1, 0xd3, 0xeb, 0xa8, 0x20, 0x74, 0x02, 0x31, 0xdb + }; + copy_block(op_srw_T0_T1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_sraw_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sraw_T0_T1 +{ + static const uint8 op_sraw_T0_T1_code[] = { + 0x89, 0xf0, 0x83, 0xec, 0x04, 0x83, 0xe0, 0x3f, 0x89, 0xc6, 0xc1, 0xe8, + 0x05, 0x84, 0xc0, 0x74, 0x11, 0x89, 0xd8, 0xc1, 0xe8, 0x1f, 0x89, 0xc3, + 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0xf7, 0xdb, 0xeb, 0x3b, 0xc6, 0x44, + 0x24, 0x03, 0x00, 0x89, 0xf1, 0x89, 0xda, 0xd3, 0xfa, 0x85, 0xdb, 0x79, + 0x1f, 0xb8, 0xff, 0xff, 0xff, 0xff, 0xd3, 0xe0, 0xf7, 0xd0, 0x85, 0xd8, + 0x74, 0x12, 0xc6, 0x44, 0x24, 0x03, 0x01, 0x8d, 0xb6, 0x00, 0x00, 0x00, + 0x00, 0x8d, 0xbc, 0x27, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xb6, 0x44, 0x24, + 0x03, 0x89, 0xd3, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x58 + }; + copy_block(op_sraw_T0_T1_code, 94); + inc_code_ptr(94); +} +#endif + +DEFINE_GEN(gen_op_sraw_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_sraw_T0_im +{ + static const uint8 op_sraw_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x89, 0xda, 0x88, 0xc1, 0x83, 0xec, 0x04, + 0xd3, 0xfa, 0x85, 0xdb, 0xc6, 0x44, 0x24, 0x03, 0x00, 0x79, 0x19, 0xb8, + 0xff, 0xff, 0xff, 0xff, 0xd3, 0xe0, 0xf7, 0xd0, 0x85, 0xc3, 0x74, 0x0c, + 0xc6, 0x44, 0x24, 0x03, 0x01, 0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xb6, 0x44, 0x24, 0x03, 0x89, 0xd3, 0x88, 0x85, 0x96, 0x03, 0x00, + 0x00, 0x5a + }; + copy_block(op_sraw_T0_im_code, 62); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + inc_code_ptr(62); +} +#endif + +DEFINE_GEN(gen_op_rlwimi_T0_T1,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rlwimi_T0_T1 +{ + static const uint8 op_rlwimi_T0_T1_code[] = { + 0xb9, 0x00, 0x00, 0x00, 0x00, 0x89, 0xf2, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0xd3, 0xc2, 0x21, 0xc2, 0xf7, 0xd0, 0x21, 0xd8, 0x89, 0xd3, 0x09, 0xc3 + }; + copy_block(op_rlwimi_T0_T1_code, 24); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + *(uint32_t *)(code_ptr() + 8) = param2 + 0; + inc_code_ptr(24); +} +#endif + +DEFINE_GEN(gen_op_rlwinm_T0_T1,void,(long param1, long param2)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rlwinm_T0_T1 +{ + static const uint8 op_rlwinm_T0_T1_code[] = { + 0x89, 0xd8, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xc0, 0x89, 0xc3, 0x81, + 0xe3, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_rlwinm_T0_T1_code, 17); + *(uint32_t *)(code_ptr() + 3) = param1 + 0; + *(uint32_t *)(code_ptr() + 13) = param2 + 0; + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_rlwnm_T0_T1,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_rlwnm_T0_T1 +{ + static const uint8 op_rlwnm_T0_T1_code[] = { + 0x89, 0xd8, 0x89, 0xf1, 0xd3, 0xc0, 0x89, 0xc3, 0x81, 0xe3, 0x00, 0x00, + 0x00, 0x00 + }; + copy_block(op_rlwnm_T0_T1_code, 14); + *(uint32_t *)(code_ptr() + 10) = param1 + 0; + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_cntlzw_32_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_cntlzw_32_T0 +{ + static const uint8 op_cntlzw_32_T0_code[] = { + 0xb8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xbd, 0xc3, 0xba, 0x1f, 0x00, 0x00, + 0x00, 0x89, 0xd3, 0x29, 0xc3 + }; + copy_block(op_cntlzw_32_T0_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_addo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addo_T0_T1 +{ + static const uint8 op_addo_T0_T1_code[] = { + 0x01, 0xf3, 0x0f, 0x90, 0xc2, 0x08, 0x95, 0x94, 0x03, 0x00, 0x00, 0x88, + 0x95, 0x95, 0x03, 0x00, 0x00 + }; + copy_block(op_addo_T0_T1_code, 17); + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_addc_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addc_T0_im +{ + static const uint8 op_addc_T0_im_code[] = { + 0x8d, 0x93, 0x00, 0x00, 0x00, 0x00, 0x39, 0xda, 0x0f, 0x92, 0x85, 0x96, + 0x03, 0x00, 0x00, 0x89, 0xd3 + }; + copy_block(op_addc_T0_im_code, 17); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(17); +} +#endif + +DEFINE_GEN(gen_op_addc_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addc_T0_T1 +{ + static const uint8 op_addc_T0_T1_code[] = { + 0x01, 0xf3, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_addc_T0_T1_code, 11); + inc_code_ptr(11); +} +#endif + +DEFINE_GEN(gen_op_addco_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addco_T0_T1 +{ + static const uint8 op_addco_T0_T1_code[] = { + 0x01, 0xf3, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x08, 0x95, 0x94, 0x03, + 0x00, 0x00, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x88, 0x95, 0x95, 0x03, + 0x00, 0x00 + }; + copy_block(op_addco_T0_T1_code, 26); + inc_code_ptr(26); +} +#endif + +DEFINE_GEN(gen_op_adde_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_adde_T0_T1 +{ + static const uint8 op_adde_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x11, + 0xf3, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_adde_T0_T1_code, 22); + inc_code_ptr(22); +} +#endif + +DEFINE_GEN(gen_op_addeo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addeo_T0_T1 +{ + static const uint8 op_addeo_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x11, + 0xf3, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x08, 0x95, 0x94, 0x03, 0x00, + 0x00, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x88, 0x95, 0x95, 0x03, 0x00, + 0x00 + }; + copy_block(op_addeo_T0_T1_code, 37); + inc_code_ptr(37); +} +#endif + +DEFINE_GEN(gen_op_addme_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addme_T0 +{ + static const uint8 op_addme_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x83, + 0xd3, 0xff, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_addme_T0_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_addmeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addmeo_T0 +{ + static const uint8 op_addmeo_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x83, + 0xd3, 0xff, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x08, 0x95, 0x94, 0x03, + 0x00, 0x00, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x88, 0x95, 0x95, 0x03, + 0x00, 0x00 + }; + copy_block(op_addmeo_T0_code, 38); + inc_code_ptr(38); +} +#endif + +DEFINE_GEN(gen_op_addze_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addze_T0 +{ + static const uint8 op_addze_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x83, + 0xd3, 0x00, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00 + }; + copy_block(op_addze_T0_code, 23); + inc_code_ptr(23); +} +#endif + +DEFINE_GEN(gen_op_addzeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_addzeo_T0 +{ + static const uint8 op_addzeo_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x0f, 0xba, 0xe0, 0x00, 0x83, + 0xd3, 0x00, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x08, 0x95, 0x94, 0x03, + 0x00, 0x00, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x88, 0x95, 0x95, 0x03, + 0x00, 0x00 + }; + copy_block(op_addzeo_T0_code, 38); + inc_code_ptr(38); +} +#endif + +DEFINE_GEN(gen_op_subf_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subf_T0_T1 +{ + static const uint8 op_subf_T0_T1_code[] = { + 0x89, 0xf0, 0x29, 0xd8, 0x89, 0xc3 + }; + copy_block(op_subf_T0_T1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_subfo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfo_T0_T1 +{ + static const uint8 op_subfo_T0_T1_code[] = { + 0x89, 0xf0, 0x29, 0xd8, 0x0f, 0x90, 0xc2, 0x08, 0x95, 0x94, 0x03, 0x00, + 0x00, 0x89, 0xc3, 0x88, 0x95, 0x95, 0x03, 0x00, 0x00 + }; + copy_block(op_subfo_T0_T1_code, 21); + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_subfc_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfc_T0_im +{ + static const uint8 op_subfc_T0_im_code[] = { + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x29, 0xd8, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x96, 0x85, 0x96, 0x03, 0x00, 0x00, 0x89, 0xc3 + }; + copy_block(op_subfc_T0_im_code, 21); + *(uint32_t *)(code_ptr() + 1) = param1 + 0; + *(uint32_t *)(code_ptr() + 8) = param1 + 0; + inc_code_ptr(21); +} +#endif + +DEFINE_GEN(gen_op_subfc_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfc_T0_T1 +{ + static const uint8 op_subfc_T0_T1_code[] = { + 0x89, 0xf2, 0x29, 0xda, 0xf5, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, + 0x00, 0x00, 0x89, 0xd3 + }; + copy_block(op_subfc_T0_T1_code, 16); + inc_code_ptr(16); +} +#endif + +DEFINE_GEN(gen_op_subfco_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfco_T0_T1 +{ + static const uint8 op_subfco_T0_T1_code[] = { + 0x89, 0xf1, 0x29, 0xd9, 0xf5, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x08, + 0x95, 0x94, 0x03, 0x00, 0x00, 0x89, 0xcb, 0x88, 0x85, 0x96, 0x03, 0x00, + 0x00, 0x88, 0x95, 0x95, 0x03, 0x00, 0x00 + }; + copy_block(op_subfco_T0_T1_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_subfe_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfe_T0_T1 +{ + static const uint8 op_subfe_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x89, 0xf2, 0x0f, 0xba, 0xe0, + 0x00, 0xf5, 0x19, 0xda, 0xf5, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, + 0x00, 0x00, 0x89, 0xd3 + }; + copy_block(op_subfe_T0_T1_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_subfeo_T0_T1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfeo_T0_T1 +{ + static const uint8 op_subfeo_T0_T1_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x89, 0xf1, 0x0f, 0xba, 0xe0, + 0x00, 0xf5, 0x19, 0xd9, 0xf5, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x08, + 0x95, 0x94, 0x03, 0x00, 0x00, 0x89, 0xcb, 0x88, 0x85, 0x96, 0x03, 0x00, + 0x00, 0x88, 0x95, 0x95, 0x03, 0x00, 0x00 + }; + copy_block(op_subfeo_T0_T1_code, 43); + inc_code_ptr(43); +} +#endif + +DEFINE_GEN(gen_op_subfme_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfme_T0 +{ + static const uint8 op_subfme_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0xba, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0xba, 0xe0, 0x00, 0xf5, 0x19, 0xda, 0xf5, 0x0f, 0x92, 0xc0, 0x88, + 0x85, 0x96, 0x03, 0x00, 0x00, 0x89, 0xd3 + }; + copy_block(op_subfme_T0_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_subfmeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfmeo_T0 +{ + static const uint8 op_subfmeo_T0_code[] = { + 0x83, 0xec, 0x04, 0xb9, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xb6, 0x95, 0x96, + 0x03, 0x00, 0x00, 0x89, 0xd0, 0x0f, 0xba, 0xe0, 0x00, 0xf5, 0x19, 0xd9, + 0xf5, 0x0f, 0x92, 0xc0, 0x0f, 0x90, 0xc2, 0x88, 0x85, 0x96, 0x03, 0x00, + 0x00, 0x89, 0xcb, 0x88, 0x95, 0x95, 0x03, 0x00, 0x00, 0x08, 0x95, 0x94, + 0x03, 0x00, 0x00, 0x59 + }; + copy_block(op_subfmeo_T0_code, 52); + inc_code_ptr(52); +} +#endif + +DEFINE_GEN(gen_op_subfze_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfze_T0 +{ + static const uint8 op_subfze_T0_code[] = { + 0x0f, 0xb6, 0x85, 0x96, 0x03, 0x00, 0x00, 0x31, 0xd2, 0x0f, 0xba, 0xe0, + 0x00, 0xf5, 0x19, 0xda, 0xf5, 0x0f, 0x92, 0xc0, 0x88, 0x85, 0x96, 0x03, + 0x00, 0x00, 0x89, 0xd3 + }; + copy_block(op_subfze_T0_code, 28); + inc_code_ptr(28); +} +#endif + +DEFINE_GEN(gen_op_subfzeo_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_subfzeo_T0 +{ + static const uint8 op_subfzeo_T0_code[] = { + 0x83, 0xec, 0x04, 0x31, 0xc9, 0x0f, 0xb6, 0x95, 0x96, 0x03, 0x00, 0x00, + 0x89, 0xd0, 0x0f, 0xba, 0xe0, 0x00, 0xf5, 0x19, 0xd9, 0xf5, 0x0f, 0x92, + 0xc0, 0x0f, 0x90, 0xc2, 0x88, 0x85, 0x96, 0x03, 0x00, 0x00, 0x89, 0xcb, + 0x88, 0x95, 0x95, 0x03, 0x00, 0x00, 0x08, 0x95, 0x94, 0x03, 0x00, 0x00, + 0x58 + }; + copy_block(op_subfzeo_T0_code, 49); + inc_code_ptr(49); +} +#endif + +DEFINE_GEN(gen_op_inc_32_mem,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_inc_32_mem +{ + static const uint8 op_inc_32_mem_code[] = { + 0xff, 0x05, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_inc_32_mem_code, 6); + *(uint32_t *)(code_ptr() + 2) = param1 + 0; + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_nego_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_nego_T0 +{ + static const uint8 op_nego_T0_code[] = { + 0x31, 0xd2, 0x81, 0xfb, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x94, 0xc2, 0x08, + 0x95, 0x94, 0x03, 0x00, 0x00, 0xf7, 0xdb, 0x88, 0x95, 0x95, 0x03, 0x00, + 0x00 + }; + copy_block(op_nego_T0_code, 25); + inc_code_ptr(25); +} +#endif + +DEFINE_GEN(gen_op_dcbz_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_dcbz_T0 +{ + static const uint8 op_dcbz_T0_code[] = { + 0x83, 0xe3, 0xe0, 0x31, 0xc9, 0x8d, 0x83, 0x00, 0x00, 0x00, 0x11, 0x89, + 0x8b, 0x00, 0x00, 0x00, 0x11, 0x31, 0xc9, 0x89, 0x8b, 0x04, 0x00, 0x00, + 0x11, 0xc7, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x40, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0xc7, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x40, + 0x14, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0xc7, 0x40, 0x1c, 0x00, 0x00, 0x00, 0x00 + }; + copy_block(op_dcbz_T0_code, 67); + inc_code_ptr(67); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_im +{ + static const uint8 op_lmw_T0_im_code[] = { + 0x83, 0xec, 0x04, 0x89, 0xd9, 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x3c, 0x24, 0x1f, 0x77, 0x27, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x8d, + 0x54, 0x85, 0x10, 0x90, 0x8d, 0x74, 0x26, 0x00, 0x8b, 0x81, 0x00, 0x00, + 0x00, 0x11, 0x0f, 0xc8, 0xff, 0x04, 0x24, 0x83, 0xc1, 0x04, 0x89, 0x02, + 0x83, 0xc2, 0x04, 0x83, 0x3c, 0x24, 0x1f, 0x76, 0xe7, 0x58 + }; + copy_block(op_lmw_T0_im_code, 58); + *(uint32_t *)(code_ptr() + 8) = param1 + 0; + *(uint32_t *)(code_ptr() + 19) = param1 + 0; + inc_code_ptr(58); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_im,void,(long param1)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_im +{ + static const uint8 op_stmw_T0_im_code[] = { + 0x83, 0xec, 0x04, 0x89, 0xd9, 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x3c, 0x24, 0x1f, 0x77, 0x27, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x8d, + 0x54, 0x85, 0x10, 0x90, 0x8d, 0x74, 0x26, 0x00, 0x8b, 0x02, 0x0f, 0xc8, + 0xff, 0x04, 0x24, 0x83, 0xc2, 0x04, 0x89, 0x81, 0x00, 0x00, 0x00, 0x11, + 0x83, 0xc1, 0x04, 0x83, 0x3c, 0x24, 0x1f, 0x76, 0xe7, 0x58 + }; + copy_block(op_stmw_T0_im_code, 58); + *(uint32_t *)(code_ptr() + 8) = param1 + 0; + *(uint32_t *)(code_ptr() + 19) = param1 + 0; + inc_code_ptr(58); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_29 +{ + static const uint8 op_lmw_T0_29_code[] = { + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x84, 0x00, + 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, + 0xc8, 0x89, 0x85, 0x88, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, + 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_29_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_28 +{ + static const uint8 op_lmw_T0_28_code[] = { + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x80, 0x00, + 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, + 0xc8, 0x89, 0x85, 0x84, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, + 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x88, 0x00, 0x00, 0x00, + 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, + 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_28_code, 65); + inc_code_ptr(65); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_27 +{ + static const uint8 op_lmw_T0_27_code[] = { + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x45, 0x7c, 0x83, + 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, + 0x80, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, + 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x84, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x88, 0x00, + 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, + 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_27_code, 79); + inc_code_ptr(79); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_26 +{ + static const uint8 op_lmw_T0_26_code[] = { + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x45, 0x78, 0x83, + 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x45, + 0x7c, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, + 0x89, 0x85, 0x80, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, + 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x84, 0x00, 0x00, 0x00, 0x83, + 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, + 0x88, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, + 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_26_code, 93); + inc_code_ptr(93); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_30 +{ + static const uint8 op_lmw_T0_30_code[] = { + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x88, 0x00, + 0x00, 0x00, 0x83, 0xc3, 0x04, 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, + 0xc8, 0x89, 0x85, 0x8c, 0x00, 0x00, 0x00 + }; + copy_block(op_lmw_T0_30_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_29 +{ + static const uint8 op_stmw_T0_29_code[] = { + 0x8b, 0x85, 0x84, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, + 0x00, 0x11, 0x8b, 0x85, 0x88, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, + 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x8c, 0x00, 0x00, + 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_stmw_T0_29_code, 48); + inc_code_ptr(48); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_28 +{ + static const uint8 op_stmw_T0_28_code[] = { + 0x8b, 0x85, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, + 0x00, 0x11, 0x8b, 0x85, 0x84, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, + 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x88, 0x00, 0x00, + 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, + 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, + 0x83, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_stmw_T0_28_code, 65); + inc_code_ptr(65); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_27 +{ + static const uint8 op_stmw_T0_27_code[] = { + 0x8b, 0x45, 0x7c, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, + 0x85, 0x80, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, + 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x84, 0x00, 0x00, 0x00, 0x83, 0xc3, + 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x88, + 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, + 0x00, 0x11, 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, + 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_stmw_T0_27_code, 79); + inc_code_ptr(79); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_26 +{ + static const uint8 op_stmw_T0_26_code[] = { + 0x8b, 0x45, 0x78, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, + 0x45, 0x7c, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, + 0x11, 0x8b, 0x85, 0x80, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, + 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x84, 0x00, 0x00, 0x00, + 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11, 0x8b, + 0x85, 0x88, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, 0xc8, 0x89, 0x83, + 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x83, 0xc3, + 0x04, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_stmw_T0_26_code, 93); + inc_code_ptr(93); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_30 +{ + static const uint8 op_stmw_T0_30_code[] = { + 0x8b, 0x85, 0x88, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, + 0x00, 0x11, 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x83, 0xc3, 0x04, 0x0f, + 0xc8, 0x89, 0x83, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_stmw_T0_30_code, 31); + inc_code_ptr(31); +} +#endif + +DEFINE_GEN(gen_op_lmw_T0_31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_lmw_T0_31 +{ + static const uint8 op_lmw_T0_31_code[] = { + 0x8b, 0x83, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x85, 0x8c, 0x00, + 0x00, 0x00 + }; + copy_block(op_lmw_T0_31_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_stmw_T0_31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_stmw_T0_31 +{ + static const uint8 op_stmw_T0_31_code[] = { + 0x8b, 0x85, 0x8c, 0x00, 0x00, 0x00, 0x0f, 0xc8, 0x89, 0x83, 0x00, 0x00, + 0x00, 0x11 + }; + copy_block(op_stmw_T0_31_code, 14); + inc_code_ptr(14); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR0 +{ + static const uint8 op_load_ad_VD_VR0_code[] = { + 0x8d, 0x85, 0x90, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR0_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR0 +{ + static const uint8 op_load_ad_V0_VR0_code[] = { + 0x8d, 0x9d, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR0 +{ + static const uint8 op_load_ad_V1_VR0_code[] = { + 0x8d, 0xb5, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR0 +{ + static const uint8 op_load_ad_V2_VR0_code[] = { + 0x8d, 0xbd, 0x90, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR0_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR1 +{ + static const uint8 op_load_ad_VD_VR1_code[] = { + 0x8d, 0x85, 0xa0, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR1_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR1 +{ + static const uint8 op_load_ad_V0_VR1_code[] = { + 0x8d, 0x9d, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR1 +{ + static const uint8 op_load_ad_V1_VR1_code[] = { + 0x8d, 0xb5, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR1 +{ + static const uint8 op_load_ad_V2_VR1_code[] = { + 0x8d, 0xbd, 0xa0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR1_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR2 +{ + static const uint8 op_load_ad_VD_VR2_code[] = { + 0x8d, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR2_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR2 +{ + static const uint8 op_load_ad_V0_VR2_code[] = { + 0x8d, 0x9d, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR2_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR2 +{ + static const uint8 op_load_ad_V1_VR2_code[] = { + 0x8d, 0xb5, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR2_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR2 +{ + static const uint8 op_load_ad_V2_VR2_code[] = { + 0x8d, 0xbd, 0xb0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR2_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR3 +{ + static const uint8 op_load_ad_VD_VR3_code[] = { + 0x8d, 0x85, 0xc0, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR3_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR3 +{ + static const uint8 op_load_ad_V0_VR3_code[] = { + 0x8d, 0x9d, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR3_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR3 +{ + static const uint8 op_load_ad_V1_VR3_code[] = { + 0x8d, 0xb5, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR3_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR3,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR3 +{ + static const uint8 op_load_ad_V2_VR3_code[] = { + 0x8d, 0xbd, 0xc0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR3_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR4 +{ + static const uint8 op_load_ad_VD_VR4_code[] = { + 0x8d, 0x85, 0xd0, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR4_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR4 +{ + static const uint8 op_load_ad_V0_VR4_code[] = { + 0x8d, 0x9d, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR4_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR4 +{ + static const uint8 op_load_ad_V1_VR4_code[] = { + 0x8d, 0xb5, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR4_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR4,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR4 +{ + static const uint8 op_load_ad_V2_VR4_code[] = { + 0x8d, 0xbd, 0xd0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR4_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR5 +{ + static const uint8 op_load_ad_VD_VR5_code[] = { + 0x8d, 0x85, 0xe0, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR5_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR5 +{ + static const uint8 op_load_ad_V0_VR5_code[] = { + 0x8d, 0x9d, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR5_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR5 +{ + static const uint8 op_load_ad_V1_VR5_code[] = { + 0x8d, 0xb5, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR5_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR5,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR5 +{ + static const uint8 op_load_ad_V2_VR5_code[] = { + 0x8d, 0xbd, 0xe0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR5_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR6 +{ + static const uint8 op_load_ad_VD_VR6_code[] = { + 0x8d, 0x85, 0xf0, 0x01, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR6_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR6 +{ + static const uint8 op_load_ad_V0_VR6_code[] = { + 0x8d, 0x9d, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR6_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR6 +{ + static const uint8 op_load_ad_V1_VR6_code[] = { + 0x8d, 0xb5, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR6_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR6,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR6 +{ + static const uint8 op_load_ad_V2_VR6_code[] = { + 0x8d, 0xbd, 0xf0, 0x01, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR6_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR7 +{ + static const uint8 op_load_ad_VD_VR7_code[] = { + 0x8d, 0x85, 0x00, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR7_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR7 +{ + static const uint8 op_load_ad_V0_VR7_code[] = { + 0x8d, 0x9d, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR7_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR7 +{ + static const uint8 op_load_ad_V1_VR7_code[] = { + 0x8d, 0xb5, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR7_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR7,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR7 +{ + static const uint8 op_load_ad_V2_VR7_code[] = { + 0x8d, 0xbd, 0x00, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR7_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR8 +{ + static const uint8 op_load_ad_VD_VR8_code[] = { + 0x8d, 0x85, 0x10, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR8_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR8 +{ + static const uint8 op_load_ad_V0_VR8_code[] = { + 0x8d, 0x9d, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR8_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR8 +{ + static const uint8 op_load_ad_V1_VR8_code[] = { + 0x8d, 0xb5, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR8_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR8,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR8 +{ + static const uint8 op_load_ad_V2_VR8_code[] = { + 0x8d, 0xbd, 0x10, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR8_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR9 +{ + static const uint8 op_load_ad_VD_VR9_code[] = { + 0x8d, 0x85, 0x20, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR9_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR9 +{ + static const uint8 op_load_ad_V0_VR9_code[] = { + 0x8d, 0x9d, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR9_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR9 +{ + static const uint8 op_load_ad_V1_VR9_code[] = { + 0x8d, 0xb5, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR9_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR9,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR9 +{ + static const uint8 op_load_ad_V2_VR9_code[] = { + 0x8d, 0xbd, 0x20, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR9_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR10 +{ + static const uint8 op_load_ad_VD_VR10_code[] = { + 0x8d, 0x85, 0x30, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR10_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR10 +{ + static const uint8 op_load_ad_V0_VR10_code[] = { + 0x8d, 0x9d, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR10_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR10 +{ + static const uint8 op_load_ad_V1_VR10_code[] = { + 0x8d, 0xb5, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR10_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR10,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR10 +{ + static const uint8 op_load_ad_V2_VR10_code[] = { + 0x8d, 0xbd, 0x30, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR10_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR11 +{ + static const uint8 op_load_ad_VD_VR11_code[] = { + 0x8d, 0x85, 0x40, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR11_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR11 +{ + static const uint8 op_load_ad_V0_VR11_code[] = { + 0x8d, 0x9d, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR11_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR11 +{ + static const uint8 op_load_ad_V1_VR11_code[] = { + 0x8d, 0xb5, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR11_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR11,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR11 +{ + static const uint8 op_load_ad_V2_VR11_code[] = { + 0x8d, 0xbd, 0x40, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR11_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR12 +{ + static const uint8 op_load_ad_VD_VR12_code[] = { + 0x8d, 0x85, 0x50, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR12_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR12 +{ + static const uint8 op_load_ad_V0_VR12_code[] = { + 0x8d, 0x9d, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR12_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR12 +{ + static const uint8 op_load_ad_V1_VR12_code[] = { + 0x8d, 0xb5, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR12_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR12,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR12 +{ + static const uint8 op_load_ad_V2_VR12_code[] = { + 0x8d, 0xbd, 0x50, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR12_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR13 +{ + static const uint8 op_load_ad_VD_VR13_code[] = { + 0x8d, 0x85, 0x60, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR13_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR13 +{ + static const uint8 op_load_ad_V0_VR13_code[] = { + 0x8d, 0x9d, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR13_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR13 +{ + static const uint8 op_load_ad_V1_VR13_code[] = { + 0x8d, 0xb5, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR13_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR13,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR13 +{ + static const uint8 op_load_ad_V2_VR13_code[] = { + 0x8d, 0xbd, 0x60, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR13_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR14 +{ + static const uint8 op_load_ad_VD_VR14_code[] = { + 0x8d, 0x85, 0x70, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR14_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR14 +{ + static const uint8 op_load_ad_V0_VR14_code[] = { + 0x8d, 0x9d, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR14_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR14 +{ + static const uint8 op_load_ad_V1_VR14_code[] = { + 0x8d, 0xb5, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR14_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR14,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR14 +{ + static const uint8 op_load_ad_V2_VR14_code[] = { + 0x8d, 0xbd, 0x70, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR14_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR15 +{ + static const uint8 op_load_ad_VD_VR15_code[] = { + 0x8d, 0x85, 0x80, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR15_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR15 +{ + static const uint8 op_load_ad_V0_VR15_code[] = { + 0x8d, 0x9d, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR15_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR15 +{ + static const uint8 op_load_ad_V1_VR15_code[] = { + 0x8d, 0xb5, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR15_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR15,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR15 +{ + static const uint8 op_load_ad_V2_VR15_code[] = { + 0x8d, 0xbd, 0x80, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR15_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR16 +{ + static const uint8 op_load_ad_VD_VR16_code[] = { + 0x8d, 0x85, 0x90, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR16_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR16 +{ + static const uint8 op_load_ad_V0_VR16_code[] = { + 0x8d, 0x9d, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR16_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR16 +{ + static const uint8 op_load_ad_V1_VR16_code[] = { + 0x8d, 0xb5, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR16_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR16,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR16 +{ + static const uint8 op_load_ad_V2_VR16_code[] = { + 0x8d, 0xbd, 0x90, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR16_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR17 +{ + static const uint8 op_load_ad_VD_VR17_code[] = { + 0x8d, 0x85, 0xa0, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR17_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR17 +{ + static const uint8 op_load_ad_V0_VR17_code[] = { + 0x8d, 0x9d, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR17_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR17 +{ + static const uint8 op_load_ad_V1_VR17_code[] = { + 0x8d, 0xb5, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR17_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR17,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR17 +{ + static const uint8 op_load_ad_V2_VR17_code[] = { + 0x8d, 0xbd, 0xa0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR17_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR18 +{ + static const uint8 op_load_ad_VD_VR18_code[] = { + 0x8d, 0x85, 0xb0, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR18_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR18 +{ + static const uint8 op_load_ad_V0_VR18_code[] = { + 0x8d, 0x9d, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR18_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR18 +{ + static const uint8 op_load_ad_V1_VR18_code[] = { + 0x8d, 0xb5, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR18_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR18,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR18 +{ + static const uint8 op_load_ad_V2_VR18_code[] = { + 0x8d, 0xbd, 0xb0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR18_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR19 +{ + static const uint8 op_load_ad_VD_VR19_code[] = { + 0x8d, 0x85, 0xc0, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR19_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR19 +{ + static const uint8 op_load_ad_V0_VR19_code[] = { + 0x8d, 0x9d, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR19_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR19 +{ + static const uint8 op_load_ad_V1_VR19_code[] = { + 0x8d, 0xb5, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR19_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR19,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR19 +{ + static const uint8 op_load_ad_V2_VR19_code[] = { + 0x8d, 0xbd, 0xc0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR19_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR20 +{ + static const uint8 op_load_ad_VD_VR20_code[] = { + 0x8d, 0x85, 0xd0, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR20_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR20 +{ + static const uint8 op_load_ad_V0_VR20_code[] = { + 0x8d, 0x9d, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR20_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR20 +{ + static const uint8 op_load_ad_V1_VR20_code[] = { + 0x8d, 0xb5, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR20_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR20,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR20 +{ + static const uint8 op_load_ad_V2_VR20_code[] = { + 0x8d, 0xbd, 0xd0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR20_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR21 +{ + static const uint8 op_load_ad_VD_VR21_code[] = { + 0x8d, 0x85, 0xe0, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR21_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR21 +{ + static const uint8 op_load_ad_V0_VR21_code[] = { + 0x8d, 0x9d, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR21_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR21 +{ + static const uint8 op_load_ad_V1_VR21_code[] = { + 0x8d, 0xb5, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR21_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR21,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR21 +{ + static const uint8 op_load_ad_V2_VR21_code[] = { + 0x8d, 0xbd, 0xe0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR21_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR22 +{ + static const uint8 op_load_ad_VD_VR22_code[] = { + 0x8d, 0x85, 0xf0, 0x02, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR22_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR22 +{ + static const uint8 op_load_ad_V0_VR22_code[] = { + 0x8d, 0x9d, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR22_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR22 +{ + static const uint8 op_load_ad_V1_VR22_code[] = { + 0x8d, 0xb5, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR22_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR22,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR22 +{ + static const uint8 op_load_ad_V2_VR22_code[] = { + 0x8d, 0xbd, 0xf0, 0x02, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR22_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR23 +{ + static const uint8 op_load_ad_VD_VR23_code[] = { + 0x8d, 0x85, 0x00, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR23_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR23 +{ + static const uint8 op_load_ad_V0_VR23_code[] = { + 0x8d, 0x9d, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR23_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR23 +{ + static const uint8 op_load_ad_V1_VR23_code[] = { + 0x8d, 0xb5, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR23_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR23,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR23 +{ + static const uint8 op_load_ad_V2_VR23_code[] = { + 0x8d, 0xbd, 0x00, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR23_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR24 +{ + static const uint8 op_load_ad_VD_VR24_code[] = { + 0x8d, 0x85, 0x10, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR24_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR24 +{ + static const uint8 op_load_ad_V0_VR24_code[] = { + 0x8d, 0x9d, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR24_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR24 +{ + static const uint8 op_load_ad_V1_VR24_code[] = { + 0x8d, 0xb5, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR24_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR24,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR24 +{ + static const uint8 op_load_ad_V2_VR24_code[] = { + 0x8d, 0xbd, 0x10, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR24_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR25 +{ + static const uint8 op_load_ad_VD_VR25_code[] = { + 0x8d, 0x85, 0x20, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR25_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR25 +{ + static const uint8 op_load_ad_V0_VR25_code[] = { + 0x8d, 0x9d, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR25_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR25 +{ + static const uint8 op_load_ad_V1_VR25_code[] = { + 0x8d, 0xb5, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR25_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR25,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR25 +{ + static const uint8 op_load_ad_V2_VR25_code[] = { + 0x8d, 0xbd, 0x20, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR25_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR26 +{ + static const uint8 op_load_ad_VD_VR26_code[] = { + 0x8d, 0x85, 0x30, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR26_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR26 +{ + static const uint8 op_load_ad_V0_VR26_code[] = { + 0x8d, 0x9d, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR26_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR26 +{ + static const uint8 op_load_ad_V1_VR26_code[] = { + 0x8d, 0xb5, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR26_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR26,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR26 +{ + static const uint8 op_load_ad_V2_VR26_code[] = { + 0x8d, 0xbd, 0x30, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR26_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR27 +{ + static const uint8 op_load_ad_VD_VR27_code[] = { + 0x8d, 0x85, 0x40, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR27_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR27 +{ + static const uint8 op_load_ad_V0_VR27_code[] = { + 0x8d, 0x9d, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR27_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR27 +{ + static const uint8 op_load_ad_V1_VR27_code[] = { + 0x8d, 0xb5, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR27_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR27,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR27 +{ + static const uint8 op_load_ad_V2_VR27_code[] = { + 0x8d, 0xbd, 0x40, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR27_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR28 +{ + static const uint8 op_load_ad_VD_VR28_code[] = { + 0x8d, 0x85, 0x50, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR28_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR28 +{ + static const uint8 op_load_ad_V0_VR28_code[] = { + 0x8d, 0x9d, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR28 +{ + static const uint8 op_load_ad_V1_VR28_code[] = { + 0x8d, 0xb5, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR28,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR28 +{ + static const uint8 op_load_ad_V2_VR28_code[] = { + 0x8d, 0xbd, 0x50, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR28_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR29 +{ + static const uint8 op_load_ad_VD_VR29_code[] = { + 0x8d, 0x85, 0x60, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR29_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR29 +{ + static const uint8 op_load_ad_V0_VR29_code[] = { + 0x8d, 0x9d, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR29 +{ + static const uint8 op_load_ad_V1_VR29_code[] = { + 0x8d, 0xb5, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR29,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR29 +{ + static const uint8 op_load_ad_V2_VR29_code[] = { + 0x8d, 0xbd, 0x60, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR29_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR30 +{ + static const uint8 op_load_ad_VD_VR30_code[] = { + 0x8d, 0x85, 0x70, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR30_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR30 +{ + static const uint8 op_load_ad_V0_VR30_code[] = { + 0x8d, 0x9d, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR30 +{ + static const uint8 op_load_ad_V1_VR30_code[] = { + 0x8d, 0xb5, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR30,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR30 +{ + static const uint8 op_load_ad_V2_VR30_code[] = { + 0x8d, 0xbd, 0x70, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR30_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_VD_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_VD_VR31 +{ + static const uint8 op_load_ad_VD_VR31_code[] = { + 0x8d, 0x85, 0x80, 0x03, 0x00, 0x00, 0x89, 0x85, 0x3c, 0x08, 0x0e, 0x00 + }; + copy_block(op_load_ad_VD_VR31_code, 12); + inc_code_ptr(12); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V0_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V0_VR31 +{ + static const uint8 op_load_ad_V0_VR31_code[] = { + 0x8d, 0x9d, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V0_VR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V1_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V1_VR31 +{ + static const uint8 op_load_ad_V1_VR31_code[] = { + 0x8d, 0xb5, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V1_VR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_ad_V2_VR31,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_ad_V2_VR31 +{ + static const uint8 op_load_ad_V2_VR31_code[] = { + 0x8d, 0xbd, 0x80, 0x03, 0x00, 0x00 + }; + copy_block(op_load_ad_V2_VR31_code, 6); + inc_code_ptr(6); +} +#endif + +DEFINE_GEN(gen_op_load_word_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_word_VD_T0 +{ + static const uint8 op_load_word_VD_T0_code[] = { + 0x89, 0xd8, 0x89, 0xda, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0xc1, 0xea, + 0x02, 0x83, 0xe0, 0xfc, 0x83, 0xe2, 0x03, 0x8b, 0x80, 0x00, 0x00, 0x00, + 0x11, 0x0f, 0xc8, 0x89, 0x04, 0x91 + }; + copy_block(op_load_word_VD_T0_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_store_word_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_word_VD_T0 +{ + static const uint8 op_store_word_VD_T0_code[] = { + 0x89, 0xd8, 0x8b, 0x95, 0x3c, 0x08, 0x0e, 0x00, 0x89, 0xd9, 0xc1, 0xe8, + 0x02, 0x83, 0xe1, 0xfc, 0x83, 0xe0, 0x03, 0x8b, 0x04, 0x82, 0x0f, 0xc8, + 0x89, 0x81, 0x00, 0x00, 0x00, 0x11 + }; + copy_block(op_store_word_VD_T0_code, 30); + inc_code_ptr(30); +} +#endif + +DEFINE_GEN(gen_op_load_vect_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_load_vect_VD_T0 +{ + static const uint8 op_load_vect_VD_T0_code[] = { + 0x89, 0xda, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x83, 0xe2, 0xf0, 0x8b, + 0x82, 0x00, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x01, 0x8b, 0x8d, 0x3c, + 0x08, 0x0e, 0x00, 0x8b, 0x82, 0x04, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, + 0x41, 0x04, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x8b, 0x82, 0x08, 0x00, + 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x41, 0x08, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, + 0x00, 0x8b, 0x82, 0x0c, 0x00, 0x00, 0x11, 0x0f, 0xc8, 0x89, 0x41, 0x0c + }; + copy_block(op_load_vect_VD_T0_code, 72); + inc_code_ptr(72); +} +#endif + +DEFINE_GEN(gen_op_store_vect_VD_T0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_vect_VD_T0 +{ + static const uint8 op_store_vect_VD_T0_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x89, 0xda, 0x83, 0xe2, 0xf0, 0x8b, + 0x00, 0x0f, 0xc8, 0x89, 0x82, 0x00, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x3c, + 0x08, 0x0e, 0x00, 0x8b, 0x40, 0x04, 0x0f, 0xc8, 0x89, 0x82, 0x04, 0x00, + 0x00, 0x11, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x8b, 0x40, 0x08, 0x0f, + 0xc8, 0x89, 0x82, 0x08, 0x00, 0x00, 0x11, 0x8b, 0x85, 0x3c, 0x08, 0x0e, + 0x00, 0x8b, 0x40, 0x0c, 0x0f, 0xc8, 0x89, 0x82, 0x0c, 0x00, 0x00, 0x11 + }; + copy_block(op_store_vect_VD_T0_code, 72); + inc_code_ptr(72); +} +#endif + +DEFINE_GEN(gen_op_record_cr6_VD,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_record_cr6_VD +{ + static const uint8 op_record_cr6_VD_code[] = { + 0x83, 0xec, 0x04, 0x8b, 0x95, 0x3c, 0x08, 0x0e, 0x00, 0xc7, 0x04, 0x24, + 0x00, 0x00, 0x00, 0x00, 0x8b, 0x0a, 0x8b, 0x42, 0x04, 0x21, 0xc8, 0x8b, + 0x4a, 0x08, 0x21, 0xc8, 0x23, 0x42, 0x0c, 0x8d, 0x8d, 0x3c, 0x08, 0x0e, + 0x00, 0x40, 0x75, 0x09, 0xc7, 0x04, 0x24, 0x08, 0x00, 0x00, 0x00, 0xeb, + 0x1f, 0x8b, 0x11, 0x8b, 0x0a, 0x8b, 0x42, 0x04, 0x09, 0xc8, 0x8b, 0x4a, + 0x08, 0x09, 0xc8, 0x0b, 0x42, 0x0c, 0x75, 0x0c, 0xc7, 0x04, 0x24, 0x02, + 0x00, 0x00, 0x00, 0x90, 0x8d, 0x74, 0x26, 0x00, 0xc1, 0x24, 0x24, 0x04, + 0x8b, 0x85, 0x90, 0x03, 0x00, 0x00, 0x8b, 0x0c, 0x24, 0x25, 0x0f, 0xff, + 0xff, 0xff, 0x09, 0xc8, 0x89, 0x85, 0x90, 0x03, 0x00, 0x00, 0x58 + }; + copy_block(op_record_cr6_VD_code, 107); + inc_code_ptr(107); +} +#endif + +DEFINE_GEN(gen_op_mfvscr_VD,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mfvscr_VD +{ + static const uint8 op_mfvscr_VD_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xc7, 0x40, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xc7, 0x40, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x8b, 0x95, 0x3c, 0x08, 0x0e, 0x00, 0x8b, 0x85, 0x98, 0x03, + 0x00, 0x00, 0x89, 0x42, 0x0c + }; + copy_block(op_mfvscr_VD_code, 53); + inc_code_ptr(53); +} +#endif + +DEFINE_GEN(gen_op_mtvscr_V0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mtvscr_V0 +{ + static const uint8 op_mtvscr_V0_code[] = { + 0x8b, 0x43, 0x0c, 0x89, 0x85, 0x98, 0x03, 0x00, 0x00 + }; + copy_block(op_mtvscr_V0_code, 9); + inc_code_ptr(9); +} +#endif + +DEFINE_GEN(gen_op_emms,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_emms +{ + static const uint8 op_emms_code[] = { + 0x0f, 0x77 + }; + copy_block(op_emms_code, 2); + inc_code_ptr(2); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpequb,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpequb +{ + static const uint8 op_mmx_vcmpequb_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0x74, 0x06, 0x0f, 0x74, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vcmpequb_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpequh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpequh +{ + static const uint8 op_mmx_vcmpequh_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0x75, 0x06, 0x0f, 0x75, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vcmpequh_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpequw,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpequw +{ + static const uint8 op_mmx_vcmpequw_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0x76, 0x06, 0x0f, 0x76, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vcmpequw_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpgtsb,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpgtsb +{ + static const uint8 op_mmx_vcmpgtsb_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0x64, 0x06, 0x0f, 0x64, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vcmpgtsb_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpgtsh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpgtsh +{ + static const uint8 op_mmx_vcmpgtsh_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0x65, 0x06, 0x0f, 0x65, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vcmpgtsh_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vcmpgtsw,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vcmpgtsw +{ + static const uint8 op_mmx_vcmpgtsw_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0x66, 0x06, 0x0f, 0x66, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vcmpgtsw_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vaddubm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vaddubm +{ + static const uint8 op_mmx_vaddubm_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xfc, 0x06, 0x0f, 0xfc, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vaddubm_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vadduhm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vadduhm +{ + static const uint8 op_mmx_vadduhm_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xfd, 0x06, 0x0f, 0xfd, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vadduhm_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vadduwm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vadduwm +{ + static const uint8 op_mmx_vadduwm_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xfe, 0x06, 0x0f, 0xfe, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vadduwm_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vsububm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vsububm +{ + static const uint8 op_mmx_vsububm_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xf8, 0x06, 0x0f, 0xf8, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vsububm_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vsubuhm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vsubuhm +{ + static const uint8 op_mmx_vsubuhm_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xf9, 0x06, 0x0f, 0xf9, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vsubuhm_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vsubuwm,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vsubuwm +{ + static const uint8 op_mmx_vsubuwm_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xfa, 0x06, 0x0f, 0xfa, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vsubuwm_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vand,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vand +{ + static const uint8 op_mmx_vand_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xdb, 0x06, 0x0f, 0xdb, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vand_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vandc,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vandc +{ + static const uint8 op_mmx_vandc_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x06, 0x0f, 0x6f, 0x4e, + 0x08, 0x0f, 0xdf, 0x03, 0x0f, 0xdf, 0x4b, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vandc_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vor,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vor +{ + static const uint8 op_mmx_vor_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xeb, 0x06, 0x0f, 0xeb, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vor_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vxor,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vxor +{ + static const uint8 op_mmx_vxor_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xef, 0x06, 0x0f, 0xef, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vxor_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vmaxub,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vmaxub +{ + static const uint8 op_mmx_vmaxub_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xde, 0x06, 0x0f, 0xde, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vmaxub_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vminub,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vminub +{ + static const uint8 op_mmx_vminub_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xda, 0x06, 0x0f, 0xda, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vminub_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vmaxsh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vmaxsh +{ + static const uint8 op_mmx_vmaxsh_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xee, 0x06, 0x0f, 0xee, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vmaxsh_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_mmx_vminsh,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_mmx_vminsh +{ + static const uint8 op_mmx_vminsh_code[] = { + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0x0f, 0x6f, 0x03, 0x0f, 0x6f, 0x4b, + 0x08, 0x0f, 0xea, 0x06, 0x0f, 0xea, 0x4e, 0x08, 0x0f, 0x7f, 0x00, 0x0f, + 0x7f, 0x48, 0x08 + }; + copy_block(op_mmx_vminsh_code, 27); + inc_code_ptr(27); +} +#endif + +DEFINE_GEN(gen_op_store_T0_XER,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_store_T0_XER +{ + static const uint8 op_store_T0_XER_code[] = { + 0x83, 0xec, 0x04, 0x8d, 0x85, 0x94, 0x03, 0x00, 0x00, 0x89, 0xda, 0x89, + 0x04, 0x24, 0x89, 0xd8, 0xc1, 0xe8, 0x1f, 0x88, 0x85, 0x94, 0x03, 0x00, + 0x00, 0x8b, 0x0c, 0x24, 0x89, 0xd8, 0xc1, 0xe8, 0x1e, 0x83, 0xe2, 0x7f, + 0x83, 0xe0, 0x01, 0x88, 0x41, 0x01, 0x89, 0xd8, 0xc1, 0xe8, 0x1d, 0x88, + 0x51, 0x03, 0x83, 0xe0, 0x01, 0x88, 0x41, 0x02, 0x58 + }; + copy_block(op_store_T0_XER_code, 57); + inc_code_ptr(57); +} +#endif + +DEFINE_GEN(gen_op_jump_next_A0,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_jump_next_A0 +{ + static const uint8 op_jump_next_A0_code[] = { + 0x8b, 0x95, 0xac, 0x03, 0x00, 0x00, 0x89, 0xd8, 0x39, 0x13, 0x74, 0x24, + 0x89, 0xd0, 0xc1, 0xe8, 0x02, 0x25, 0xff, 0x7f, 0x00, 0x00, 0x8b, 0x84, + 0x85, 0xfc, 0x07, 0x0c, 0x00, 0x85, 0xc0, 0x74, 0x04, 0x39, 0x10, 0x74, + 0x02, 0x31, 0xc0, 0x85, 0xc0, 0x74, 0x08, 0x90, 0x8d, 0x74, 0x26, 0x00, + 0xff, 0x60, 0x40 + }; + copy_block(op_jump_next_A0_code, 51); + inc_code_ptr(51); +} +#endif + +DEFINE_GEN(gen_op_vand_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vand_VD_V0_V1 +{ + static const uint8 op_vand_VD_V0_V1_code[] = { + 0x8b, 0x16, 0x8b, 0x03, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x21, 0xd0, + 0x8b, 0x53, 0x04, 0x23, 0x56, 0x04, 0x89, 0x01, 0x89, 0x51, 0x04, 0x8b, + 0x56, 0x08, 0x8b, 0x43, 0x08, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x21, + 0xd0, 0x8b, 0x53, 0x0c, 0x23, 0x56, 0x0c, 0x89, 0x41, 0x08, 0x89, 0x51, + 0x0c + }; + copy_block(op_vand_VD_V0_V1_code, 49); + inc_code_ptr(49); +} +#endif + +DEFINE_GEN(gen_op_vandc_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vandc_VD_V0_V1 +{ + static const uint8 op_vandc_VD_V0_V1_code[] = { + 0x8b, 0x06, 0x8b, 0x56, 0x04, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0xf7, + 0xd0, 0xf7, 0xd2, 0x23, 0x03, 0x23, 0x53, 0x04, 0x89, 0x01, 0x89, 0x51, + 0x04, 0x8b, 0x46, 0x08, 0x8b, 0x56, 0x0c, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, + 0x00, 0xf7, 0xd0, 0xf7, 0xd2, 0x23, 0x43, 0x08, 0x23, 0x53, 0x0c, 0x89, + 0x41, 0x08, 0x89, 0x51, 0x0c + }; + copy_block(op_vandc_VD_V0_V1_code, 53); + inc_code_ptr(53); +} +#endif + +DEFINE_GEN(gen_op_vnor_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vnor_VD_V0_V1 +{ + static const uint8 op_vnor_VD_V0_V1_code[] = { + 0x8b, 0x16, 0x8b, 0x03, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x09, 0xd0, + 0x8b, 0x53, 0x04, 0xf7, 0xd0, 0x0b, 0x56, 0x04, 0x89, 0x01, 0xf7, 0xd2, + 0x89, 0x51, 0x04, 0x8b, 0x56, 0x08, 0x8b, 0x43, 0x08, 0x8b, 0x8d, 0x3c, + 0x08, 0x0e, 0x00, 0x09, 0xd0, 0x8b, 0x53, 0x0c, 0x0b, 0x56, 0x0c, 0xf7, + 0xd0, 0x89, 0x41, 0x08, 0xf7, 0xd2, 0x89, 0x51, 0x0c + }; + copy_block(op_vnor_VD_V0_V1_code, 57); + inc_code_ptr(57); +} +#endif + +DEFINE_GEN(gen_op_vor_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vor_VD_V0_V1 +{ + static const uint8 op_vor_VD_V0_V1_code[] = { + 0x8b, 0x16, 0x8b, 0x03, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x09, 0xd0, + 0x8b, 0x53, 0x04, 0x0b, 0x56, 0x04, 0x89, 0x01, 0x89, 0x51, 0x04, 0x8b, + 0x56, 0x08, 0x8b, 0x43, 0x08, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x09, + 0xd0, 0x8b, 0x53, 0x0c, 0x0b, 0x56, 0x0c, 0x89, 0x41, 0x08, 0x89, 0x51, + 0x0c + }; + copy_block(op_vor_VD_V0_V1_code, 49); + inc_code_ptr(49); +} +#endif + +DEFINE_GEN(gen_op_vxor_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vxor_VD_V0_V1 +{ + static const uint8 op_vxor_VD_V0_V1_code[] = { + 0x8b, 0x16, 0x8b, 0x03, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x31, 0xd0, + 0x8b, 0x53, 0x04, 0x33, 0x56, 0x04, 0x89, 0x01, 0x89, 0x51, 0x04, 0x8b, + 0x56, 0x08, 0x8b, 0x43, 0x08, 0x8b, 0x8d, 0x3c, 0x08, 0x0e, 0x00, 0x31, + 0xd0, 0x8b, 0x53, 0x0c, 0x33, 0x56, 0x0c, 0x89, 0x41, 0x08, 0x89, 0x51, + 0x0c + }; + copy_block(op_vxor_VD_V0_V1_code, 49); + inc_code_ptr(49); +} +#endif + +DEFINE_GEN(gen_op_vaddfp_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vaddfp_VD_V0_V1 +{ + static const uint8 op_vaddfp_VD_V0_V1_code[] = { + 0xd9, 0x06, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd8, 0x03, 0xd9, 0x18, + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x46, 0x04, 0xd8, 0x43, 0x04, + 0xd9, 0x58, 0x04, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x46, 0x08, + 0xd8, 0x43, 0x08, 0xd9, 0x58, 0x08, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, + 0xd9, 0x46, 0x0c, 0xd8, 0x43, 0x0c, 0xd9, 0x58, 0x0c + }; + copy_block(op_vaddfp_VD_V0_V1_code, 57); + inc_code_ptr(57); +} +#endif + +DEFINE_GEN(gen_op_vsubfp_VD_V0_V1,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vsubfp_VD_V0_V1 +{ + static const uint8 op_vsubfp_VD_V0_V1_code[] = { + 0xd9, 0x06, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd8, 0x2b, 0xd9, 0x18, + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x46, 0x04, 0xd8, 0x6b, 0x04, + 0xd9, 0x58, 0x04, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x46, 0x08, + 0xd8, 0x6b, 0x08, 0xd9, 0x58, 0x08, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, + 0xd9, 0x46, 0x0c, 0xd8, 0x6b, 0x0c, 0xd9, 0x58, 0x0c + }; + copy_block(op_vsubfp_VD_V0_V1_code, 57); + inc_code_ptr(57); +} +#endif + +DEFINE_GEN(gen_op_vmaddfp_VD_V0_V1_V2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vmaddfp_VD_V0_V1_V2 +{ + static const uint8 op_vmaddfp_VD_V0_V1_V2_code[] = { + 0xd9, 0x07, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd8, 0x0b, 0xd8, 0x06, + 0xd9, 0x18, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x47, 0x04, 0xd8, + 0x4b, 0x04, 0xd8, 0x46, 0x04, 0xd9, 0x58, 0x04, 0x8b, 0x85, 0x3c, 0x08, + 0x0e, 0x00, 0xd9, 0x47, 0x08, 0xd8, 0x4b, 0x08, 0xd8, 0x46, 0x08, 0xd9, + 0x58, 0x08, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x47, 0x0c, 0xd8, + 0x4b, 0x0c, 0xd8, 0x46, 0x0c, 0xd9, 0x58, 0x0c + }; + copy_block(op_vmaddfp_VD_V0_V1_V2_code, 68); + inc_code_ptr(68); +} +#endif + +DEFINE_GEN(gen_op_vnmsubfp_VD_V0_V1_V2,void,(void)) +#ifdef DYNGEN_IMPL +#define HAVE_gen_op_vnmsubfp_VD_V0_V1_V2 +{ + static const uint8 op_vnmsubfp_VD_V0_V1_V2_code[] = { + 0xd9, 0x07, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd8, 0x0b, 0xd8, 0x26, + 0xd9, 0xe0, 0xd9, 0x18, 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x47, + 0x04, 0xd8, 0x4b, 0x04, 0xd8, 0x66, 0x04, 0xd9, 0xe0, 0xd9, 0x58, 0x04, + 0x8b, 0x85, 0x3c, 0x08, 0x0e, 0x00, 0xd9, 0x47, 0x08, 0xd8, 0x4b, 0x08, + 0xd8, 0x66, 0x08, 0xd9, 0xe0, 0xd9, 0x58, 0x08, 0x8b, 0x85, 0x3c, 0x08, + 0x0e, 0x00, 0xd9, 0x47, 0x0c, 0xd8, 0x4b, 0x0c, 0xd8, 0x66, 0x0c, 0xd9, + 0xe0, 0xd9, 0x58, 0x0c + }; + copy_block(op_vnmsubfp_VD_V0_V1_V2_code, 76); + inc_code_ptr(76); +} +#endif + +#undef DEFINE_CST +#undef DEFINE_GEN diff --git a/SheepShaver/src/Windows/kernel_windows.cpp b/SheepShaver/src/Windows/kernel_windows.cpp deleted file mode 120000 index d9c12cdc5..000000000 --- a/SheepShaver/src/Windows/kernel_windows.cpp +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/Windows/kernel_windows.cpp \ No newline at end of file diff --git a/SheepShaver/src/Windows/kernel_windows.h b/SheepShaver/src/Windows/kernel_windows.h deleted file mode 120000 index 10e68cebd..000000000 --- a/SheepShaver/src/Windows/kernel_windows.h +++ /dev/null @@ -1 +0,0 @@ -../../../BasiliskII/src/Windows/kernel_windows.h \ No newline at end of file diff --git a/SheepShaver/src/Windows/main_windows.cpp b/SheepShaver/src/Windows/main_windows.cpp index 2d63d76b8..c9cb4a6f2 100755 --- a/SheepShaver/src/Windows/main_windows.cpp +++ b/SheepShaver/src/Windows/main_windows.cpp @@ -44,7 +44,7 @@ #include "vm_alloc.h" #include "sigsegv.h" #include "util_windows.h" -#include "kernel_windows.h" +//#include "kernel_windows.h" #define DEBUG 0 #include "debug.h" @@ -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,12 +164,8 @@ 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)); + printf(GetString(STR_ABOUT_TEXT)); // Read preferences PrefsInit(NULL, argc, argv); @@ -207,12 +199,8 @@ int main(int argc, char **argv) if (!check_drivers()) QuitEmulator(); - // Load win32 libraries - KernelInit(); - - // FIXME: default to DIB driver - if (getenv("SDL_VIDEODRIVER") == NULL) - putenv("SDL_VIDEODRIVER=windib"); +// // Load win32 libraries +// KernelInit(); // Initialize SDL system int sdl_flags = 0; @@ -253,6 +241,10 @@ int main(int argc, char **argv) TimebaseSpeed = 25000000; // Default: 25MHz PVR = 0x000c0000; // Default: 7400 (with AltiVec) D(bug("PVR: %08x (assumed)\n", PVR)); + { + int pref_cpu_clock = PrefsFindInt32("cpuclock"); + if (pref_cpu_clock) CPUClockSpeed = 1000000 * pref_cpu_clock; + } // Init system routines SysInit(); @@ -294,24 +286,28 @@ 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)); // Create area for Mac RAM RAMSize = PrefsFindInt32("ramsize"); - if (RAMSize < 8*1024*1024) { + if (RAMSize <= 1000) { + RAMSize *= 1024 * 1024; + } + if (RAMSize < 16 * 1024 * 1024) { WarningAlert(GetString(STR_SMALL_RAM_WARN)); - RAMSize = 8*1024*1024; + RAMSize = 16 * 1024 * 1024; } - RAMBase = 0; if (vm_mac_acquire(RAMBase, RAMSize) < 0) { sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno)); ErrorAlert(str); @@ -359,7 +355,7 @@ int main(int argc, char **argv) } } delete[] rom_tmp; - + // Initialize native timers timer_init(); @@ -395,13 +391,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(); @@ -446,8 +440,8 @@ static void Quit(void) // Exit preferences PrefsExit(); - // Release win32 libraries - KernelExit(); +// // Release win32 libraries +// KernelExit(); #ifdef ENABLE_MON // Exit mon @@ -770,11 +764,21 @@ void SheepMem::Exit(void) #ifdef USE_SDL_VIDEO #include +extern SDL_Window *sdl_window; HWND GetMainWindowHandle(void) { SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); - return SDL_GetWMInfo(&wmInfo) ? wmInfo.window : NULL; + if (!sdl_window) { + return NULL; + } + if (!SDL_GetWindowWMInfo(sdl_window, &wmInfo)) { + return NULL; + } + if (wmInfo.subsystem != SDL_SYSWM_WINDOWS) { + return NULL; + } + return wmInfo.info.win.window; } #endif diff --git a/SheepShaver/src/Windows/prefs_windows.cpp b/SheepShaver/src/Windows/prefs_windows.cpp index 3f83b045d..9c3865bf5 100755 --- a/SheepShaver/src/Windows/prefs_windows.cpp +++ b/SheepShaver/src/Windows/prefs_windows.cpp @@ -36,9 +36,6 @@ prefs_desc platform_prefs_items[] = { {"keycodefile", TYPE_STRING, false, "path of keycode translation file"}, {"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"}, {"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"}, -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, {"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"}, {"keycodefile", TYPE_STRING, false, "path of keycode translation file"}, @@ -57,6 +54,10 @@ prefs_desc platform_prefs_items[] = { {"tcp_port", TYPE_STRING, false, "TCP ports list"}, {"portfile0", TYPE_STRING, false, "output file for serial port 0"}, {"portfile1", TYPE_STRING, false, "output file for serial port 1"}, +#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 }; @@ -131,9 +132,6 @@ void AddPlatformPrefsDefaults(void) PrefsReplaceInt32("mousewheellines", 3); PrefsAddInt32("windowmodes", 3); PrefsAddInt32("screenmodes", 0x3f); -#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION - PrefsAddBool("ignoresegv", false); -#endif PrefsAddBool("idlewait", true); PrefsReplaceBool("etherpermanentaddress", true); PrefsReplaceInt32("ethermulticastmode", 0); @@ -143,4 +141,8 @@ void AddPlatformPrefsDefaults(void) PrefsReplaceString("serialb", "COM2"); PrefsReplaceString("portfile0", "C:\\B2TEMP0.OUT"); PrefsReplaceString("portfile1", "C:\\B2TEMP1.OUT"); +#ifdef USE_SDL_VIDEO + PrefsReplaceString("sdlrender", "software"); + PrefsReplaceBool("sdl_vsync", false); +#endif } diff --git a/SheepShaver/src/Windows/sysdeps.h b/SheepShaver/src/Windows/sysdeps.h index f5aaee125..3db649c8b 100755 --- a/SheepShaver/src/Windows/sysdeps.h +++ b/SheepShaver/src/Windows/sysdeps.h @@ -28,18 +28,18 @@ #include "config.h" #include "user_strings_windows.h" -#ifndef STDC_HEADERS -#error "You don't have ANSI C header files." -#endif - #include #include #include #include #include +#include +#undef _TEXT #include #ifdef __WIN32__ +#define WIN32_LEAN_AND_MEAN #include +#include #endif #include @@ -145,6 +145,19 @@ static inline uint32 do_opt_bswap_32(uint32 x) __asm__ __volatile__ ("bswap %0" : "=r" (v) : "0" (x)); return v; } + +#if defined(__CYGWIN__) || defined(__MINGW32__) + +#define opt_bswap_16 do_opt_bswap_16 +static inline uint16 do_opt_bswap_16(uint16 x) +{ + uint16 v; + __asm__ __volatile__ ("rolw $8, %0" : "=r" (v) : "0" (x)); + return v; +} + +#endif + #endif #endif @@ -225,6 +238,7 @@ static inline uint64 tswap64(uint64 x) { return bswap_64(x); } (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) #if defined(__GNUC__) +#if 0 #define do_byteswap_16(x) \ (__extension__ \ ({ register uint16 __v, __x = (x); \ @@ -243,8 +257,19 @@ static inline uint64 tswap64(uint64 x) { return bswap_64(x); } __v = do_byteswap_32_g(__x); \ __v; })) #else -#define do_byteswap_16(x) do_byteswap_16_g(x) -#define do_byteswap_32(x) do_byteswap_32_g(x) + +inline uint16 sysdeps_inline_bswap_16(uint16 x) +{ + return ((x & 0xff) << 8) | ((x >> 8) & 0xff); +} + +#define do_byteswap_16(x) (sysdeps_inline_bswap_16(x)) +#define do_byteswap_32(x) (do_byteswap_32_g(x)) + +#endif +#else +#define do_byteswap_16(x) (do_byteswap_16_g((uint16)(x))) +#define do_byteswap_32(x) (do_byteswap_32_g(x)) #endif #if defined(__i386__) || defined(__x86_64__) diff --git a/SheepShaver/src/Windows/user_strings_windows.cpp b/SheepShaver/src/Windows/user_strings_windows.cpp index 32e52d25b..eb12de57d 100755 --- a/SheepShaver/src/Windows/user_strings_windows.cpp +++ b/SheepShaver/src/Windows/user_strings_windows.cpp @@ -20,7 +20,7 @@ #include "sysdeps.h" #include "user_strings.h" - +#include "util_windows.h" // Platform-specific string definitions user_string_def platform_strings[] = { @@ -86,7 +86,11 @@ static const char *get_volume_name(void) HKEY hHelpKey; DWORD key_type, cbData; - static char volume[256]; + #ifdef _UNICODE + static char out_volume[256]; + #endif + + static TCHAR volume[256]; memset(volume, 0, sizeof(volume)); // Try Windows 2000 key first @@ -123,14 +127,19 @@ static const char *get_volume_name(void) } // Fix the error that some "tweak" apps do. - if (stricmp(volume, "%USERNAME% on %COMPUTER%") == 0) - volume[0] = '\0'; + if (_tcsicmp(volume, TEXT("%USERNAME% on %COMPUTER%")) == 0) + volume[0] = TEXT('\0'); // No volume name found, default to "My Computer" if (volume[0] == 0) - strcpy(volume, "My Computer"); + _tcscpy(volume, TEXT("My Computer")); + #ifdef _UNICODE + strlcpy(out_volume, volume, 256); + return out_volume; + #else return volume; + #endif } diff --git a/SheepShaver/src/bincue.cpp b/SheepShaver/src/bincue.cpp new file mode 120000 index 000000000..a3de57df0 --- /dev/null +++ b/SheepShaver/src/bincue.cpp @@ -0,0 +1 @@ +../../BasiliskII/src/bincue.cpp \ No newline at end of file diff --git a/SheepShaver/src/gfxaccel.cpp b/SheepShaver/src/gfxaccel.cpp index ed65e5d83..ec1e96a32 100644 --- a/SheepShaver/src/gfxaccel.cpp +++ b/SheepShaver/src/gfxaccel.cpp @@ -85,7 +85,7 @@ static inline void do_invrect(uint8 *dest, uint32 length) } // Align on 32-bit boundaries - if (bpp < 32 && (((uintptr)dest) & 2)) { + if (bpp < 32 && (((uintptr)dest) & 2) && length >= 2) { INVERT_2(dest, 0); dest += 2; length -= 2; } @@ -198,7 +198,7 @@ static inline void do_fillrect(uint8 *dest, uint32 color, uint32 length) } // Align on 32-bit boundaries - if (bpp < 32 && (((uintptr)dest) & 2)) { + if (bpp < 32 && (((uintptr)dest) & 2) && length >= 2) { FILL_2(dest, 0, color); dest += 2; length -= 2; } diff --git a/SheepShaver/src/include/bincue.h b/SheepShaver/src/include/bincue.h new file mode 120000 index 000000000..59a01bfbc --- /dev/null +++ b/SheepShaver/src/include/bincue.h @@ -0,0 +1 @@ +../../../BasiliskII/src/include/bincue.h \ No newline at end of file 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" diff --git a/SheepShaver/src/include/ether_defs.h b/SheepShaver/src/include/ether_defs.h index 390aee4cb..60468d86e 100644 --- a/SheepShaver/src/include/ether_defs.h +++ b/SheepShaver/src/include/ether_defs.h @@ -525,7 +525,7 @@ union DL_primitives { struct EnetPacketHeader { uint8 fDestAddr[6]; uint8 fSourceAddr[6]; - nw_uint16 fProto; + uint16 fProto; } PACKED__; struct T8022Header { @@ -548,7 +548,7 @@ struct T8022FullPacketHeader { struct T8022AddressStruct { uint8 fHWAddr[6]; - nw_uint16 fSAP; + uint16 fSAP; uint8 fSNAP[k8022SNAPLength]; } PACKED__; diff --git a/SheepShaver/src/include/macos_util.h b/SheepShaver/src/include/macos_util.h index aec13cff5..50bcee3bc 100644 --- a/SheepShaver/src/include/macos_util.h +++ b/SheepShaver/src/include/macos_util.h @@ -353,6 +353,7 @@ extern void Enqueue(uint32 elem, uint32 list); // Enqueue QElem to list extern int FindFreeDriveNumber(int num); // Find first free drive number, starting at "num" extern void MountVolume(void *fh); // Mount volume with given file handle (see sys.h) extern void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size); // Calculate disk image file layout given file size and first 256 data bytes +extern void MoveDrivesFromDriverToFront(uint32 driverRefNum); // Move drives from the given driver to the head of the drive queue extern uint32 FindLibSymbol(const char *lib, const char *sym); // Find symbol in shared library extern void InitCallUniversalProc(void); // Init CallUniversalProc() extern long CallUniversalProc(void *upp, uint32 info); // CallUniversalProc() diff --git a/SheepShaver/src/include/main.h b/SheepShaver/src/include/main.h index e595c04a5..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]; @@ -77,4 +73,15 @@ extern void TriggerInterrupt(void); // Trigger SIGUSR1 interrupt in emulat extern void DisableInterrupt(void); // Disable SIGUSR1 interrupt (can be nested) extern void EnableInterrupt(void); // Enable SIGUSR1 interrupt (can be nested) +// Array length +#if __cplusplus >= 201103L || (_MSC_VER >= 1900 && defined __cplusplus) +template +constexpr size_t lengthof(T (& a)[size]) +{ + return size; +} +#else +#define lengthof(a) (sizeof(a) / sizeof(a[0])) +#endif + #endif 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/include/user_strings.h b/SheepShaver/src/include/user_strings.h index 1813954a2..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, @@ -132,6 +131,12 @@ enum { STR_SIZE_1024_LAB, STR_SIZE_MAX_LAB, STR_NOSOUND_CTRL, + STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL, + STR_SOFTWARE_LAB, + STR_OPENGL_LAB, + STR_DIRECT3D_LAB, + STR_GRAPHICS_SDL_VSYNC_CTRL, + STR_DEFAULT_LAB, // Serial/Network pane STR_SERIAL_NETWORK_PANE_TITLE = 3400, @@ -165,8 +170,6 @@ enum { // Mac window STR_WINDOW_TITLE = 4000, - STR_WINDOW_TITLE_FROZEN, - STR_WINDOW_TITLE_GRABBED, STR_WINDOW_TITLE_GRABBED0, STR_WINDOW_TITLE_GRABBED1, STR_WINDOW_TITLE_GRABBED2, diff --git a/SheepShaver/src/include/version.h b/SheepShaver/src/include/version.h index 78a3837fa..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 = 4; +#ifdef PACKAGE_VERSION // from config.h +#define VERSION_STRING PACKAGE_VERSION +#else +#define VERSION_STRING "2.5" +#endif #endif diff --git a/SheepShaver/src/include/video.h b/SheepShaver/src/include/video.h index 3b82203ef..790292ad7 100644 --- a/SheepShaver/src/include/video.h +++ b/SheepShaver/src/include/video.h @@ -66,13 +66,13 @@ inline int DepthModeForPixelDepth(int depth) } } -// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width +// Return a bytes-per-row value (assuming enough bytes to fit the bits but no further padding) for the specified depth and pixel width inline uint32 TrivialBytesPerRow(uint32 width, int mode) { switch (mode) { - case APPLE_1_BIT: return width / 8; - case APPLE_2_BIT: return width / 4; - case APPLE_4_BIT: return width / 2; + case APPLE_1_BIT: return (width + 7) / 8; + case APPLE_2_BIT: return (width + 3) / 4; + case APPLE_4_BIT: return (width + 1) / 2; case APPLE_8_BIT: return width; case APPLE_16_BIT: return width * 2; case APPLE_32_BIT: return width * 4; @@ -106,6 +106,7 @@ extern uint32 screen_base; // Frame buffer base address extern int cur_mode; // Number of current video mode (index in VModes array) extern int display_type; // Current display type (see above) extern rgb_color mac_pal[256]; +extern rgb_color mac_gamma[256]; extern uint8 remap_mac_be[256]; extern uint8 MacCursor[68]; @@ -140,6 +141,7 @@ extern void VideoInstallAccel(void); extern void VideoQuitFullScreen(void); extern void video_set_palette(void); +extern void video_set_gamma(int n_colors); extern void video_set_cursor(void); extern bool video_can_change_cursor(void); extern int16 video_mode_change(VidLocals *csSave, uint32 ParamPtr); diff --git a/SheepShaver/src/include/video_defs.h b/SheepShaver/src/include/video_defs.h index ef9e2824c..039684364 100644 --- a/SheepShaver/src/include/video_defs.h +++ b/SheepShaver/src/include/video_defs.h @@ -164,9 +164,9 @@ enum { enum { kDisplayModeIDCurrent = 0x00, /* Reference the Current DisplayModeID */ - kDisplayModeIDInvalid = (long)0xFFFFFFFF, /* A bogus DisplayModeID in all cases */ - kDisplayModeIDFindFirstResolution = (long)0xFFFFFFFE, /* Used in cscGetNextResolution to reset iterator */ - kDisplayModeIDNoMoreResolutions = (long)0xFFFFFFFD /* Used in cscGetNextResolution to indicate End Of List */ + kDisplayModeIDInvalid = 0xFFFFFFFF, /* A bogus DisplayModeID in all cases */ + kDisplayModeIDFindFirstResolution = 0xFFFFFFFE, /* Used in cscGetNextResolution to reset iterator */ + kDisplayModeIDNoMoreResolutions = 0xFFFFFFFD /* Used in cscGetNextResolution to indicate End Of List */ }; /* codes for Display Manager status requests */ diff --git a/SheepShaver/src/kpx_cpu/include/nvmemfun.hpp b/SheepShaver/src/kpx_cpu/include/nvmemfun.hpp index efad01ffc..e5df5dabb 100644 --- a/SheepShaver/src/kpx_cpu/include/nvmemfun.hpp +++ b/SheepShaver/src/kpx_cpu/include/nvmemfun.hpp @@ -23,6 +23,10 @@ #include +#ifdef __MINGW32__ +#include "vm_alloc.h" +#endif + #if defined __GNUC__ #define HAVE_FAST_NV_MEM_FUN 1 #define MEM_FUN_WORDS 2 @@ -47,8 +51,17 @@ #if HAVE_FAST_NV_MEM_FUN +#ifdef __MINGW32__ +#define PF_CONVENTION __thiscall +#else +// TODO set a calling convention on other platforms/compilers where the default cc does not pass obj as first param +#define PF_CONVENTION +#endif + template< class PMF, class PF > inline PF nv_mem_fun_of(PMF pmf) { + /** Convert member function pointer to a regular function pointer that takes the object as first parameter + */ if (pmf == 0) return 0; union { PMF pmf; uintptr p[MEM_FUN_WORDS]; } x; @@ -59,7 +72,7 @@ inline PF nv_mem_fun_of(PMF pmf) { template< class R, class T > class nv_mem_fun_t : public std::unary_function { typedef R (T::*pmf_t)(); - typedef R (*pf_t)(T *); + typedef R (* PF_CONVENTION pf_t)(T *); pf_t pf; public: nv_mem_fun_t(pmf_t pmf) : pf(nv_mem_fun_of(pmf)) {} @@ -70,7 +83,7 @@ class nv_mem_fun_t : public std::unary_function { template< class R, class T > class const_nv_mem_fun_t : public std::unary_function { typedef R (T::*pmf_t)(); - typedef R (*pf_t)(T *); + typedef R (* PF_CONVENTION pf_t)(T *); pf_t const pf; public: const_nv_mem_fun_t(pmf_t const pmf) : pf(nv_mem_fun_of(pmf)) {} @@ -81,18 +94,130 @@ class const_nv_mem_fun_t : public std::unary_function { template< class R, class T, class A > class nv_mem_fun1_t : public std::binary_function { typedef R (T::*pmf_t)(A); - typedef R (*pf_t)(T *, A x); + typedef R (* PF_CONVENTION pf_t)(T *, A x); +#ifdef __MINGW32__ + typedef R (* default_call_conv_pf_t)(T *, A x); +#endif pf_t pf; public: - nv_mem_fun1_t(pmf_t pmf) : pf(nv_mem_fun_of(pmf)) {} + nv_mem_fun1_t(pmf_t pmf) : pf(nv_mem_fun_of(pmf)) { + #ifdef __MINGW32__ + init_func(); + #endif + } R operator()(T *p, A x) const { return (*pf)(p, x); } + + #ifdef __MINGW32__ + + #define NVMEMFUN_THUNK_DEBUG 0 + +private: + #define DO_CONVENTION_CALL_PF_PLACEHOLDER 0x12345678 + + #define DO_CONVENTION_CALL_STATICS + static bool do_convention_call_init_done; + static int do_convention_call_code_len; + static int do_convention_call_pf_offset; + unsigned char * do_convention_call_instance_copy; + + static void init_do_convention_call() { + if (do_convention_call_init_done) return; + + const int max_code_bytes = 100; + const unsigned char last_code_byte_value = 0xc3; + + // figure out the size of the function + unsigned char * func_pos = (unsigned char *) &do_convention_call; + int i; + for (i = 0; i < max_code_bytes; i++) { + if (func_pos[i] == last_code_byte_value) { + break; + } + } + do_convention_call_code_len = i + 1; + + #if NVMEMFUN_THUNK_DEBUG + printf("do_convention_call func size %d ", do_convention_call_code_len); + #endif + + // find the position of the pf placeholder in the function + int placeholder_matches = 0; + for (i = 0; i < do_convention_call_code_len - 3; i++) { + pf_t * cur_ptr = (pf_t*)(func_pos + i); + if (*cur_ptr == (pf_t) DO_CONVENTION_CALL_PF_PLACEHOLDER) { + do_convention_call_pf_offset = i; + #if NVMEMFUN_THUNK_DEBUG + printf("ptr pos offset %x", (uint32)cur_ptr - (uint32)func_pos); + #endif + ++placeholder_matches; + } + } + + #if NVMEMFUN_THUNK_DEBUG + printf("\n"); + fflush(stdout); + #endif + + assert(placeholder_matches == 1); + + do_convention_call_init_done = true; + } + + void init_func() { + if (!do_convention_call_init_done) { + init_do_convention_call(); + } + + // copy do_convention_call and patch in the address of pf + + do_convention_call_instance_copy = (unsigned char *) vm_acquire(do_convention_call_code_len); + // Thunk buffer needs to be around while default_call_conv_ptr() is still in use, + // longer than nv_mem_fun1_t lifetime + //FIXME track the lifetime of this + if (do_convention_call_instance_copy == NULL) return; + unsigned char * func_pos = (unsigned char *) &do_convention_call; + memcpy((void *)do_convention_call_instance_copy, func_pos, do_convention_call_code_len); + + // replace byte sequence in buf copy + *(pf_t*)(do_convention_call_instance_copy + do_convention_call_pf_offset) = pf; + + #if NVMEMFUN_THUNK_DEBUG + printf("patching do_convention_call to %x; func size %d ", do_convention_call_instance_copy, do_convention_call_code_len); + for (int i = 0 ; i < do_convention_call_code_len; i ++) { + printf("%02x ", do_convention_call_instance_copy[i]); + } + printf("\n"); + fflush(stdout); + #endif + + vm_protect(do_convention_call_instance_copy, do_convention_call_code_len, VM_PAGE_READ | VM_PAGE_EXECUTE); + } + + // Cheesy thunk solution to adapt the calling convention: + // do_convention_call accepts the default calling convention and calls pf with PF_CONVENTION + // Each instance makes its own copy of do_convention_call in a buffer and patches the address of pf into it + static R do_convention_call(T * obj, A x) { + pf_t fn = (pf_t) DO_CONVENTION_CALL_PF_PLACEHOLDER; + return (*fn)(obj, x); + } + +public: + + default_call_conv_pf_t default_call_conv_ptr() const { return (default_call_conv_pf_t) do_convention_call_instance_copy; } + + #else + pf_t ptr() const { return pf; } + + #endif + + }; template< class R, class T, class A > class const_nv_mem_fun1_t : public std::binary_function { typedef R (T::*pmf_t)(A); - typedef R (*pf_t)(T *, A x); + typedef R (* PF_CONVENTION pf_t)(T *, A x); pf_t const pf; public: const_nv_mem_fun1_t(pmf_t const pmf) : pf(nv_mem_fun_of(pmf)) {} diff --git a/SheepShaver/src/kpx_cpu/ppc-dis.c b/SheepShaver/src/kpx_cpu/ppc-dis.c index a2478e633..3c1fc9e39 100644 --- a/SheepShaver/src/kpx_cpu/ppc-dis.c +++ b/SheepShaver/src/kpx_cpu/ppc-dis.c @@ -23,6 +23,7 @@ see . */ #include #include "dis-asm.h" +#include "config.h" #define BFD_DEFAULT_TARGET_SIZE 64 @@ -5263,6 +5264,8 @@ bfd_vma bfd_getb32 (const bfd_byte *addr) return (bfd_vma) v; } +#if !ENABLE_MON + /* Get LENGTH bytes from info's buffer, at target address memaddr. Transfer them to myaddr. */ int @@ -5313,6 +5316,8 @@ generic_symbol_at_address (bfd_vma addr, struct disassemble_info *info) return 1; } +#endif // !ENABLE_MON + /* Print a PowerPC or POWER instruction. */ static int diff --git a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp old mode 100644 new mode 100755 index af7ba4672..9b6d87946 --- a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp +++ b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp @@ -151,9 +151,11 @@ class sheepshaver_cpu // Execute NATIVE_OP routine void execute_native_op(uint32 native_op); + static void call_execute_native_op(powerpc_cpu * cpu, uint32 native_op); // Execute EMUL_OP routine void execute_emul_op(uint32 emul_op); + static void call_execute_emul_op(powerpc_cpu * cpu, uint32 emul_op); // Execute 68k routine void execute_68k(uint32 entry, M68kRegisters *r); @@ -170,6 +172,7 @@ class sheepshaver_cpu #endif // Resource manager thunk void get_resource(uint32 old_get_resource); + static void call_get_resource(powerpc_cpu * cpu, uint32 old_get_resource); // Handle MacOS interrupt void interrupt(uint32 entry); @@ -218,6 +221,10 @@ typedef bit_field< 19, 19 > FN_field; typedef bit_field< 20, 25 > NATIVE_OP_field; typedef bit_field< 26, 31 > EMUL_OP_field; +void sheepshaver_cpu::call_execute_emul_op(powerpc_cpu * cpu, uint32 emul_op) { + static_cast(cpu)->execute_emul_op(emul_op); +} + // Execute EMUL_OP routine void sheepshaver_cpu::execute_emul_op(uint32 emul_op) { @@ -332,7 +339,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context) }; uint32 old_get_resource = ReadMacInt32(get_resource_ptr[selector - NATIVE_GET_RESOURCE]); typedef void (*func_t)(dyngen_cpu_base, uint32); - func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::get_resource).ptr(); + func_t func = &sheepshaver_cpu::call_get_resource; dg.gen_invoke_CPU_im(func, old_get_resource); status = COMPILE_CODE_OK; break; @@ -421,7 +428,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context) // Invoke NativeOp handler if (!FN_field::test(opcode)) { typedef void (*func_t)(dyngen_cpu_base, uint32); - func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_native_op).ptr(); + func_t func = &sheepshaver_cpu::call_execute_native_op; dg.gen_invoke_CPU_im(func, selector); cg_context.done_compile = false; status = COMPILE_CODE_OK; @@ -445,7 +452,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context) #else // Invoke EmulOp handler typedef void (*func_t)(dyngen_cpu_base, uint32); - func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op).ptr(); + func_t func = &sheepshaver_cpu::call_execute_emul_op; dg.gen_invoke_CPU_im(func, emul_op); cg_context.done_compile = false; status = COMPILE_CODE_OK; @@ -478,10 +485,10 @@ void sheepshaver_cpu::interrupt(uint32 entry) SheepVar32 trampoline = POWERPC_EXEC_RETURN; // Prepare registers for nanokernel interrupt routine - kernel_data->v[0x004 >> 2] = htonl(gpr(1)); - kernel_data->v[0x018 >> 2] = htonl(gpr(6)); + WriteMacInt32(KERNEL_DATA_BASE + 0x004, gpr(1)); + WriteMacInt32(KERNEL_DATA_BASE + 0x018, gpr(6)); - gpr(6) = ntohl(kernel_data->v[0x65c >> 2]); + gpr(6) = ReadMacInt32(KERNEL_DATA_BASE + 0x65c); assert(gpr(6) != 0); WriteMacInt32(gpr(6) + 0x13c, gpr(7)); WriteMacInt32(gpr(6) + 0x144, gpr(8)); @@ -492,7 +499,7 @@ void sheepshaver_cpu::interrupt(uint32 entry) WriteMacInt32(gpr(6) + 0x16c, gpr(13)); gpr(1) = KernelDataAddr; - gpr(7) = ntohl(kernel_data->v[0x660 >> 2]); + gpr(7) = ReadMacInt32(KERNEL_DATA_BASE + 0x660); gpr(8) = 0; gpr(10) = trampoline.addr(); gpr(12) = trampoline.addr(); @@ -564,8 +571,8 @@ void sheepshaver_cpu::execute_68k(uint32 entry, M68kRegisters *r) gpr(25) = ReadMacInt32(XLM_68K_R25); // MSB of SR gpr(26) = 0; gpr(28) = 0; // VBR - gpr(29) = ntohl(kernel_data->ed.v[0x74 >> 2]); // Pointer to opcode table - gpr(30) = ntohl(kernel_data->ed.v[0x78 >> 2]); // Address of emulator + gpr(29) = ReadMacInt32(KERNEL_DATA_BASE + 0x1074); // Pointer to opcode table + gpr(30) = ReadMacInt32(KERNEL_DATA_BASE + 0x1078); // Address of emulator gpr(31) = KernelDataAddr + 0x1000; // Push return address (points to EXEC_RETURN opcode) on stack @@ -685,6 +692,10 @@ inline void sheepshaver_cpu::execute_ppc(uint32 entry) lr() = saved_lr; } +void sheepshaver_cpu::call_get_resource(powerpc_cpu * cpu, uint32 old_get_resource) { + static_cast(cpu)->get_resource(old_get_resource); +} + // Resource Manager thunk inline void sheepshaver_cpu::get_resource(uint32 old_get_resource) { @@ -897,14 +908,14 @@ void init_emul_op_trampolines(basic_dyngen & dg) // EmulOp emul_op_trampoline = dg.gen_start(); - func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op).ptr(); + func = &sheepshaver_cpu::call_execute_emul_op; dg.gen_invoke_CPU_T0(func); dg.gen_exec_return(); dg.gen_end(); // NativeOp native_op_trampoline = dg.gen_start(); - func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_native_op).ptr(); + func = &sheepshaver_cpu::call_execute_native_op; dg.gen_invoke_CPU_T0(func); dg.gen_exec_return(); dg.gen_end(); @@ -963,8 +974,8 @@ void HandleInterrupt(powerpc_registers *r) switch (ReadMacInt32(XLM_RUN_MODE)) { case MODE_68K: // 68k emulator active, trigger 68k interrupt level 1 - WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); - r->cr.set(r->cr.get() | tswap32(kernel_data->v[0x674 >> 2])); + WriteMacInt16(ReadMacInt32(KERNEL_DATA_BASE + 0x67c), 1); + r->cr.set(r->cr.get() | ReadMacInt32(KERNEL_DATA_BASE + 0x674)); break; #if INTERRUPTS_IN_NATIVE_MODE @@ -973,10 +984,10 @@ void HandleInterrupt(powerpc_registers *r) if (r->gpr[1] != KernelDataAddr) { // Prepare for 68k interrupt level 1 - WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); - WriteMacInt32(tswap32(kernel_data->v[0x658 >> 2]) + 0xdc, - ReadMacInt32(tswap32(kernel_data->v[0x658 >> 2]) + 0xdc) - | tswap32(kernel_data->v[0x674 >> 2])); + WriteMacInt16(ReadMacInt32(KERNEL_DATA_BASE + 0x67c), 1); + WriteMacInt32(ReadMacInt32(KERNEL_DATA_BASE + 0x658) + 0xdc, + ReadMacInt32(ReadMacInt32(KERNEL_DATA_BASE + 0x658) + 0xdc) + | ReadMacInt32(KERNEL_DATA_BASE + 0x674)); // Execute nanokernel interrupt routine (this will activate the 68k emulator) DisableInterrupt(); @@ -1030,6 +1041,10 @@ void HandleInterrupt(powerpc_registers *r) } } +void sheepshaver_cpu::call_execute_native_op(powerpc_cpu * cpu, uint32 selector) { + static_cast(cpu)->execute_native_op(selector); +} + // Execute NATIVE_OP routine void sheepshaver_cpu::execute_native_op(uint32 selector) { diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp index 2423d67a2..b74fda81f 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp @@ -19,6 +19,9 @@ */ #include "sysdeps.h" + +#if ENABLE_DYNGEN + #include "basic-dyngen.hpp" int __op_param1, __op_param2, __op_param3; @@ -181,3 +184,5 @@ basic_dyngen::gen_align(int align) #endif return code_ptr(); } + +#endif //ENABLE_DYNGEN diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c b/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c index b6ead7922..2fdeebd12 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/dyngen.c @@ -2396,6 +2396,7 @@ void patch_relocations(FILE *outfile, const char *name, host_ulong size, host_ul fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (int32_t)%s + %d;\n", slide, final_sym_name, addend); break; case R_X86_64_PC32: + case R_X86_64_PLT32: fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s - (long)(code_ptr() + %d) + %d;\n", slide, final_sym_name, slide, addend); break; diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp index 77762e92f..dfe1dbeef 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/jit-cache.cpp @@ -19,6 +19,9 @@ */ #include "sysdeps.h" + +#if ENABLE_DYNGEN + #include "vm_alloc.h" #include "cpu/jit/jit-cache.hpp" @@ -146,3 +149,5 @@ basic_jit_cache::copy_data(const uint8 *block, uint32 size) D(bug("basic_jit_cache: DATA %p, %d bytes [data=%p, offs=%u]\n", ptr, size, data, data->offs)); return ptr; } + +#endif //ENABLE_DYNGEN diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/x86/codegen_x86.h b/SheepShaver/src/kpx_cpu/src/cpu/jit/x86/codegen_x86.h deleted file mode 120000 index 110f4bd0d..000000000 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/x86/codegen_x86.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../../../BasiliskII/src/uae_cpu/compiler/codegen_x86.h \ No newline at end of file diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/x86/codegen_x86.h b/SheepShaver/src/kpx_cpu/src/cpu/jit/x86/codegen_x86.h new file mode 100644 index 000000000..08538b7af --- /dev/null +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/x86/codegen_x86.h @@ -0,0 +1,2565 @@ +/******************** -*- mode: C; tab-width: 8 -*- ******************** + * + * Run-time assembler for IA-32 and AMD64 + * + ***********************************************************************/ + + +/*********************************************************************** + * + * This file is derived from CCG. + * + * Copyright 1999, 2000, 2001, 2002, 2003 Ian Piumarta + * + * Adaptations and enhancements for AMD64 support, Copyright 2003-2008 + * Gwenole Beauchesne + * + * 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 X86_RTASM_H +#define X86_RTASM_H + +/* NOTES + * + * o Best viewed on a 1024x768 screen with fixed-6x10 font ;-) + * + * TODO + * + * o Fix FIXMEs + * o SSE instructions + * o Optimize for cases where register numbers are not integral constants + */ + +/* --- Configuration ------------------------------------------------------- */ + +/* Define to settle a "flat" register set, i.e. different regno for + each size variant. */ +#ifndef X86_FLAT_REGISTERS +#define X86_FLAT_REGISTERS 1 +#endif + +/* Define to generate x86-64 code. */ +#ifndef X86_TARGET_64BIT +#define X86_TARGET_64BIT 0 +#endif + +/* Define to optimize ALU instructions. */ +#ifndef X86_OPTIMIZE_ALU +#define X86_OPTIMIZE_ALU 1 +#endif + +/* Define to optimize rotate/shift instructions. */ +#ifndef X86_OPTIMIZE_ROTSHI +#define X86_OPTIMIZE_ROTSHI 1 +#endif + +/* Define to optimize absolute addresses for RIP relative addressing. */ +#ifndef X86_RIP_RELATIVE_ADDR +#define X86_RIP_RELATIVE_ADDR 1 +#endif + + +/* --- Macros -------------------------------------------------------------- */ + +/* Functions used to emit code. + * + * x86_emit_byte(B) + * x86_emit_word(W) + * x86_emit_long(L) + */ + +/* Get pointer to current code + * + * x86_get_target() + */ + +/* Abort assembler, fatal failure. + * + * x86_emit_failure(MSG) + */ + +#define x86_emit_failure0(MSG) (x86_emit_failure(MSG),0) + + +/* --- Register set -------------------------------------------------------- */ + +enum { + X86_RIP = -2, +#if X86_FLAT_REGISTERS + X86_NOREG = 0, + X86_Reg8L_Base = 0x10, + X86_Reg8H_Base = 0x20, + X86_Reg16_Base = 0x30, + X86_Reg32_Base = 0x40, + X86_Reg64_Base = 0x50, + X86_RegMMX_Base = 0x60, + X86_RegXMM_Base = 0x70, + X86_RegFPU_Base = 0x80 +#else + X86_NOREG = -1, + X86_Reg8L_Base = 0, + X86_Reg8H_Base = 16, + X86_Reg16_Base = 0, + X86_Reg32_Base = 0, + X86_Reg64_Base = 0, + X86_RegMMX_Base = 0, + X86_RegXMM_Base = 0, + X86_RegFPU_Base = 0 +#endif +}; + +enum { + X86_AL = X86_Reg8L_Base, + X86_CL, X86_DL, X86_BL, + X86_SPL, X86_BPL, X86_SIL, X86_DIL, + X86_R8B, X86_R9B, X86_R10B, X86_R11B, + X86_R12B, X86_R13B, X86_R14B, X86_R15B, + X86_AH = X86_Reg8H_Base + 4, + X86_CH, X86_DH, X86_BH +}; + +enum { + X86_AX = X86_Reg16_Base, + X86_CX, X86_DX, X86_BX, + X86_SP, X86_BP, X86_SI, X86_DI, + X86_R8W, X86_R9W, X86_R10W, X86_R11W, + X86_R12W, X86_R13W, X86_R14W, X86_R15W +}; + +enum { + X86_EAX = X86_Reg32_Base, + X86_ECX, X86_EDX, X86_EBX, + X86_ESP, X86_EBP, X86_ESI, X86_EDI, + X86_R8D, X86_R9D, X86_R10D, X86_R11D, + X86_R12D, X86_R13D, X86_R14D, X86_R15D +}; + +enum { + X86_RAX = X86_Reg64_Base, + X86_RCX, X86_RDX, X86_RBX, + X86_RSP, X86_RBP, X86_RSI, X86_RDI, + X86_R8, X86_R9, X86_R10, X86_R11, + X86_R12, X86_R13, X86_R14, X86_R15 +}; + +enum { + X86_MM0 = X86_RegMMX_Base, + X86_MM1, X86_MM2, X86_MM3, + X86_MM4, X86_MM5, X86_MM6, X86_MM7, +}; + +enum { + X86_XMM0 = X86_RegXMM_Base, + X86_XMM1, X86_XMM2, X86_XMM3, + X86_XMM4, X86_XMM5, X86_XMM6, X86_XMM7, + X86_XMM8, X86_XMM9, X86_XMM10, X86_XMM11, + X86_XMM12, X86_XMM13, X86_XMM14, X86_XMM15 +}; + +enum { + X86_ST0 = X86_RegFPU_Base, + X86_ST1, X86_ST2, X86_ST3, + X86_ST4, X86_ST5, X86_ST6, X86_ST7 +}; + +/* Register control and access + * + * _r0P(R) Null register? + * _rIP(R) RIP register? + * _rXP(R) Extended register? + * + * _rC(R) Class of register (only valid if X86_FLAT_REGISTERS) + * _rR(R) Full register number + * _rN(R) Short register number for encoding + * + * _r1(R) 8-bit register ID + * _r2(R) 16-bit register ID + * _r4(R) 32-bit register ID + * _r8(R) 64-bit register ID + * _rM(R) MMX register ID + * _rX(R) XMM register ID + * _rF(R) FPU register ID + * _rA(R) Address register ID used for EA calculation + */ + +#define _rST0P(R) ((int)(R) == (int)X86_ST0) +#define _r0P(R) ((int)(R) == (int)X86_NOREG) +#define _rIP(R) (X86_TARGET_64BIT ? ((int)(R) == (int)X86_RIP) : 0) + +#if X86_FLAT_REGISTERS +#define _rC(R) ((R) & 0xf0) +#define _rR(R) ((R) & 0x0f) +#define _rN(R) ((R) & 0x07) +#define _rXP(R) (((R) > 0 && _rR(R) > 7) ? 1 : 0) +#else +#define _rN(R) ((R) & 0x07) +#define _rR(R) (int(R)) +#define _rXP(R) ((_rR(R) > 7 && _rR(R) < 16) ? 1 : 0) +#endif + +#if !defined(_ASM_SAFETY) || ! X86_FLAT_REGISTERS +#define _r1(R) _rN(R) +#define _r2(R) _rN(R) +#define _r4(R) _rN(R) +#define _r8(R) _rN(R) +#define _rA(R) _rN(R) +#define _rM(R) _rN(R) +#define _rX(R) _rN(R) +#define _rF(R) _rN(R) +#else +#define _r1(R) ( ((_rC(R) & (X86_Reg8L_Base | X86_Reg8H_Base)) != 0) ? _rN(R) : x86_emit_failure0( "8-bit register required")) +#define _r2(R) ( (_rC(R) == X86_Reg16_Base) ? _rN(R) : x86_emit_failure0("16-bit register required")) +#define _r4(R) ( (_rC(R) == X86_Reg32_Base) ? _rN(R) : x86_emit_failure0("32-bit register required")) +#define _r8(R) ( (_rC(R) == X86_Reg64_Base) ? _rN(R) : x86_emit_failure0("64-bit register required")) +#define _rA(R) ( X86_TARGET_64BIT ? \ + ( (_rC(R) == X86_Reg64_Base) ? _rN(R) : x86_emit_failure0("not a valid 64-bit base/index expression")) : \ + ( (_rC(R) == X86_Reg32_Base) ? _rN(R) : x86_emit_failure0("not a valid 32-bit base/index expression")) ) +#define _rM(R) ( (_rC(R) == X86_RegMMX_Base) ? _rN(R) : x86_emit_failure0("MMX register required")) +#define _rX(R) ( (_rC(R) == X86_RegXMM_Base) ? _rN(R) : x86_emit_failure0("SSE register required")) +#define _rF(R) ( (_rC(R) == X86_RegFPU_Base) ? _rN(R) : x86_emit_failure0("FPU register required")) +#endif + +#define _rSP() (X86_TARGET_64BIT ? (int)X86_RSP : (int)X86_ESP) +#define _r1e8lP(R) (int(R) >= X86_SPL && int(R) <= X86_DIL) +#define _rbpP(R) (_rR(R) == _rR(X86_RBP)) +#define _rspP(R) (_rR(R) == _rR(X86_RSP)) +#define _rbp13P(R) (_rN(R) == _rN(X86_RBP)) +#define _rsp12P(R) (_rN(R) == _rN(X86_RSP)) + + +/* ========================================================================= */ +/* --- UTILITY ------------------------------------------------------------- */ +/* ========================================================================= */ + +typedef signed char _sc; +typedef unsigned char _uc; +typedef signed short _ss; +typedef unsigned short _us; +typedef signed int _sl; +typedef unsigned int _ul; + +#define _UC(X) ((_uc )(unsigned long)(X)) +#define _US(X) ((_us )(unsigned long)(X)) +#define _SL(X) ((_sl )(unsigned long)(X)) +#define _UL(X) ((_ul )(unsigned long)(X)) + +#define _PUC(X) ((_uc *)(X)) +#define _PUS(X) ((_us *)(X)) +#define _PSL(X) ((_sl *)(X)) +#define _PUL(X) ((_ul *)(X)) + +#define _B(B) x86_emit_byte((B)) +#define _W(W) x86_emit_word((W)) +#define _L(L) x86_emit_long((L)) +#define _Q(Q) x86_emit_quad((Q)) + +#define _MASK(N) ((unsigned)((1<<(N)))-1) +#define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N))) +#define _uiP(N,I) (!(((unsigned)(I))&~_MASK(N))) +#define _suiP(N,I) (_siP(N,I) | _uiP(N,I)) + +#ifndef _ASM_SAFETY +#define _ck_s(W,I) (_UL(I) & _MASK(W)) +#define _ck_u(W,I) (_UL(I) & _MASK(W)) +#define _ck_su(W,I) (_UL(I) & _MASK(W)) +#define _ck_d(W,I) (_UL(I) & _MASK(W)) +#else +#define _ck_s(W,I) (_siP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "signed integer `"#I"' too large for "#W"-bit field")) +#define _ck_u(W,I) (_uiP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0("unsigned integer `"#I"' too large for "#W"-bit field")) +#define _ck_su(W,I) (_suiP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "integer `"#I"' too large for "#W"-bit field")) +#define _ck_d(W,I) (_siP(W,I) ? (_UL(I) & _MASK(W)) : x86_emit_failure0( "displacement `"#I"' too large for "#W"-bit field")) +#endif + +#define _s0P(I) ((I)==0) +#define _s8P(I) _siP(8,I) +#define _s16P(I) _siP(16,I) +#define _u8P(I) _uiP(8,I) +#define _u16P(I) _uiP(16,I) + +#define _su8(I) _ck_su(8,I) +#define _su16(I) _ck_su(16,I) + +#define _s1(I) _ck_s( 1,I) +#define _s2(I) _ck_s( 2,I) +#define _s3(I) _ck_s( 3,I) +#define _s4(I) _ck_s( 4,I) +#define _s5(I) _ck_s( 5,I) +#define _s6(I) _ck_s( 6,I) +#define _s7(I) _ck_s( 7,I) +#define _s8(I) _ck_s( 8,I) +#define _s9(I) _ck_s( 9,I) +#define _s10(I) _ck_s(10,I) +#define _s11(I) _ck_s(11,I) +#define _s12(I) _ck_s(12,I) +#define _s13(I) _ck_s(13,I) +#define _s14(I) _ck_s(14,I) +#define _s15(I) _ck_s(15,I) +#define _s16(I) _ck_s(16,I) +#define _s17(I) _ck_s(17,I) +#define _s18(I) _ck_s(18,I) +#define _s19(I) _ck_s(19,I) +#define _s20(I) _ck_s(20,I) +#define _s21(I) _ck_s(21,I) +#define _s22(I) _ck_s(22,I) +#define _s23(I) _ck_s(23,I) +#define _s24(I) _ck_s(24,I) +#define _s25(I) _ck_s(25,I) +#define _s26(I) _ck_s(26,I) +#define _s27(I) _ck_s(27,I) +#define _s28(I) _ck_s(28,I) +#define _s29(I) _ck_s(29,I) +#define _s30(I) _ck_s(30,I) +#define _s31(I) _ck_s(31,I) +#define _u1(I) _ck_u( 1,I) +#define _u2(I) _ck_u( 2,I) +#define _u3(I) _ck_u( 3,I) +#define _u4(I) _ck_u( 4,I) +#define _u5(I) _ck_u( 5,I) +#define _u6(I) _ck_u( 6,I) +#define _u7(I) _ck_u( 7,I) +#define _u8(I) _ck_u( 8,I) +#define _u9(I) _ck_u( 9,I) +#define _u10(I) _ck_u(10,I) +#define _u11(I) _ck_u(11,I) +#define _u12(I) _ck_u(12,I) +#define _u13(I) _ck_u(13,I) +#define _u14(I) _ck_u(14,I) +#define _u15(I) _ck_u(15,I) +#define _u16(I) _ck_u(16,I) +#define _u17(I) _ck_u(17,I) +#define _u18(I) _ck_u(18,I) +#define _u19(I) _ck_u(19,I) +#define _u20(I) _ck_u(20,I) +#define _u21(I) _ck_u(21,I) +#define _u22(I) _ck_u(22,I) +#define _u23(I) _ck_u(23,I) +#define _u24(I) _ck_u(24,I) +#define _u25(I) _ck_u(25,I) +#define _u26(I) _ck_u(26,I) +#define _u27(I) _ck_u(27,I) +#define _u28(I) _ck_u(28,I) +#define _u29(I) _ck_u(29,I) +#define _u30(I) _ck_u(30,I) +#define _u31(I) _ck_u(31,I) + +/* ========================================================================= */ +/* --- ASSEMBLER ----------------------------------------------------------- */ +/* ========================================================================= */ + +#define _b00 0 +#define _b01 1 +#define _b10 2 +#define _b11 3 + +#define _b000 0 +#define _b001 1 +#define _b010 2 +#define _b011 3 +#define _b100 4 +#define _b101 5 +#define _b110 6 +#define _b111 7 + +#define _OFF4(D) (_UL(D) - _UL(x86_get_target())) +#define _CKD8(D) _ck_d(8, ((_uc) _OFF4(D)) ) + +#define _D8(D) (_B(0), ((*(_PUC(x86_get_target())-1))= _CKD8(D))) +#define _D32(D) (_L(0), ((*(_PUL(x86_get_target())-1))= _OFF4(D))) + +#ifndef _ASM_SAFETY +# define _M(M) (M) +# define _r(R) (R) +# define _m(M) (M) +# define _s(S) (S) +# define _i(I) (I) +# define _b(B) (B) +#else +# define _M(M) (((M)>3) ? x86_emit_failure0("internal error: mod = " #M) : (M)) +# define _r(R) (((R)>7) ? x86_emit_failure0("internal error: reg = " #R) : (R)) +# define _m(M) (((M)>7) ? x86_emit_failure0("internal error: r/m = " #M) : (M)) +# define _s(S) (((S)>3) ? x86_emit_failure0("internal error: memory scale = " #S) : (S)) +# define _i(I) (((I)>7) ? x86_emit_failure0("internal error: memory index = " #I) : (I)) +# define _b(B) (((B)>7) ? x86_emit_failure0("internal error: memory base = " #B) : (B)) +#endif + +#define _Mrm(Md,R,M) _B((_M(Md)<<6)|(_r(R)<<3)|_m(M)) +#define _SIB(Sc,I, B) _B((_s(Sc)<<6)|(_i(I)<<3)|_b(B)) + +#define _SCL(S) ((((S)==1) ? _b00 : \ + (((S)==2) ? _b01 : \ + (((S)==4) ? _b10 : \ + (((S)==8) ? _b11 : x86_emit_failure0("illegal scale: " #S)))))) + + +/* --- Memory subformats - urgh! ------------------------------------------- */ + +/* _r_D() is RIP addressing mode if X86_TARGET_64BIT, use _r_DSIB() instead */ +#define _r_D( R, D ) (_Mrm(_b00,_rN(R),_b101 ) ,_L((_sl)(D))) +#define _r_DSIB(R, D ) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(1),_b100 ,_b101 ),_L((_sl)(D))) +#define _r_0B( R, B ) (_Mrm(_b00,_rN(R),_rA(B)) ) +#define _r_0BIS(R, B,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)) ) +#define _r_1B( R, D,B ) (_Mrm(_b01,_rN(R),_rA(B)) ,_B((_sc)(D))) +#define _r_1BIS(R, D,B,I,S) (_Mrm(_b01,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_B((_sc)(D))) +#define _r_4B( R, D,B ) (_Mrm(_b10,_rN(R),_rA(B)) ,_L((_sl)(D))) +#define _r_4IS( R, D,I,S) (_Mrm(_b00,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_b101 ),_L((_sl)(D))) +#define _r_4BIS(R, D,B,I,S) (_Mrm(_b10,_rN(R),_b100 ),_SIB(_SCL(S),_rA(I),_rA(B)),_L((_sl)(D))) + +#define _r_DB( R, D,B ) ((_s0P(D) && (!_rbp13P(B)) ? _r_0B (R, B ) : (_s8P(D) ? _r_1B( R,D,B ) : _r_4B( R,D,B )))) +#define _r_DBIS(R, D,B,I,S) ((_s0P(D) && (!_rbp13P(B)) ? _r_0BIS(R, B,I,S) : (_s8P(D) ? _r_1BIS(R,D,B,I,S) : _r_4BIS(R,D,B,I,S)))) + +/* Use RIP-addressing in 64-bit mode, if possible */ +#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && \ + ((uintptr)x86_get_target() + 4 + (O) - (D) <= 0xffffffff)) + +#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? (!X86_TARGET_64BIT ? _r_D(R,D) : \ + (_x86_RIP_addressing_possible(D, O) ? \ + _r_D(R, (D) - ((uintptr)x86_get_target() + 4 + (O))) : \ + _r_DSIB(R,D))) : \ + (_rIP(B) ? _r_D (R,D ) : \ + (_rsp12P(B) ? _r_DBIS(R,D,_rSP(),_rSP(),1) : \ + _r_DB (R,D, B )))) : \ + (_r0P(B) ? _r_4IS (R,D, I,S) : \ + (!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \ + x86_emit_failure("illegal index register: %esp")))) + + +/* --- Instruction formats ------------------------------------------------- */ + +#define _m32only(X) (! X86_TARGET_64BIT ? X : x86_emit_failure("invalid instruction in 64-bit mode")) +#define _m64only(X) ( X86_TARGET_64BIT ? X : x86_emit_failure("invalid instruction in 32-bit mode")) +#define _m64(X) ( X86_TARGET_64BIT ? X : ((void)0) ) + +/* _format Opcd ModR/M dN(rB,rI,Sc) imm... */ + +#define _d16() ( _B(0x66 ) ) +#define _O( OP ) ( _B( OP ) ) +#define _Or( OP,R ) ( _B( (OP)|_r(R)) ) +#define _OO( OP ) ( _B((OP)>>8), _B(( (OP) )&0xff) ) +#define _OOr( OP,R ) ( _B((OP)>>8), _B(( (OP)|_r(R))&0xff) ) +#define _Os( OP,B ) ( _s8P(B) ? _B(((OP)|_b10)) : _B(OP) ) +#define _sW( W ) ( _s8P(W) ? _B(W):_W(W) ) +#define _sL( L ) ( _s8P(L) ? _B(L):_L(L) ) +#define _sWO( W ) ( _s8P(W) ? 1 : 2 ) +#define _sLO( L ) ( _s8P(L) ? 1 : 4 ) +#define _O_B( OP ,B ) ( _O ( OP ) ,_B(B) ) +#define _O_W( OP ,W ) ( _O ( OP ) ,_W(W) ) +#define _O_L( OP ,L ) ( _O ( OP ) ,_L(L) ) +#define _OO_L( OP ,L ) ( _OO ( OP ) ,_L(L) ) +#define _O_D8( OP ,D ) ( _O ( OP ) ,_D8(D) ) +#define _O_D32( OP ,D ) ( _O ( OP ) ,_D32(D) ) +#define _OO_D32( OP ,D ) ( _OO ( OP ) ,_D32(D) ) +#define _Os_sW( OP ,W ) ( _Os ( OP,W) ,_sW(W) ) +#define _Os_sL( OP ,L ) ( _Os ( OP,L) ,_sL(L) ) +#define _O_W_B( OP ,W,B) ( _O ( OP ) ,_W(W),_B(B)) +#define _Or_B( OP,R ,B ) ( _Or ( OP,R) ,_B(B) ) +#define _Or_W( OP,R ,W ) ( _Or ( OP,R) ,_W(W) ) +#define _Or_L( OP,R ,L ) ( _Or ( OP,R) ,_L(L) ) +#define _Or_Q( OP,R ,Q ) ( _Or ( OP,R) ,_Q(Q) ) +#define _O_Mrm( OP ,MO,R,M ) ( _O ( OP ),_Mrm(MO,R,M ) ) +#define _OO_Mrm( OP ,MO,R,M ) ( _OO ( OP ),_Mrm(MO,R,M ) ) +#define _O_Mrm_B( OP ,MO,R,M ,B ) ( _O ( OP ),_Mrm(MO,R,M ) ,_B(B) ) +#define _O_Mrm_W( OP ,MO,R,M ,W ) ( _O ( OP ),_Mrm(MO,R,M ) ,_W(W) ) +#define _O_Mrm_L( OP ,MO,R,M ,L ) ( _O ( OP ),_Mrm(MO,R,M ) ,_L(L) ) +#define _OO_Mrm_B( OP ,MO,R,M ,B ) ( _OO ( OP ),_Mrm(MO,R,M ) ,_B(B) ) +#define _Os_Mrm_sW(OP ,MO,R,M ,W ) ( _Os ( OP,W),_Mrm(MO,R,M ),_sW(W) ) +#define _Os_Mrm_sL(OP ,MO,R,M ,L ) ( _Os ( OP,L),_Mrm(MO,R,M ),_sL(L) ) +#define _O_r_X( OP ,R ,MD,MB,MI,MS ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,0) ) +#define _OO_r_X( OP ,R ,MD,MB,MI,MS ) ( _OO ( OP ),_r_X( R ,MD,MB,MI,MS,0) ) +#define _O_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,1) ,_B(B) ) +#define _O_r_X_W( OP ,R ,MD,MB,MI,MS,W ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,2) ,_W(W) ) +#define _O_r_X_L( OP ,R ,MD,MB,MI,MS,L ) ( _O ( OP ),_r_X( R ,MD,MB,MI,MS,4) ,_L(L) ) +#define _OO_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _OO ( OP ),_r_X( R ,MD,MB,MI,MS,1) ,_B(B) ) +#define _Os_r_X_sW(OP ,R ,MD,MB,MI,MS,W ) ( _Os ( OP,W),_r_X( R ,MD,MB,MI,MS,_sWO(W)),_sW(W)) +#define _Os_r_X_sL(OP ,R ,MD,MB,MI,MS,L ) ( _Os ( OP,L),_r_X( R ,MD,MB,MI,MS,_sLO(L)),_sL(L)) +#define _O_X_B( OP ,MD,MB,MI,MS,B ) ( _O_r_X_B( OP ,0 ,MD,MB,MI,MS ,B) ) +#define _O_X_W( OP ,MD,MB,MI,MS,W ) ( _O_r_X_W( OP ,0 ,MD,MB,MI,MS ,W) ) +#define _O_X_L( OP ,MD,MB,MI,MS,L ) ( _O_r_X_L( OP ,0 ,MD,MB,MI,MS ,L) ) + + +/* --- REX prefixes -------------------------------------------------------- */ + +#define _VOID() ((void)0) +#define _BIT(X) ((X) ? 1 : 0) +#define _d64(W,R,X,B) (_B(0x40|(W)<<3|(R)<<2|(X)<<1|(B))) + +#define __REXwrxb(L,W,R,X,B) ((W|R|X|B) || (L) ? _d64(W,R,X,B) : _VOID()) +#define __REXwrx_(L,W,R,X,MR) (__REXwrxb(L,W,R,X,_BIT(_rIP(MR)?0:_rXP(MR)))) +#define __REXw_x_(L,W,R,X,MR) (__REXwrx_(L,W,_BIT(_rXP(R)),X,MR)) +#define __REX_reg(RR) (__REXwrxb(0,0,0,00,_BIT(_rXP(RR)))) +#define __REX_mem(MB,MI) (__REXwrxb(0,0,0,_BIT(_rXP(MI)),_BIT(_rXP(MB)))) + +// FIXME: can't mix new (SPL,BPL,SIL,DIL) with (AH,BH,CH,DH) +#define _REXBrr(RR,MR) _m64(__REXw_x_(_r1e8lP(RR)||_r1e8lP(MR),0,RR,0,MR)) +#define _REXBmr(MB,MI,RD) _m64(__REXw_x_(_r1e8lP(RD)||_r1e8lP(MB),0,RD,_BIT(_rXP(MI)),MB)) +#define _REXBrm(RS,MB,MI) _REXBmr(MB,MI,RS) + +#define _REXBLrr(RR,MR) _m64(__REXw_x_(_r1e8lP(MR),0,RR,0,MR)) +#define _REXLrr(RR,MR) _m64(__REXw_x_(0,0,RR,0,MR)) +#define _REXLmr(MB,MI,RD) _m64(__REXw_x_(0,0,RD,_BIT(_rXP(MI)),MB)) +#define _REXLrm(RS,MB,MI) _REXLmr(MB,MI,RS) +#define _REXLr(RR) _m64(__REX_reg(RR)) +#define _REXLm(MB,MI) _m64(__REX_mem(MB,MI)) + +#define _REXQrr(RR,MR) _m64only(__REXw_x_(0,1,RR,0,MR)) +#define _REXQmr(MB,MI,RD) _m64only(__REXw_x_(0,1,RD,_BIT(_rXP(MI)),MB)) +#define _REXQrm(RS,MB,MI) _REXQmr(MB,MI,RS) +#define _REXQr(RR) _m64only(__REX_reg(RR)) +#define _REXQm(MB,MI) _m64only(__REX_mem(MB,MI)) + + +/* ========================================================================= */ +/* --- Fully-qualified intrinsic instructions ------------------------------ */ +/* ========================================================================= */ + +/* OPCODE + i = immediate operand + * + r = register operand + * + m = memory operand (disp,base,index,scale) + * + sr/sm = a star preceding a register or memory + * + 0 = top of stack register (for FPU instructions) + * + * NOTE in x86-64 mode: a memory operand with only a valid + * displacement value will lead to the expect absolute mode. If + * RIP addressing is necessary, X86_RIP shall be used as the base + * register argument. + */ + +/* --- ALU instructions ---------------------------------------------------- */ + +enum { + X86_ADD = 0, + X86_OR = 1, + X86_ADC = 2, + X86_SBB = 3, + X86_AND = 4, + X86_SUB = 5, + X86_XOR = 6, + X86_CMP = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _ALUBrr(OP,RS, RD) (_REXBrr(RS, RD), _O_Mrm (((OP) << 3) ,_b11,_r1(RS),_r1(RD) )) +#define _ALUBmr(OP, MD, MB, MI, MS, RD) (_REXBmr(MB, MI, RD), _O_r_X (((OP) << 3) + 2 ,_r1(RD) ,MD,MB,MI,MS )) +#define _ALUBrm(OP, RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (((OP) << 3) ,_r1(RS) ,MD,MB,MI,MS )) +#define _ALUBir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AL) ? \ + (_REXBrr(0, RD), _O_B (((OP) << 3) + 4 ,_su8(IM))) : \ + (_REXBrr(0, RD), _O_Mrm_B (0x80 ,_b11,OP ,_r1(RD) ,_su8(IM))) ) +#define _ALUBim(OP, IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X_B (0x80 ,OP ,MD,MB,MI,MS ,_su8(IM))) + +#define _ALUWrr(OP, RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r2(RS),_r2(RD) )) +#define _ALUWmr(OP, MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r2(RD) ,MD,MB,MI,MS )) +#define _ALUWrm(OP, RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r2(RS) ,MD,MB,MI,MS )) +#define _ALUWir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AX) ? \ + (_d16(), _REXLrr(0, RD), _O_W (((OP) << 3) + 5 ,_su16(IM))) : \ + (_d16(), _REXLrr(0, RD), _Os_Mrm_sW (0x81 ,_b11,OP ,_r2(RD) ,_su16(IM))) ) +#define _ALUWim(OP, IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _Os_r_X_sW (0x81 ,OP ,MD,MB,MI,MS ,_su16(IM))) + +#define _ALULrr(OP, RS, RD) (_REXLrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r4(RS),_r4(RD) )) +#define _ALULmr(OP, MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r4(RD) ,MD,MB,MI,MS )) +#define _ALULrm(OP, RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r4(RS) ,MD,MB,MI,MS )) +#define _ALULir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_EAX) ? \ + (_REXLrr(0, RD), _O_L (((OP) << 3) + 5 ,IM )) : \ + (_REXLrr(0, RD), _Os_Mrm_sL (0x81 ,_b11,OP ,_r4(RD) ,IM )) ) +#define _ALULim(OP, IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _Os_r_X_sL (0x81 ,OP ,MD,MB,MI,MS ,IM )) + +#define _ALUQrr(OP, RS, RD) (_REXQrr(RS, RD), _O_Mrm (((OP) << 3) + 1,_b11,_r8(RS),_r8(RD) )) +#define _ALUQmr(OP, MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (((OP) << 3) + 3 ,_r8(RD) ,MD,MB,MI,MS )) +#define _ALUQrm(OP, RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (((OP) << 3) + 1 ,_r8(RS) ,MD,MB,MI,MS )) +#define _ALUQir(OP, IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_RAX) ? \ + (_REXQrr(0, RD), _O_L (((OP) << 3) + 5 ,IM )) : \ + (_REXQrr(0, RD), _Os_Mrm_sL (0x81 ,_b11,OP ,_r8(RD) ,IM )) ) +#define _ALUQim(OP, IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _Os_r_X_sL (0x81 ,OP ,MD,MB,MI,MS ,IM )) + +#define ADCBrr(RS, RD) _ALUBrr(X86_ADC, RS, RD) +#define ADCBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCBir(IM, RD) _ALUBir(X86_ADC, IM, RD) +#define ADCBim(IM, MD, MB, MI, MS) _ALUBim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADCWrr(RS, RD) _ALUWrr(X86_ADC, RS, RD) +#define ADCWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCWir(IM, RD) _ALUWir(X86_ADC, IM, RD) +#define ADCWim(IM, MD, MB, MI, MS) _ALUWim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADCLrr(RS, RD) _ALULrr(X86_ADC, RS, RD) +#define ADCLmr(MD, MB, MI, MS, RD) _ALULmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCLrm(RS, MD, MB, MI, MS) _ALULrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCLir(IM, RD) _ALULir(X86_ADC, IM, RD) +#define ADCLim(IM, MD, MB, MI, MS) _ALULim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADCQrr(RS, RD) _ALUQrr(X86_ADC, RS, RD) +#define ADCQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADC, MD, MB, MI, MS, RD) +#define ADCQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADC, RS, MD, MB, MI, MS) +#define ADCQir(IM, RD) _ALUQir(X86_ADC, IM, RD) +#define ADCQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADC, IM, MD, MB, MI, MS) + +#define ADDBrr(RS, RD) _ALUBrr(X86_ADD, RS, RD) +#define ADDBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDBir(IM, RD) _ALUBir(X86_ADD, IM, RD) +#define ADDBim(IM, MD, MB, MI, MS) _ALUBim(X86_ADD, IM, MD, MB, MI, MS) + +#define ADDWrr(RS, RD) _ALUWrr(X86_ADD, RS, RD) +#define ADDWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDWir(IM, RD) _ALUWir(X86_ADD, IM, RD) +#define ADDWim(IM, MD, MB, MI, MS) _ALUWim(X86_ADD, IM, MD, MB, MI, MS) + +#define ADDLrr(RS, RD) _ALULrr(X86_ADD, RS, RD) +#define ADDLmr(MD, MB, MI, MS, RD) _ALULmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDLrm(RS, MD, MB, MI, MS) _ALULrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDLir(IM, RD) _ALULir(X86_ADD, IM, RD) +#define ADDLim(IM, MD, MB, MI, MS) _ALULim(X86_ADD, IM, MD, MB, MI, MS) + +#define ADDQrr(RS, RD) _ALUQrr(X86_ADD, RS, RD) +#define ADDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADD, MD, MB, MI, MS, RD) +#define ADDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADD, RS, MD, MB, MI, MS) +#define ADDQir(IM, RD) _ALUQir(X86_ADD, IM, RD) +#define ADDQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADD, IM, MD, MB, MI, MS) + +#define ANDBrr(RS, RD) _ALUBrr(X86_AND, RS, RD) +#define ANDBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDBir(IM, RD) _ALUBir(X86_AND, IM, RD) +#define ANDBim(IM, MD, MB, MI, MS) _ALUBim(X86_AND, IM, MD, MB, MI, MS) + +#define ANDWrr(RS, RD) _ALUWrr(X86_AND, RS, RD) +#define ANDWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDWir(IM, RD) _ALUWir(X86_AND, IM, RD) +#define ANDWim(IM, MD, MB, MI, MS) _ALUWim(X86_AND, IM, MD, MB, MI, MS) + +#define ANDLrr(RS, RD) _ALULrr(X86_AND, RS, RD) +#define ANDLmr(MD, MB, MI, MS, RD) _ALULmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDLrm(RS, MD, MB, MI, MS) _ALULrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDLir(IM, RD) _ALULir(X86_AND, IM, RD) +#define ANDLim(IM, MD, MB, MI, MS) _ALULim(X86_AND, IM, MD, MB, MI, MS) + +#define ANDQrr(RS, RD) _ALUQrr(X86_AND, RS, RD) +#define ANDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_AND, MD, MB, MI, MS, RD) +#define ANDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_AND, RS, MD, MB, MI, MS) +#define ANDQir(IM, RD) _ALUQir(X86_AND, IM, RD) +#define ANDQim(IM, MD, MB, MI, MS) _ALUQim(X86_AND, IM, MD, MB, MI, MS) + +#define CMPBrr(RS, RD) _ALUBrr(X86_CMP, RS, RD) +#define CMPBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPBir(IM, RD) _ALUBir(X86_CMP, IM, RD) +#define CMPBim(IM, MD, MB, MI, MS) _ALUBim(X86_CMP, IM, MD, MB, MI, MS) + +#define CMPWrr(RS, RD) _ALUWrr(X86_CMP, RS, RD) +#define CMPWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPWir(IM, RD) _ALUWir(X86_CMP, IM, RD) +#define CMPWim(IM, MD, MB, MI, MS) _ALUWim(X86_CMP, IM, MD, MB, MI, MS) + +#define CMPLrr(RS, RD) _ALULrr(X86_CMP, RS, RD) +#define CMPLmr(MD, MB, MI, MS, RD) _ALULmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPLrm(RS, MD, MB, MI, MS) _ALULrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPLir(IM, RD) _ALULir(X86_CMP, IM, RD) +#define CMPLim(IM, MD, MB, MI, MS) _ALULim(X86_CMP, IM, MD, MB, MI, MS) + +#define CMPQrr(RS, RD) _ALUQrr(X86_CMP, RS, RD) +#define CMPQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_CMP, MD, MB, MI, MS, RD) +#define CMPQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_CMP, RS, MD, MB, MI, MS) +#define CMPQir(IM, RD) _ALUQir(X86_CMP, IM, RD) +#define CMPQim(IM, MD, MB, MI, MS) _ALUQim(X86_CMP, IM, MD, MB, MI, MS) + +#define ORBrr(RS, RD) _ALUBrr(X86_OR, RS, RD) +#define ORBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_OR, MD, MB, MI, MS, RD) +#define ORBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_OR, RS, MD, MB, MI, MS) +#define ORBir(IM, RD) _ALUBir(X86_OR, IM, RD) +#define ORBim(IM, MD, MB, MI, MS) _ALUBim(X86_OR, IM, MD, MB, MI, MS) + +#define ORWrr(RS, RD) _ALUWrr(X86_OR, RS, RD) +#define ORWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_OR, MD, MB, MI, MS, RD) +#define ORWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_OR, RS, MD, MB, MI, MS) +#define ORWir(IM, RD) _ALUWir(X86_OR, IM, RD) +#define ORWim(IM, MD, MB, MI, MS) _ALUWim(X86_OR, IM, MD, MB, MI, MS) + +#define ORLrr(RS, RD) _ALULrr(X86_OR, RS, RD) +#define ORLmr(MD, MB, MI, MS, RD) _ALULmr(X86_OR, MD, MB, MI, MS, RD) +#define ORLrm(RS, MD, MB, MI, MS) _ALULrm(X86_OR, RS, MD, MB, MI, MS) +#define ORLir(IM, RD) _ALULir(X86_OR, IM, RD) +#define ORLim(IM, MD, MB, MI, MS) _ALULim(X86_OR, IM, MD, MB, MI, MS) + +#define ORQrr(RS, RD) _ALUQrr(X86_OR, RS, RD) +#define ORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_OR, MD, MB, MI, MS, RD) +#define ORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_OR, RS, MD, MB, MI, MS) +#define ORQir(IM, RD) _ALUQir(X86_OR, IM, RD) +#define ORQim(IM, MD, MB, MI, MS) _ALUQim(X86_OR, IM, MD, MB, MI, MS) + +#define SBBBrr(RS, RD) _ALUBrr(X86_SBB, RS, RD) +#define SBBBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBBir(IM, RD) _ALUBir(X86_SBB, IM, RD) +#define SBBBim(IM, MD, MB, MI, MS) _ALUBim(X86_SBB, IM, MD, MB, MI, MS) + +#define SBBWrr(RS, RD) _ALUWrr(X86_SBB, RS, RD) +#define SBBWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBWir(IM, RD) _ALUWir(X86_SBB, IM, RD) +#define SBBWim(IM, MD, MB, MI, MS) _ALUWim(X86_SBB, IM, MD, MB, MI, MS) + +#define SBBLrr(RS, RD) _ALULrr(X86_SBB, RS, RD) +#define SBBLmr(MD, MB, MI, MS, RD) _ALULmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBLrm(RS, MD, MB, MI, MS) _ALULrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBLir(IM, RD) _ALULir(X86_SBB, IM, RD) +#define SBBLim(IM, MD, MB, MI, MS) _ALULim(X86_SBB, IM, MD, MB, MI, MS) + +#define SBBQrr(RS, RD) _ALUQrr(X86_SBB, RS, RD) +#define SBBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SBB, MD, MB, MI, MS, RD) +#define SBBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SBB, RS, MD, MB, MI, MS) +#define SBBQir(IM, RD) _ALUQir(X86_SBB, IM, RD) +#define SBBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SBB, IM, MD, MB, MI, MS) + +#define SUBBrr(RS, RD) _ALUBrr(X86_SUB, RS, RD) +#define SUBBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBBir(IM, RD) _ALUBir(X86_SUB, IM, RD) +#define SUBBim(IM, MD, MB, MI, MS) _ALUBim(X86_SUB, IM, MD, MB, MI, MS) + +#define SUBWrr(RS, RD) _ALUWrr(X86_SUB, RS, RD) +#define SUBWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBWir(IM, RD) _ALUWir(X86_SUB, IM, RD) +#define SUBWim(IM, MD, MB, MI, MS) _ALUWim(X86_SUB, IM, MD, MB, MI, MS) + +#define SUBLrr(RS, RD) _ALULrr(X86_SUB, RS, RD) +#define SUBLmr(MD, MB, MI, MS, RD) _ALULmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBLrm(RS, MD, MB, MI, MS) _ALULrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBLir(IM, RD) _ALULir(X86_SUB, IM, RD) +#define SUBLim(IM, MD, MB, MI, MS) _ALULim(X86_SUB, IM, MD, MB, MI, MS) + +#define SUBQrr(RS, RD) _ALUQrr(X86_SUB, RS, RD) +#define SUBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SUB, MD, MB, MI, MS, RD) +#define SUBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SUB, RS, MD, MB, MI, MS) +#define SUBQir(IM, RD) _ALUQir(X86_SUB, IM, RD) +#define SUBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SUB, IM, MD, MB, MI, MS) + +#define XORBrr(RS, RD) _ALUBrr(X86_XOR, RS, RD) +#define XORBmr(MD, MB, MI, MS, RD) _ALUBmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORBrm(RS, MD, MB, MI, MS) _ALUBrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORBir(IM, RD) _ALUBir(X86_XOR, IM, RD) +#define XORBim(IM, MD, MB, MI, MS) _ALUBim(X86_XOR, IM, MD, MB, MI, MS) + +#define XORWrr(RS, RD) _ALUWrr(X86_XOR, RS, RD) +#define XORWmr(MD, MB, MI, MS, RD) _ALUWmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORWrm(RS, MD, MB, MI, MS) _ALUWrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORWir(IM, RD) _ALUWir(X86_XOR, IM, RD) +#define XORWim(IM, MD, MB, MI, MS) _ALUWim(X86_XOR, IM, MD, MB, MI, MS) + +#define XORLrr(RS, RD) _ALULrr(X86_XOR, RS, RD) +#define XORLmr(MD, MB, MI, MS, RD) _ALULmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORLrm(RS, MD, MB, MI, MS) _ALULrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORLir(IM, RD) _ALULir(X86_XOR, IM, RD) +#define XORLim(IM, MD, MB, MI, MS) _ALULim(X86_XOR, IM, MD, MB, MI, MS) + +#define XORQrr(RS, RD) _ALUQrr(X86_XOR, RS, RD) +#define XORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_XOR, MD, MB, MI, MS, RD) +#define XORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_XOR, RS, MD, MB, MI, MS) +#define XORQir(IM, RD) _ALUQir(X86_XOR, IM, RD) +#define XORQim(IM, MD, MB, MI, MS) _ALUQim(X86_XOR, IM, MD, MB, MI, MS) + + +/* --- Shift/Rotate instructions ------------------------------------------- */ + +enum { + X86_ROL = 0, + X86_ROR = 1, + X86_RCL = 2, + X86_RCR = 3, + X86_SHL = 4, + X86_SHR = 5, + X86_SAR = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _ROTSHIBir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXBrr(0, RD), _O_Mrm (0xd0 ,_b11,OP,_r1(RD) )) : \ + (_REXBrr(0, RD), _O_Mrm_B (0xc0 ,_b11,OP,_r1(RD) ,_u8(IM))) ) +#define _ROTSHIBim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXBrm(0, MB, MI), _O_r_X (0xd0 ,OP ,MD,MB,MI,MS )) : \ + (_REXBrm(0, MB, MI), _O_r_X_B (0xc0 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHIBrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_REXBrr(RS, RD), _O_Mrm (0xd2 ,_b11,OP,_r1(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHIBrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_REXBrm(RS, MB, MI), _O_r_X (0xd2 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define _ROTSHIWir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_d16(), _REXLrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r2(RD) )) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r2(RD) ,_u8(IM))) ) +#define _ROTSHIWim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ + (_d16(), _REXLrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHIWrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_d16(), _REXLrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r2(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHIWrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define _ROTSHILir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXLrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r4(RD) )) : \ + (_REXLrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r4(RD) ,_u8(IM))) ) +#define _ROTSHILim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXLrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ + (_REXLrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHILrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_REXLrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r4(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHILrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_REXLrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define _ROTSHIQir(OP,IM,RD) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXQrr(0, RD), _O_Mrm (0xd1 ,_b11,OP,_r8(RD) )) : \ + (_REXQrr(0, RD), _O_Mrm_B (0xc1 ,_b11,OP,_r8(RD) ,_u8(IM))) ) +#define _ROTSHIQim(OP,IM,MD,MB,MI,MS) (X86_OPTIMIZE_ROTSHI && ((IM) == 1) ? \ + (_REXQrm(0, MB, MI), _O_r_X (0xd1 ,OP ,MD,MB,MI,MS )) : \ + (_REXQrm(0, MB, MI), _O_r_X_B (0xc1 ,OP ,MD,MB,MI,MS ,_u8(IM))) ) +#define _ROTSHIQrr(OP,RS,RD) (((RS) == X86_CL) ? \ + (_REXQrr(RS, RD), _O_Mrm (0xd3 ,_b11,OP,_r8(RD) )) : \ + x86_emit_failure("source register must be CL" ) ) +#define _ROTSHIQrm(OP,RS,MD,MB,MI,MS) (((RS) == X86_CL) ? \ + (_REXQrm(RS, MB, MI), _O_r_X (0xd3 ,OP ,MD,MB,MI,MS )) : \ + x86_emit_failure("source register must be CL" ) ) + +#define ROLBir(IM, RD) _ROTSHIBir(X86_ROL, IM, RD) +#define ROLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLBrr(RS, RD) _ROTSHIBrr(X86_ROL, RS, RD) +#define ROLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_ROL, RS, MD, MB, MI, MS) + +#define ROLWir(IM, RD) _ROTSHIWir(X86_ROL, IM, RD) +#define ROLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLWrr(RS, RD) _ROTSHIWrr(X86_ROL, RS, RD) +#define ROLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_ROL, RS, MD, MB, MI, MS) + +#define ROLLir(IM, RD) _ROTSHILir(X86_ROL, IM, RD) +#define ROLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLLrr(RS, RD) _ROTSHILrr(X86_ROL, RS, RD) +#define ROLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_ROL, RS, MD, MB, MI, MS) + +#define ROLQir(IM, RD) _ROTSHIQir(X86_ROL, IM, RD) +#define ROLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROL, IM, MD, MB, MI, MS) +#define ROLQrr(RS, RD) _ROTSHIQrr(X86_ROL, RS, RD) +#define ROLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROL, RS, MD, MB, MI, MS) + +#define RORBir(IM, RD) _ROTSHIBir(X86_ROR, IM, RD) +#define RORBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_ROR, IM, MD, MB, MI, MS) +#define RORBrr(RS, RD) _ROTSHIBrr(X86_ROR, RS, RD) +#define RORBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RORWir(IM, RD) _ROTSHIWir(X86_ROR, IM, RD) +#define RORWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_ROR, IM, MD, MB, MI, MS) +#define RORWrr(RS, RD) _ROTSHIWrr(X86_ROR, RS, RD) +#define RORWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RORLir(IM, RD) _ROTSHILir(X86_ROR, IM, RD) +#define RORLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_ROR, IM, MD, MB, MI, MS) +#define RORLrr(RS, RD) _ROTSHILrr(X86_ROR, RS, RD) +#define RORLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RORQir(IM, RD) _ROTSHIQir(X86_ROR, IM, RD) +#define RORQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROR, IM, MD, MB, MI, MS) +#define RORQrr(RS, RD) _ROTSHIQrr(X86_ROR, RS, RD) +#define RORQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROR, RS, MD, MB, MI, MS) + +#define RCLBir(IM, RD) _ROTSHIBir(X86_RCL, IM, RD) +#define RCLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLBrr(RS, RD) _ROTSHIBrr(X86_RCL, RS, RD) +#define RCLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCLWir(IM, RD) _ROTSHIWir(X86_RCL, IM, RD) +#define RCLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLWrr(RS, RD) _ROTSHIWrr(X86_RCL, RS, RD) +#define RCLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCLLir(IM, RD) _ROTSHILir(X86_RCL, IM, RD) +#define RCLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLLrr(RS, RD) _ROTSHILrr(X86_RCL, RS, RD) +#define RCLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCLQir(IM, RD) _ROTSHIQir(X86_RCL, IM, RD) +#define RCLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCL, IM, MD, MB, MI, MS) +#define RCLQrr(RS, RD) _ROTSHIQrr(X86_RCL, RS, RD) +#define RCLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCL, RS, MD, MB, MI, MS) + +#define RCRBir(IM, RD) _ROTSHIBir(X86_RCR, IM, RD) +#define RCRBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRBrr(RS, RD) _ROTSHIBrr(X86_RCR, RS, RD) +#define RCRBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_RCR, RS, MD, MB, MI, MS) + +#define RCRWir(IM, RD) _ROTSHIWir(X86_RCR, IM, RD) +#define RCRWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRWrr(RS, RD) _ROTSHIWrr(X86_RCR, RS, RD) +#define RCRWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_RCR, RS, MD, MB, MI, MS) + +#define RCRLir(IM, RD) _ROTSHILir(X86_RCR, IM, RD) +#define RCRLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRLrr(RS, RD) _ROTSHILrr(X86_RCR, RS, RD) +#define RCRLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_RCR, RS, MD, MB, MI, MS) + +#define RCRQir(IM, RD) _ROTSHIQir(X86_RCR, IM, RD) +#define RCRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCR, IM, MD, MB, MI, MS) +#define RCRQrr(RS, RD) _ROTSHIQrr(X86_RCR, RS, RD) +#define RCRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCR, RS, MD, MB, MI, MS) + +#define SHLBir(IM, RD) _ROTSHIBir(X86_SHL, IM, RD) +#define SHLBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLBrr(RS, RD) _ROTSHIBrr(X86_SHL, RS, RD) +#define SHLBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHLWir(IM, RD) _ROTSHIWir(X86_SHL, IM, RD) +#define SHLWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLWrr(RS, RD) _ROTSHIWrr(X86_SHL, RS, RD) +#define SHLWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHLLir(IM, RD) _ROTSHILir(X86_SHL, IM, RD) +#define SHLLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLLrr(RS, RD) _ROTSHILrr(X86_SHL, RS, RD) +#define SHLLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHLQir(IM, RD) _ROTSHIQir(X86_SHL, IM, RD) +#define SHLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHL, IM, MD, MB, MI, MS) +#define SHLQrr(RS, RD) _ROTSHIQrr(X86_SHL, RS, RD) +#define SHLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHL, RS, MD, MB, MI, MS) + +#define SHRBir(IM, RD) _ROTSHIBir(X86_SHR, IM, RD) +#define SHRBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRBrr(RS, RD) _ROTSHIBrr(X86_SHR, RS, RD) +#define SHRBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SHRWir(IM, RD) _ROTSHIWir(X86_SHR, IM, RD) +#define SHRWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRWrr(RS, RD) _ROTSHIWrr(X86_SHR, RS, RD) +#define SHRWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SHRLir(IM, RD) _ROTSHILir(X86_SHR, IM, RD) +#define SHRLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRLrr(RS, RD) _ROTSHILrr(X86_SHR, RS, RD) +#define SHRLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SHRQir(IM, RD) _ROTSHIQir(X86_SHR, IM, RD) +#define SHRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHR, IM, MD, MB, MI, MS) +#define SHRQrr(RS, RD) _ROTSHIQrr(X86_SHR, RS, RD) +#define SHRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHR, RS, MD, MB, MI, MS) + +#define SALBir SHLBir +#define SALBim SHLBim +#define SALBrr SHLBrr +#define SALBrm SHLBrm + +#define SALWir SHLWir +#define SALWim SHLWim +#define SALWrr SHLWrr +#define SALWrm SHLWrm + +#define SALLir SHLLir +#define SALLim SHLLim +#define SALLrr SHLLrr +#define SALLrm SHLLrm + +#define SALQir SHLQir +#define SALQim SHLQim +#define SALQrr SHLQrr +#define SALQrm SHLQrm + +#define SARBir(IM, RD) _ROTSHIBir(X86_SAR, IM, RD) +#define SARBim(IM, MD, MB, MI, MS) _ROTSHIBim(X86_SAR, IM, MD, MB, MI, MS) +#define SARBrr(RS, RD) _ROTSHIBrr(X86_SAR, RS, RD) +#define SARBrm(RS, MD, MB, MI, MS) _ROTSHIBrm(X86_SAR, RS, MD, MB, MI, MS) + +#define SARWir(IM, RD) _ROTSHIWir(X86_SAR, IM, RD) +#define SARWim(IM, MD, MB, MI, MS) _ROTSHIWim(X86_SAR, IM, MD, MB, MI, MS) +#define SARWrr(RS, RD) _ROTSHIWrr(X86_SAR, RS, RD) +#define SARWrm(RS, MD, MB, MI, MS) _ROTSHIWrm(X86_SAR, RS, MD, MB, MI, MS) + +#define SARLir(IM, RD) _ROTSHILir(X86_SAR, IM, RD) +#define SARLim(IM, MD, MB, MI, MS) _ROTSHILim(X86_SAR, IM, MD, MB, MI, MS) +#define SARLrr(RS, RD) _ROTSHILrr(X86_SAR, RS, RD) +#define SARLrm(RS, MD, MB, MI, MS) _ROTSHILrm(X86_SAR, RS, MD, MB, MI, MS) + +#define SARQir(IM, RD) _ROTSHIQir(X86_SAR, IM, RD) +#define SARQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SAR, IM, MD, MB, MI, MS) +#define SARQrr(RS, RD) _ROTSHIQrr(X86_SAR, RS, RD) +#define SARQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SAR, RS, MD, MB, MI, MS) + + +/* --- Bit test instructions ----------------------------------------------- */ + +enum { + X86_BT = 4, + X86_BTS = 5, + X86_BTR = 6, + X86_BTC = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _BTWir(OP, IM, RD) (_d16(), _REXLrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r2(RD) ,_u8(IM))) +#define _BTWim(OP, IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) +#define _BTWrr(OP, RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r2(RS),_r2(RD) )) +#define _BTWrm(OP, RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r2(RS) ,MD,MB,MI,MS )) + +#define _BTLir(OP, IM, RD) (_REXLrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r4(RD) ,_u8(IM))) +#define _BTLim(OP, IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) +#define _BTLrr(OP, RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r4(RS),_r4(RD) )) +#define _BTLrm(OP, RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r4(RS) ,MD,MB,MI,MS )) + +#define _BTQir(OP, IM, RD) (_REXQrr(0, RD), _OO_Mrm_B (0x0fba ,_b11,OP ,_r8(RD) ,_u8(IM))) +#define _BTQim(OP, IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _OO_r_X_B (0x0fba ,OP ,MD,MB,MI,MS ,_u8(IM))) +#define _BTQrr(OP, RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0f83|((OP)<<3),_b11,_r8(RS),_r8(RD) )) +#define _BTQrm(OP, RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f83|((OP)<<3) ,_r8(RS) ,MD,MB,MI,MS )) + +#define BTWir(IM, RD) _BTWir(X86_BT, IM, RD) +#define BTWim(IM, MD, MB, MI, MS) _BTWim(X86_BT, IM, MD, MB, MI, MS) +#define BTWrr(RS, RD) _BTWrr(X86_BT, RS, RD) +#define BTWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BT, RS, MD, MB, MI, MS) + +#define BTLir(IM, RD) _BTLir(X86_BT, IM, RD) +#define BTLim(IM, MD, MB, MI, MS) _BTLim(X86_BT, IM, MD, MB, MI, MS) +#define BTLrr(RS, RD) _BTLrr(X86_BT, RS, RD) +#define BTLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BT, RS, MD, MB, MI, MS) + +#define BTQir(IM, RD) _BTQir(X86_BT, IM, RD) +#define BTQim(IM, MD, MB, MI, MS) _BTQim(X86_BT, IM, MD, MB, MI, MS) +#define BTQrr(RS, RD) _BTQrr(X86_BT, RS, RD) +#define BTQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BT, RS, MD, MB, MI, MS) + +#define BTCWir(IM, RD) _BTWir(X86_BTC, IM, RD) +#define BTCWim(IM, MD, MB, MI, MS) _BTWim(X86_BTC, IM, MD, MB, MI, MS) +#define BTCWrr(RS, RD) _BTWrr(X86_BTC, RS, RD) +#define BTCWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTC, RS, MD, MB, MI, MS) + +#define BTCLir(IM, RD) _BTLir(X86_BTC, IM, RD) +#define BTCLim(IM, MD, MB, MI, MS) _BTLim(X86_BTC, IM, MD, MB, MI, MS) +#define BTCLrr(RS, RD) _BTLrr(X86_BTC, RS, RD) +#define BTCLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTC, RS, MD, MB, MI, MS) + +#define BTCQir(IM, RD) _BTQir(X86_BTC, IM, RD) +#define BTCQim(IM, MD, MB, MI, MS) _BTQim(X86_BTC, IM, MD, MB, MI, MS) +#define BTCQrr(RS, RD) _BTQrr(X86_BTC, RS, RD) +#define BTCQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTC, RS, MD, MB, MI, MS) + +#define BTRWir(IM, RD) _BTWir(X86_BTR, IM, RD) +#define BTRWim(IM, MD, MB, MI, MS) _BTWim(X86_BTR, IM, MD, MB, MI, MS) +#define BTRWrr(RS, RD) _BTWrr(X86_BTR, RS, RD) +#define BTRWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTR, RS, MD, MB, MI, MS) + +#define BTRLir(IM, RD) _BTLir(X86_BTR, IM, RD) +#define BTRLim(IM, MD, MB, MI, MS) _BTLim(X86_BTR, IM, MD, MB, MI, MS) +#define BTRLrr(RS, RD) _BTLrr(X86_BTR, RS, RD) +#define BTRLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTR, RS, MD, MB, MI, MS) + +#define BTRQir(IM, RD) _BTQir(X86_BTR, IM, RD) +#define BTRQim(IM, MD, MB, MI, MS) _BTQim(X86_BTR, IM, MD, MB, MI, MS) +#define BTRQrr(RS, RD) _BTQrr(X86_BTR, RS, RD) +#define BTRQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTR, RS, MD, MB, MI, MS) + +#define BTSWir(IM, RD) _BTWir(X86_BTS, IM, RD) +#define BTSWim(IM, MD, MB, MI, MS) _BTWim(X86_BTS, IM, MD, MB, MI, MS) +#define BTSWrr(RS, RD) _BTWrr(X86_BTS, RS, RD) +#define BTSWrm(RS, MD, MB, MI, MS) _BTWrm(X86_BTS, RS, MD, MB, MI, MS) + +#define BTSLir(IM, RD) _BTLir(X86_BTS, IM, RD) +#define BTSLim(IM, MD, MB, MI, MS) _BTLim(X86_BTS, IM, MD, MB, MI, MS) +#define BTSLrr(RS, RD) _BTLrr(X86_BTS, RS, RD) +#define BTSLrm(RS, MD, MB, MI, MS) _BTLrm(X86_BTS, RS, MD, MB, MI, MS) + +#define BTSQir(IM, RD) _BTQir(X86_BTS, IM, RD) +#define BTSQim(IM, MD, MB, MI, MS) _BTQim(X86_BTS, IM, MD, MB, MI, MS) +#define BTSQrr(RS, RD) _BTQrr(X86_BTS, RS, RD) +#define BTSQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTS, RS, MD, MB, MI, MS) + + +/* --- Move instructions --------------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define MOVBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x88 ,_b11,_r1(RS),_r1(RD) )) +#define MOVBmr(MD, MB, MI, MS, RD) (_REXBmr(MB, MI, RD), _O_r_X (0x8a ,_r1(RD) ,MD,MB,MI,MS )) +#define MOVBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x88 ,_r1(RS) ,MD,MB,MI,MS )) +#define MOVBir(IM, R) (_REXBrr(0, R), _Or_B (0xb0,_r1(R) ,_su8(IM))) +#define MOVBim(IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_X_B (0xc6 ,MD,MB,MI,MS ,_su8(IM))) + +#define MOVWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x89 ,_b11,_r2(RS),_r2(RD) )) +#define MOVWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _O_r_X (0x8b ,_r2(RD) ,MD,MB,MI,MS )) +#define MOVWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x89 ,_r2(RS) ,MD,MB,MI,MS )) +#define MOVWir(IM, R) (_d16(), _REXLrr(0, R), _Or_W (0xb8,_r2(R) ,_su16(IM))) +#define MOVWim(IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_X_W (0xc7 ,MD,MB,MI,MS ,_su16(IM))) + +#define MOVLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x89 ,_b11,_r4(RS),_r4(RD) )) +#define MOVLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (0x8b ,_r4(RD) ,MD,MB,MI,MS )) +#define MOVLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x89 ,_r4(RS) ,MD,MB,MI,MS )) +#define MOVLir(IM, R) (_REXLrr(0, R), _Or_L (0xb8,_r4(R) ,IM )) +#define MOVLim(IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM )) + +#define MOVQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x89 ,_b11,_r8(RS),_r8(RD) )) +#define MOVQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8b ,_r8(RD) ,MD,MB,MI,MS )) +#define MOVQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x89 ,_r8(RS) ,MD,MB,MI,MS )) +#define MOVQir(IM, R) (_REXQrr(0, R), _Or_Q (0xb8,_r8(R) ,IM )) +#define MOVQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM )) + + +/* --- Unary and Multiply/Divide instructions ------------------------------ */ + +enum { + X86_NOT = 2, + X86_NEG = 3, + X86_MUL = 4, + X86_IMUL = 5, + X86_DIV = 6, + X86_IDIV = 7, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _UNARYBr(OP, RS) (_REXBrr(0, RS), _O_Mrm (0xf6 ,_b11,OP ,_r1(RS) )) +#define _UNARYBm(OP, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xf6 ,OP ,MD,MB,MI,MS )) +#define _UNARYWr(OP, RS) (_d16(), _REXLrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r2(RS) )) +#define _UNARYWm(OP, MD, MB, MI, MS) (_d16(), _REXLmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) +#define _UNARYLr(OP, RS) (_REXLrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r4(RS) )) +#define _UNARYLm(OP, MD, MB, MI, MS) (_REXLmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) +#define _UNARYQr(OP, RS) (_REXQrr(0, RS), _O_Mrm (0xf7 ,_b11,OP ,_r8(RS) )) +#define _UNARYQm(OP, MD, MB, MI, MS) (_REXQmr(MB, MI, 0), _O_r_X (0xf7 ,OP ,MD,MB,MI,MS )) + +#define NOTBr(RS) _UNARYBr(X86_NOT, RS) +#define NOTBm(MD, MB, MI, MS) _UNARYBm(X86_NOT, MD, MB, MI, MS) +#define NOTWr(RS) _UNARYWr(X86_NOT, RS) +#define NOTWm(MD, MB, MI, MS) _UNARYWm(X86_NOT, MD, MB, MI, MS) +#define NOTLr(RS) _UNARYLr(X86_NOT, RS) +#define NOTLm(MD, MB, MI, MS) _UNARYLm(X86_NOT, MD, MB, MI, MS) +#define NOTQr(RS) _UNARYQr(X86_NOT, RS) +#define NOTQm(MD, MB, MI, MS) _UNARYQm(X86_NOT, MD, MB, MI, MS) + +#define NEGBr(RS) _UNARYBr(X86_NEG, RS) +#define NEGBm(MD, MB, MI, MS) _UNARYBm(X86_NEG, MD, MB, MI, MS) +#define NEGWr(RS) _UNARYWr(X86_NEG, RS) +#define NEGWm(MD, MB, MI, MS) _UNARYWm(X86_NEG, MD, MB, MI, MS) +#define NEGLr(RS) _UNARYLr(X86_NEG, RS) +#define NEGLm(MD, MB, MI, MS) _UNARYLm(X86_NEG, MD, MB, MI, MS) +#define NEGQr(RS) _UNARYQr(X86_NEG, RS) +#define NEGQm(MD, MB, MI, MS) _UNARYQm(X86_NEG, MD, MB, MI, MS) + +#define MULBr(RS) _UNARYBr(X86_MUL, RS) +#define MULBm(MD, MB, MI, MS) _UNARYBm(X86_MUL, MD, MB, MI, MS) +#define MULWr(RS) _UNARYWr(X86_MUL, RS) +#define MULWm(MD, MB, MI, MS) _UNARYWm(X86_MUL, MD, MB, MI, MS) +#define MULLr(RS) _UNARYLr(X86_MUL, RS) +#define MULLm(MD, MB, MI, MS) _UNARYLm(X86_MUL, MD, MB, MI, MS) +#define MULQr(RS) _UNARYQr(X86_MUL, RS) +#define MULQm(MD, MB, MI, MS) _UNARYQm(X86_MUL, MD, MB, MI, MS) + +#define IMULBr(RS) _UNARYBr(X86_IMUL, RS) +#define IMULBm(MD, MB, MI, MS) _UNARYBm(X86_IMUL, MD, MB, MI, MS) +#define IMULWr(RS) _UNARYWr(X86_IMUL, RS) +#define IMULWm(MD, MB, MI, MS) _UNARYWm(X86_IMUL, MD, MB, MI, MS) +#define IMULLr(RS) _UNARYLr(X86_IMUL, RS) +#define IMULLm(MD, MB, MI, MS) _UNARYLm(X86_IMUL, MD, MB, MI, MS) +#define IMULQr(RS) _UNARYQr(X86_IMUL, RS) +#define IMULQm(MD, MB, MI, MS) _UNARYQm(X86_IMUL, MD, MB, MI, MS) + +#define DIVBr(RS) _UNARYBr(X86_DIV, RS) +#define DIVBm(MD, MB, MI, MS) _UNARYBm(X86_DIV, MD, MB, MI, MS) +#define DIVWr(RS) _UNARYWr(X86_DIV, RS) +#define DIVWm(MD, MB, MI, MS) _UNARYWm(X86_DIV, MD, MB, MI, MS) +#define DIVLr(RS) _UNARYLr(X86_DIV, RS) +#define DIVLm(MD, MB, MI, MS) _UNARYLm(X86_DIV, MD, MB, MI, MS) +#define DIVQr(RS) _UNARYQr(X86_DIV, RS) +#define DIVQm(MD, MB, MI, MS) _UNARYQm(X86_DIV, MD, MB, MI, MS) + +#define IDIVBr(RS) _UNARYBr(X86_IDIV, RS) +#define IDIVBm(MD, MB, MI, MS) _UNARYBm(X86_IDIV, MD, MB, MI, MS) +#define IDIVWr(RS) _UNARYWr(X86_IDIV, RS) +#define IDIVWm(MD, MB, MI, MS) _UNARYWm(X86_IDIV, MD, MB, MI, MS) +#define IDIVLr(RS) _UNARYLr(X86_IDIV, RS) +#define IDIVLm(MD, MB, MI, MS) _UNARYLm(X86_IDIV, MD, MB, MI, MS) +#define IDIVQr(RS) _UNARYQr(X86_IDIV, RS) +#define IDIVQm(MD, MB, MI, MS) _UNARYQm(X86_IDIV, MD, MB, MI, MS) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define IMULWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r2(RD),_r2(RS) )) +#define IMULWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0faf ,_r2(RD) ,MD,MB,MI,MS )) + +#define IMULWirr(IM,RS,RD) (_d16(), _REXLrr(RS, RD), _Os_Mrm_sW (0x69 ,_b11,_r2(RS),_r2(RD) ,_su16(IM) )) +#define IMULWimr(IM,MD,MB,MI,MS,RD) (_d16(), _REXLmr(MB, MI, RD), _Os_r_X_sW (0x69 ,_r2(RD) ,MD,MB,MI,MS ,_su16(IM) )) + +#define IMULLir(IM, RD) (_REXLrr(0, RD), _Os_Mrm_sL (0x69 ,_b11,_r4(RD),_r4(RD) ,IM )) +#define IMULLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r4(RD),_r4(RS) )) +#define IMULLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0faf ,_r4(RD) ,MD,MB,MI,MS )) + +#define IMULQir(IM, RD) (_REXQrr(0, RD), _Os_Mrm_sL (0x69 ,_b11,_r8(RD),_r8(RD) ,IM )) +#define IMULQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r8(RD),_r8(RS) )) +#define IMULQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0faf ,_r8(RD) ,MD,MB,MI,MS )) + +#define IMULLirr(IM,RS,RD) (_REXLrr(RS, RD), _Os_Mrm_sL (0x69 ,_b11,_r4(RS),_r4(RD) ,IM )) +#define IMULLimr(IM,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r4(RD) ,MD,MB,MI,MS ,IM )) + +#define IMULQirr(IM,RS,RD) (_REXQrr(RS, RD), _Os_Mrm_sL (0x69 ,_b11,_r8(RS),_r8(RD) ,IM )) +#define IMULQimr(IM,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r8(RD) ,MD,MB,MI,MS ,IM )) + + +/* --- Control Flow related instructions ----------------------------------- */ + +enum { + X86_CC_O = 0x0, + X86_CC_NO = 0x1, + X86_CC_NAE = 0x2, + X86_CC_B = 0x2, + X86_CC_C = 0x2, + X86_CC_AE = 0x3, + X86_CC_NB = 0x3, + X86_CC_NC = 0x3, + X86_CC_E = 0x4, + X86_CC_Z = 0x4, + X86_CC_NE = 0x5, + X86_CC_NZ = 0x5, + X86_CC_BE = 0x6, + X86_CC_NA = 0x6, + X86_CC_A = 0x7, + X86_CC_NBE = 0x7, + X86_CC_S = 0x8, + X86_CC_NS = 0x9, + X86_CC_P = 0xa, + X86_CC_PE = 0xa, + X86_CC_NP = 0xb, + X86_CC_PO = 0xb, + X86_CC_L = 0xc, + X86_CC_NGE = 0xc, + X86_CC_GE = 0xd, + X86_CC_NL = 0xd, + X86_CC_LE = 0xe, + X86_CC_NG = 0xe, + X86_CC_G = 0xf, + X86_CC_NLE = 0xf, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode +#define CALLm(M) _O_D32 (0xe8 ,(int)(M) ) +#define _CALLLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r4(R) )) +#define _CALLQsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r8(R) )) +#define CALLsr(R) ( X86_TARGET_64BIT ? _CALLQsr(R) : _CALLLsr(R)) +#define CALLsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b010 ,(int)(D),B,I,S )) + +// FIXME: no prefix is availble to encode a 32-bit operand size in 64-bit mode +#define JMPSm(M) _O_D8 (0xeb ,(int)(M) ) +#define JMPm(M) _O_D32 (0xe9 ,(int)(M) ) +#define _JMPLsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r4(R) )) +#define _JMPQsr(R) (_REXLrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r8(R) )) +#define JMPsr(R) ( X86_TARGET_64BIT ? _JMPQsr(R) : _JMPLsr(R)) +#define JMPsm(D,B,I,S) (_REXLrm(0, B, I), _O_r_X (0xff ,_b100 ,(int)(D),B,I,S )) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define JCCSii(CC, D) _O_B (0x70|(CC) ,(_sc)(int)(D) ) +#define JCCSim(CC, D) _O_D8 (0x70|(CC) ,(int)(D) ) +#define JOSm(D) JCCSim(X86_CC_O, D) +#define JNOSm(D) JCCSim(X86_CC_NO, D) +#define JBSm(D) JCCSim(X86_CC_B, D) +#define JNAESm(D) JCCSim(X86_CC_NAE, D) +#define JNBSm(D) JCCSim(X86_CC_NB, D) +#define JAESm(D) JCCSim(X86_CC_AE, D) +#define JESm(D) JCCSim(X86_CC_E, D) +#define JZSm(D) JCCSim(X86_CC_Z, D) +#define JNESm(D) JCCSim(X86_CC_NE, D) +#define JNZSm(D) JCCSim(X86_CC_NZ, D) +#define JBESm(D) JCCSim(X86_CC_BE, D) +#define JNASm(D) JCCSim(X86_CC_NA, D) +#define JNBESm(D) JCCSim(X86_CC_NBE, D) +#define JASm(D) JCCSim(X86_CC_A, D) +#define JSSm(D) JCCSim(X86_CC_S, D) +#define JNSSm(D) JCCSim(X86_CC_NS, D) +#define JPSm(D) JCCSim(X86_CC_P, D) +#define JPESm(D) JCCSim(X86_CC_PE, D) +#define JNPSm(D) JCCSim(X86_CC_NP, D) +#define JPOSm(D) JCCSim(X86_CC_PO, D) +#define JLSm(D) JCCSim(X86_CC_L, D) +#define JNGESm(D) JCCSim(X86_CC_NGE, D) +#define JNLSm(D) JCCSim(X86_CC_NL, D) +#define JGESm(D) JCCSim(X86_CC_GE, D) +#define JLESm(D) JCCSim(X86_CC_LE, D) +#define JNGSm(D) JCCSim(X86_CC_NG, D) +#define JNLESm(D) JCCSim(X86_CC_NLE, D) +#define JGSm(D) JCCSim(X86_CC_G, D) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define JCCii(CC, D) _OO_L (0x0f80|(CC) ,(int)(D) ) +#define JCCim(CC, D) _OO_D32 (0x0f80|(CC) ,(int)(D) ) +#define JOm(D) JCCim(X86_CC_O, D) +#define JNOm(D) JCCim(X86_CC_NO, D) +#define JBm(D) JCCim(X86_CC_B, D) +#define JNAEm(D) JCCim(X86_CC_NAE, D) +#define JNBm(D) JCCim(X86_CC_NB, D) +#define JAEm(D) JCCim(X86_CC_AE, D) +#define JEm(D) JCCim(X86_CC_E, D) +#define JZm(D) JCCim(X86_CC_Z, D) +#define JNEm(D) JCCim(X86_CC_NE, D) +#define JNZm(D) JCCim(X86_CC_NZ, D) +#define JBEm(D) JCCim(X86_CC_BE, D) +#define JNAm(D) JCCim(X86_CC_NA, D) +#define JNBEm(D) JCCim(X86_CC_NBE, D) +#define JAm(D) JCCim(X86_CC_A, D) +#define JSm(D) JCCim(X86_CC_S, D) +#define JNSm(D) JCCim(X86_CC_NS, D) +#define JPm(D) JCCim(X86_CC_P, D) +#define JPEm(D) JCCim(X86_CC_PE, D) +#define JNPm(D) JCCim(X86_CC_NP, D) +#define JPOm(D) JCCim(X86_CC_PO, D) +#define JLm(D) JCCim(X86_CC_L, D) +#define JNGEm(D) JCCim(X86_CC_NGE, D) +#define JNLm(D) JCCim(X86_CC_NL, D) +#define JGEm(D) JCCim(X86_CC_GE, D) +#define JLEm(D) JCCim(X86_CC_LE, D) +#define JNGm(D) JCCim(X86_CC_NG, D) +#define JNLEm(D) JCCim(X86_CC_NLE, D) +#define JGm(D) JCCim(X86_CC_G, D) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define SETCCir(CC, RD) (_REXBrr(0, RD), _OO_Mrm (0x0f90|(CC) ,_b11,_b000,_r1(RD) )) +#define SETOr(RD) SETCCir(X86_CC_O, RD) +#define SETNOr(RD) SETCCir(X86_CC_NO, RD) +#define SETBr(RD) SETCCir(X86_CC_B, RD) +#define SETNAEr(RD) SETCCir(X86_CC_NAE, RD) +#define SETNBr(RD) SETCCir(X86_CC_NB, RD) +#define SETAEr(RD) SETCCir(X86_CC_AE, RD) +#define SETEr(RD) SETCCir(X86_CC_E, RD) +#define SETZr(RD) SETCCir(X86_CC_Z, RD) +#define SETNEr(RD) SETCCir(X86_CC_NE, RD) +#define SETNZr(RD) SETCCir(X86_CC_NZ, RD) +#define SETBEr(RD) SETCCir(X86_CC_BE, RD) +#define SETNAr(RD) SETCCir(X86_CC_NA, RD) +#define SETNBEr(RD) SETCCir(X86_CC_NBE, RD) +#define SETAr(RD) SETCCir(X86_CC_A, RD) +#define SETSr(RD) SETCCir(X86_CC_S, RD) +#define SETNSr(RD) SETCCir(X86_CC_NS, RD) +#define SETPr(RD) SETCCir(X86_CC_P, RD) +#define SETPEr(RD) SETCCir(X86_CC_PE, RD) +#define SETNPr(RD) SETCCir(X86_CC_NP, RD) +#define SETPOr(RD) SETCCir(X86_CC_PO, RD) +#define SETLr(RD) SETCCir(X86_CC_L, RD) +#define SETNGEr(RD) SETCCir(X86_CC_NGE, RD) +#define SETNLr(RD) SETCCir(X86_CC_NL, RD) +#define SETGEr(RD) SETCCir(X86_CC_GE, RD) +#define SETLEr(RD) SETCCir(X86_CC_LE, RD) +#define SETNGr(RD) SETCCir(X86_CC_NG, RD) +#define SETNLEr(RD) SETCCir(X86_CC_NLE, RD) +#define SETGr(RD) SETCCir(X86_CC_G, RD) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define SETCCim(CC,MD,MB,MI,MS) (_REXBrm(0, MB, MI), _OO_r_X (0x0f90|(CC) ,_b000 ,MD,MB,MI,MS )) +#define SETOm(D, B, I, S) SETCCim(X86_CC_O, D, B, I, S) +#define SETNOm(D, B, I, S) SETCCim(X86_CC_NO, D, B, I, S) +#define SETBm(D, B, I, S) SETCCim(X86_CC_B, D, B, I, S) +#define SETNAEm(D, B, I, S) SETCCim(X86_CC_NAE, D, B, I, S) +#define SETNBm(D, B, I, S) SETCCim(X86_CC_NB, D, B, I, S) +#define SETAEm(D, B, I, S) SETCCim(X86_CC_AE, D, B, I, S) +#define SETEm(D, B, I, S) SETCCim(X86_CC_E, D, B, I, S) +#define SETZm(D, B, I, S) SETCCim(X86_CC_Z, D, B, I, S) +#define SETNEm(D, B, I, S) SETCCim(X86_CC_NE, D, B, I, S) +#define SETNZm(D, B, I, S) SETCCim(X86_CC_NZ, D, B, I, S) +#define SETBEm(D, B, I, S) SETCCim(X86_CC_BE, D, B, I, S) +#define SETNAm(D, B, I, S) SETCCim(X86_CC_NA, D, B, I, S) +#define SETNBEm(D, B, I, S) SETCCim(X86_CC_NBE, D, B, I, S) +#define SETAm(D, B, I, S) SETCCim(X86_CC_A, D, B, I, S) +#define SETSm(D, B, I, S) SETCCim(X86_CC_S, D, B, I, S) +#define SETNSm(D, B, I, S) SETCCim(X86_CC_NS, D, B, I, S) +#define SETPm(D, B, I, S) SETCCim(X86_CC_P, D, B, I, S) +#define SETPEm(D, B, I, S) SETCCim(X86_CC_PE, D, B, I, S) +#define SETNPm(D, B, I, S) SETCCim(X86_CC_NP, D, B, I, S) +#define SETPOm(D, B, I, S) SETCCim(X86_CC_PO, D, B, I, S) +#define SETLm(D, B, I, S) SETCCim(X86_CC_L, D, B, I, S) +#define SETNGEm(D, B, I, S) SETCCim(X86_CC_NGE, D, B, I, S) +#define SETNLm(D, B, I, S) SETCCim(X86_CC_NL, D, B, I, S) +#define SETGEm(D, B, I, S) SETCCim(X86_CC_GE, D, B, I, S) +#define SETLEm(D, B, I, S) SETCCim(X86_CC_LE, D, B, I, S) +#define SETNGm(D, B, I, S) SETCCim(X86_CC_NG, D, B, I, S) +#define SETNLEm(D, B, I, S) SETCCim(X86_CC_NLE, D, B, I, S) +#define SETGm(D, B, I, S) SETCCim(X86_CC_G, D, B, I, S) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ +#define CMOVWrr(CC,RS,RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r2(RD),_r2(RS) )) +#define CMOVWmr(CC,MD,MB,MI,MS,RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r2(RD) ,MD,MB,MI,MS )) +#define CMOVLrr(CC,RS,RD) (_REXLrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r4(RD),_r4(RS) )) +#define CMOVLmr(CC,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r4(RD) ,MD,MB,MI,MS )) +#define CMOVQrr(CC,RS,RD) (_REXQrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r8(RD),_r8(RS) )) +#define CMOVQmr(CC,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r8(RD) ,MD,MB,MI,MS )) + + +/* --- Push/Pop instructions ----------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define POPWr(RD) _m32only((_d16(), _Or (0x58,_r2(RD) ))) +#define POPWm(MD, MB, MI, MS) _m32only((_d16(), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ))) + +#define POPLr(RD) _m32only( _Or (0x58,_r4(RD) )) +#define POPLm(MD, MB, MI, MS) _m32only( _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS )) + +#define POPQr(RD) _m64only((_REXQr(RD), _Or (0x58,_r8(RD) ))) +#define POPQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ))) + +#define PUSHWr(RS) _m32only((_d16(), _Or (0x50,_r2(RS) ))) +#define PUSHWm(MD, MB, MI, MS) _m32only((_d16(), _O_r_X (0xff, ,_b110 ,MD,MB,MI,MS ))) +#define PUSHWi(IM) _m32only((_d16(), _Os_sW (0x68 ,IM ))) + +#define PUSHLr(RS) _m32only( _Or (0x50,_r4(RS) )) +#define PUSHLm(MD, MB, MI, MS) _m32only( _O_r_X (0xff ,_b110 ,MD,MB,MI,MS )) +#define PUSHLi(IM) _m32only( _Os_sL (0x68 ,IM )) + +#define PUSHQr(RS) _m64only((_REXQr(RS), _Or (0x50,_r8(RS) ))) +#define PUSHQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0xff ,_b110 ,MD,MB,MI,MS ))) +#define PUSHQi(IM) _m64only( _Os_sL (0x68 ,IM )) + +#define POPA() (_d16(), _O (0x61 )) +#define POPAD() _O (0x61 ) + +#define PUSHA() (_d16(), _O (0x60 )) +#define PUSHAD() _O (0x60 ) + +#define POPF() _O (0x9d ) +#define PUSHF() _O (0x9c ) + + +/* --- Test instructions --------------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define TESTBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x84 ,_b11,_r1(RS),_r1(RD) )) +#define TESTBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x84 ,_r1(RS) ,MD,MB,MI,MS )) +#define TESTBir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AL) ? \ + (_REXBrr(0, RD), _O_B (0xa8 ,_u8(IM))) : \ + (_REXBrr(0, RD), _O_Mrm_B (0xf6 ,_b11,_b000 ,_r1(RD) ,_u8(IM))) ) +#define TESTBim(IM, MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X_B (0xf6 ,_b000 ,MD,MB,MI,MS ,_u8(IM))) + +#define TESTWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x85 ,_b11,_r2(RS),_r2(RD) )) +#define TESTWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x85 ,_r2(RS) ,MD,MB,MI,MS )) +#define TESTWir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_AX) ? \ + (_d16(), _REXLrr(0, RD), _O_W (0xa9 ,_u16(IM))) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm_W (0xf7 ,_b11,_b000 ,_r2(RD) ,_u16(IM))) ) +#define TESTWim(IM, MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X_W (0xf7 ,_b000 ,MD,MB,MI,MS ,_u16(IM))) + +#define TESTLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x85 ,_b11,_r4(RS),_r4(RD) )) +#define TESTLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x85 ,_r4(RS) ,MD,MB,MI,MS )) +#define TESTLir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_EAX) ? \ + (_REXLrr(0, RD), _O_L (0xa9 ,IM )) : \ + (_REXLrr(0, RD), _O_Mrm_L (0xf7 ,_b11,_b000 ,_r4(RD) ,IM )) ) +#define TESTLim(IM, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM )) + +#define TESTQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x85 ,_b11,_r8(RS),_r8(RD) )) +#define TESTQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x85 ,_r8(RS) ,MD,MB,MI,MS )) +#define TESTQir(IM, RD) (X86_OPTIMIZE_ALU && ((RD) == X86_RAX) ? \ + (_REXQrr(0, RD), _O_L (0xa9 ,IM )) : \ + (_REXQrr(0, RD), _O_Mrm_L (0xf7 ,_b11,_b000 ,_r8(RD) ,IM )) ) +#define TESTQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM )) + + +/* --- Exchange instructions ----------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define CMPXCHGBrr(RS, RD) (_REXBrr(RS, RD), _OO_Mrm (0x0fb0 ,_b11,_r1(RS),_r1(RD) )) +#define CMPXCHGBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _OO_r_X (0x0fb0 ,_r1(RS) ,MD,MB,MI,MS )) + +#define CMPXCHGWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r2(RS),_r2(RD) )) +#define CMPXCHGWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r2(RS) ,MD,MB,MI,MS )) + +#define CMPXCHGLrr(RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r4(RS),_r4(RD) )) +#define CMPXCHGLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r4(RS) ,MD,MB,MI,MS )) + +#define CMPXCHGQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r8(RS),_r8(RD) )) +#define CMPXCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r8(RS) ,MD,MB,MI,MS )) + +#define XADDBrr(RS, RD) (_REXBrr(RS, RD), _OO_Mrm (0x0fc0 ,_b11,_r1(RS),_r1(RD) )) +#define XADDBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _OO_r_X (0x0fc0 ,_r1(RS) ,MD,MB,MI,MS )) + +#define XADDWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r2(RS),_r2(RD) )) +#define XADDWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r2(RS) ,MD,MB,MI,MS )) + +#define XADDLrr(RS, RD) (_REXLrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r4(RS),_r4(RD) )) +#define XADDLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r4(RS) ,MD,MB,MI,MS )) + +#define XADDQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r8(RS),_r8(RD) )) +#define XADDQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r8(RS) ,MD,MB,MI,MS )) + +#define XCHGBrr(RS, RD) (_REXBrr(RS, RD), _O_Mrm (0x86 ,_b11,_r1(RS),_r1(RD) )) +#define XCHGBrm(RS, MD, MB, MI, MS) (_REXBrm(RS, MB, MI), _O_r_X (0x86 ,_r1(RS) ,MD,MB,MI,MS )) + +#define XCHGWrr(RS, RD) (_d16(), _REXLrr(RS, RD), _O_Mrm (0x87 ,_b11,_r2(RS),_r2(RD) )) +#define XCHGWrm(RS, MD, MB, MI, MS) (_d16(), _REXLrm(RS, MB, MI), _O_r_X (0x87 ,_r2(RS) ,MD,MB,MI,MS )) + +#define XCHGLrr(RS, RD) (_REXLrr(RS, RD), _O_Mrm (0x87 ,_b11,_r4(RS),_r4(RD) )) +#define XCHGLrm(RS, MD, MB, MI, MS) (_REXLrm(RS, MB, MI), _O_r_X (0x87 ,_r4(RS) ,MD,MB,MI,MS )) + +#define XCHGQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x87 ,_b11,_r8(RS),_r8(RD) )) +#define XCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x87 ,_r8(RS) ,MD,MB,MI,MS )) + + +/* --- Increment/Decrement instructions ------------------------------------ */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define DECBm(MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xfe ,_b001 ,MD,MB,MI,MS )) +#define DECBr(RD) (_REXBrr(0, RD), _O_Mrm (0xfe ,_b11,_b001 ,_r1(RD) )) + +#define DECWm(MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) +#define DECWr(RD) (! X86_TARGET_64BIT ? (_d16(), _Or (0x48,_r2(RD) )) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r2(RD) ))) + +#define DECLm(MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) +#define DECLr(RD) (! X86_TARGET_64BIT ? _Or (0x48,_r4(RD) ) : \ + (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r4(RD) ))) + +#define DECQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS )) +#define DECQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r8(RD) )) + +#define INCBm(MD, MB, MI, MS) (_REXBrm(0, MB, MI), _O_r_X (0xfe ,_b000 ,MD,MB,MI,MS )) +#define INCBr(RD) (_REXBrr(0, RD), _O_Mrm (0xfe ,_b11,_b000 ,_r1(RD) )) + +#define INCWm(MD, MB, MI, MS) (_d16(), _REXLrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) +#define INCWr(RD) (! X86_TARGET_64BIT ? (_d16(), _Or (0x40,_r2(RD) )) : \ + (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r2(RD) )) ) + +#define INCLm(MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) +#define INCLr(RD) (! X86_TARGET_64BIT ? _Or (0x40,_r4(RD) ) : \ + (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r4(RD) ))) + +#define INCQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )) +#define INCQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r8(RD) )) + + +/* --- Misc instructions --------------------------------------------------- */ + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define BSFWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r2(RD),_r2(RS) )) +#define BSFWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r2(RD) ,MD,MB,MI,MS )) +#define BSRWrr(RS, RD) (_d16(), _REXLrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r2(RD),_r2(RS) )) +#define BSRWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r2(RD) ,MD,MB,MI,MS )) + +#define BSFLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r4(RD),_r4(RS) )) +#define BSFLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r4(RD) ,MD,MB,MI,MS )) +#define BSRLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r4(RD),_r4(RS) )) +#define BSRLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r4(RD) ,MD,MB,MI,MS )) + +#define BSFQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r8(RD),_r8(RS) )) +#define BSFQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r8(RD) ,MD,MB,MI,MS )) +#define BSRQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r8(RD),_r8(RS) )) +#define BSRQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r8(RD) ,MD,MB,MI,MS )) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define MOVSBWrr(RS, RD) (_d16(), _REXBLrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r2(RD),_r1(RS) )) +#define MOVSBWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r2(RD) ,MD,MB,MI,MS )) +#define MOVZBWrr(RS, RD) (_d16(), _REXBLrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r2(RD),_r1(RS) )) +#define MOVZBWmr(MD, MB, MI, MS, RD) (_d16(), _REXLmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r2(RD) ,MD,MB,MI,MS )) + +#define MOVSBLrr(RS, RD) (_REXBLrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r4(RD),_r1(RS) )) +#define MOVSBLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r4(RD) ,MD,MB,MI,MS )) +#define MOVZBLrr(RS, RD) (_REXBLrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r4(RD),_r1(RS) )) +#define MOVZBLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r4(RD) ,MD,MB,MI,MS )) + +#define MOVSBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r8(RD),_r1(RS) )) +#define MOVSBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r8(RD) ,MD,MB,MI,MS )) +#define MOVZBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r8(RD),_r1(RS) )) +#define MOVZBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r8(RD) ,MD,MB,MI,MS )) + +#define MOVSWLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r4(RD),_r2(RS) )) +#define MOVSWLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r4(RD) ,MD,MB,MI,MS )) +#define MOVZWLrr(RS, RD) (_REXLrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r4(RD),_r2(RS) )) +#define MOVZWLmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r4(RD) ,MD,MB,MI,MS )) + +#define MOVSWQrr(RS, RD) _m64only((_REXQrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r8(RD),_r2(RS) ))) +#define MOVSWQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r8(RD) ,MD,MB,MI,MS ))) +#define MOVZWQrr(RS, RD) _m64only((_REXQrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r8(RD),_r2(RS) ))) +#define MOVZWQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r8(RD) ,MD,MB,MI,MS ))) + +#define MOVSLQrr(RS, RD) _m64only((_REXQrr(RD, RS), _O_Mrm (0x63 ,_b11,_r8(RD),_r4(RS) ))) +#define MOVSLQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _O_r_X (0x63 ,_r8(RD) ,MD,MB,MI,MS ))) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define LEALmr(MD, MB, MI, MS, RD) (_REXLmr(MB, MI, RD), _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS )) +#define LEAQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS )) + +#define BSWAPLr(R) (_REXLrr(0, R), _OOr (0x0fc8,_r4(R) )) +#define BSWAPQr(R) (_REXQrr(0, R), _OOr (0x0fc8,_r8(R) )) + +#define CLC() _O (0xf8 ) +#define STC() _O (0xf9 ) +#define CMC() _O (0xf5 ) + +#define CLD() _O (0xfc ) +#define STD() _O (0xfd ) + +#define CBTW() (_d16(), _O (0x98 )) +#define CWTL() _O (0x98 ) +#define CLTQ() _m64only(_REXQrr(0, 0), _O (0x98 )) + +#define CBW CBTW +#define CWDE CWTL +#define CDQE CLTQ + +#define CWTD() (_d16(), _O (0x99 )) +#define CLTD() _O (0x99 ) +#define CQTO() _m64only(_REXQrr(0, 0), _O (0x99 )) + +#define CWD CWTD +#define CDQ CLTD +#define CQO CQTO + +#define LAHF() _O (0x9f ) +#define SAHF() _O (0x9e ) + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define CPUID() _OO (0x0fa2 ) +#define RDTSC() _OO (0xff31 ) + +#define ENTERii(W, B) _O_W_B (0xc8 ,_su16(W),_su8(B)) + +#define LEAVE() _O (0xc9 ) +#define RET() _O (0xc3 ) +#define RETi(IM) _O_W (0xc2 ,_su16(IM)) + +#define NOP() _O (0x90 ) + + +/* --- Media 64-bit instructions ------------------------------------------- */ + +enum { + X86_MMX_PABSB = 0x1c, // 2P + X86_MMX_PABSW = 0x1d, // 2P + X86_MMX_PABSD = 0x1e, // 2P + X86_MMX_PACKSSWB = 0x63, + X86_MMX_PACKSSDW = 0x6b, + X86_MMX_PACKUSWB = 0x67, + X86_MMX_PADDB = 0xfc, + X86_MMX_PADDW = 0xfd, + X86_MMX_PADDD = 0xfe, + X86_MMX_PADDQ = 0xd4, + X86_MMX_PADDSB = 0xec, + X86_MMX_PADDSW = 0xed, + X86_MMX_PADDUSB = 0xdc, + X86_MMX_PADDUSW = 0xdd, + X86_MMX_PAND = 0xdb, + X86_MMX_PANDN = 0xdf, + X86_MMX_PAVGB = 0xe0, + X86_MMX_PAVGW = 0xe3, + X86_MMX_PCMPEQB = 0x74, + X86_MMX_PCMPEQW = 0x75, + X86_MMX_PCMPEQD = 0x76, + X86_MMX_PCMPGTB = 0x64, + X86_MMX_PCMPGTW = 0x65, + X86_MMX_PCMPGTD = 0x66, + X86_MMX_PEXTRW = 0xc5, // 64, /r ib + X86_MMX_PHADDW = 0x01, // 2P + X86_MMX_PHADDD = 0x02, // 2P + X86_MMX_PHADDSW = 0x03, // 2P + X86_MMX_PHSUBW = 0x05, // 2P + X86_MMX_PHSUBD = 0x06, // 2P + X86_MMX_PHSUBSW = 0x07, // 2P + X86_MMX_PINSRW = 0xc4, // 64, /r ib + X86_MMX_PMADDUBSW = 0x04, // 2P + X86_MMX_PMADDWD = 0xf5, + X86_MMX_PMAXSW = 0xee, + X86_MMX_PMAXUB = 0xde, + X86_MMX_PMINSW = 0xea, + X86_MMX_PMINUB = 0xda, + X86_MMX_PMOVMSKB = 0xd7, // 64 + X86_MMX_PMULHRSW = 0x0b, // 2P + X86_MMX_PMULHUW = 0xe4, + X86_MMX_PMULHW = 0xe5, + X86_MMX_PMULLW = 0xd5, + X86_MMX_PMULUDQ = 0xf4, + X86_MMX_POR = 0xeb, + X86_MMX_PSADBW = 0xf6, + X86_MMX_PSHUFB = 0x00, // 2P + X86_MMX_PSHUFW = 0x70, // /r ib + X86_MMX_PSIGNB = 0x08, // 2P + X86_MMX_PSIGNW = 0x09, // 2P + X86_MMX_PSIGND = 0x0a, // 2P + X86_MMX_PSLLW = 0xf1, + X86_MMX_PSLLWi = 0x71, // /6 ib + X86_MMX_PSLLD = 0xf2, + X86_MMX_PSLLDi = 0x72, // /6 ib + X86_MMX_PSLLQ = 0xf3, + X86_MMX_PSLLQi = 0x73, // /6 ib + X86_MMX_PSRAW = 0xe1, + X86_MMX_PSRAWi = 0x71, // /4 ib + X86_MMX_PSRAD = 0xe2, + X86_MMX_PSRADi = 0x72, // /4 ib + X86_MMX_PSRLW = 0xd1, + X86_MMX_PSRLWi = 0x71, // /2 ib + X86_MMX_PSRLD = 0xd2, + X86_MMX_PSRLDi = 0x72, // /2 ib + X86_MMX_PSRLQ = 0xd3, + X86_MMX_PSRLQi = 0x73, // /2 ib + X86_MMX_PSUBB = 0xf8, + X86_MMX_PSUBW = 0xf9, + X86_MMX_PSUBD = 0xfa, + X86_MMX_PSUBQ = 0xfb, + X86_MMX_PSUBSB = 0xe8, + X86_MMX_PSUBSW = 0xe9, + X86_MMX_PSUBUSB = 0xd8, + X86_MMX_PSUBUSW = 0xd9, + X86_MMX_PUNPCKHBW = 0x68, + X86_MMX_PUNPCKHWD = 0x69, + X86_MMX_PUNPCKHDQ = 0x6a, + X86_MMX_PUNPCKLBW = 0x60, + X86_MMX_PUNPCKLWD = 0x61, + X86_MMX_PUNPCKLDQ = 0x62, + X86_MMX_PXOR = 0xef, +}; + +#define __MMXLrr(OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __MMXLmr(OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __MMXLrm(OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) +#define __MMXLirr(OP,IM,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm_B (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) ,_u8(IM))) +#define __MMXLimr(OP,IM,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RS), _OO_r_X_B (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS ,_u8(IM))) +#define __MMXQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __MMXQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __MMXQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) +#define __MMXQirr(OP,IM,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm_B (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) ,_u8(IM))) +#define __MMXQimr(OP,IM,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RS), _OO_r_X_B (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS ,_u8(IM))) +#define __MMX1Lrr(PX,OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _B(0x0f),_OO_Mrm(((PX)<<8)|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __MMX1Lmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _B(0x0f),_OO_r_X(((PX)<<8)|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __MMX1Lrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _B(0x0f),_OO_r_X(((PX)<<8)|(OP) ,RSA(RS) ,MD,MB,MI,MS )) + +#define _MMXLrr(OP,RS,RD) __MMXLrr(OP,RS,_rM,RD,_rM) +#define _MMXLmr(OP,MD,MB,MI,MS,RD) __MMXLmr(OP,MD,MB,MI,MS,RD,_rM) +#define _MMXLrm(OP,RS,MD,MB,MI,MS) __MMXLrm(OP,RS,_rM,MD,MB,MI,MS) +#define _MMXQrr(OP,RS,RD) __MMXQrr(OP,RS,_rM,RD,_rM) +#define _MMXQmr(OP,MD,MB,MI,MS,RD) __MMXQmr(OP,MD,MB,MI,MS,RD,_rM) +#define _MMXQrm(OP,RS,MD,MB,MI,MS) __MMXQrm(OP,RS,_rM,MD,MB,MI,MS) +#define _2P_MMXLrr(OP,RS,RD) __MMX1Lrr(0x38, OP,RS,_rM,RD,_rM) +#define _2P_MMXLmr(OP,MD,MB,MI,MS,RD) __MMX1Lmr(0x38, OP,MD,MB,MI,MS,RD,_rM) +#define _2P_MMXLrm(OP,RS,MD,MB,MI,MS) __MMX1Lrm(0x38, OP,RS,_rM,MD,MB,MI,MS) + +#define MMX_MOVDMDrr(RS, RD) __MMXLrr(0x6e, RS,_r4, RD,_rM) +#define MMX_MOVQMDrr(RS, RD) __MMXQrr(0x6e, RS,_r8, RD,_rM) +#define MMX_MOVDMSrr(RS, RD) __MMXLrr(0x7e, RD,_r4, RS,_rM) +#define MMX_MOVQMSrr(RS, RD) __MMXQrr(0x7e, RD,_r8, RS,_rM) + +#define MMX_MOVDmr(MD, MB, MI, MS, RD) _MMXLmr(0x6e, MD, MB, MI, MS, RD) +#define MMX_MOVDrm(RS, MD, MB, MI, MS) _MMXLrm(0x7e, RS, MD, MB, MI, MS) +#define MMX_MOVQrr(RS, RD) _MMXLrr(0x6f, RS, RD) +#define MMX_MOVQmr(MD, MB, MI, MS, RD) _MMXLmr(0x6f, MD, MB, MI, MS, RD) +#define MMX_MOVQrm(RS, MD, MB, MI, MS) _MMXLrm(0x7f, RS, MD, MB, MI, MS) + +// Original MMX instructions +#define MMX_PACKSSWBrr(RS, RD) _MMXLrr(X86_MMX_PACKSSWB,RS,RD) +#define MMX_PACKSSWBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PACKSSWB, MD, MB, MI, MS, RD) +#define MMX_PACKSSDWrr(RS, RD) _MMXLrr(X86_MMX_PACKSSDW,RS,RD) +#define MMX_PACKSSDWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PACKSSDW, MD, MB, MI, MS, RD) +#define MMX_PACKUSWBrr(RS, RD) _MMXLrr(X86_MMX_PACKUSWB,RS,RD) +#define MMX_PACKUSWBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PACKUSWB, MD, MB, MI, MS, RD) +#define MMX_PADDBrr(RS, RD) _MMXLrr(X86_MMX_PADDB,RS,RD) +#define MMX_PADDBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDB, MD, MB, MI, MS, RD) +#define MMX_PADDWrr(RS, RD) _MMXLrr(X86_MMX_PADDW,RS,RD) +#define MMX_PADDWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDW, MD, MB, MI, MS, RD) +#define MMX_PADDDrr(RS, RD) _MMXLrr(X86_MMX_PADDD,RS,RD) +#define MMX_PADDDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDD, MD, MB, MI, MS, RD) +#define MMX_PADDQrr(RS, RD) _MMXLrr(X86_MMX_PADDQ,RS,RD) +#define MMX_PADDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDQ, MD, MB, MI, MS, RD) +#define MMX_PADDSBrr(RS, RD) _MMXLrr(X86_MMX_PADDSB,RS,RD) +#define MMX_PADDSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDSB, MD, MB, MI, MS, RD) +#define MMX_PADDSWrr(RS, RD) _MMXLrr(X86_MMX_PADDSW,RS,RD) +#define MMX_PADDSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDSW, MD, MB, MI, MS, RD) +#define MMX_PADDUSBrr(RS, RD) _MMXLrr(X86_MMX_PADDUSB,RS,RD) +#define MMX_PADDUSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDUSB, MD, MB, MI, MS, RD) +#define MMX_PADDUSWrr(RS, RD) _MMXLrr(X86_MMX_PADDUSW,RS,RD) +#define MMX_PADDUSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PADDUSW, MD, MB, MI, MS, RD) +#define MMX_PANDrr(RS, RD) _MMXLrr(X86_MMX_PAND,RS,RD) +#define MMX_PANDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PAND, MD, MB, MI, MS, RD) +#define MMX_PANDNrr(RS, RD) _MMXLrr(X86_MMX_PANDN,RS,RD) +#define MMX_PANDNmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PANDN, MD, MB, MI, MS, RD) +#define MMX_PAVGBrr(RS, RD) _MMXLrr(X86_MMX_PAVGB,RS,RD) +#define MMX_PAVGBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PAVGB, MD, MB, MI, MS, RD) +#define MMX_PAVGWrr(RS, RD) _MMXLrr(X86_MMX_PAVGW,RS,RD) +#define MMX_PAVGWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PAVGW, MD, MB, MI, MS, RD) +#define MMX_PCMPEQBrr(RS, RD) _MMXLrr(X86_MMX_PCMPEQB,RS,RD) +#define MMX_PCMPEQBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPEQB, MD, MB, MI, MS, RD) +#define MMX_PCMPEQWrr(RS, RD) _MMXLrr(X86_MMX_PCMPEQW,RS,RD) +#define MMX_PCMPEQWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPEQW, MD, MB, MI, MS, RD) +#define MMX_PCMPEQDrr(RS, RD) _MMXLrr(X86_MMX_PCMPEQD,RS,RD) +#define MMX_PCMPEQDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPEQD, MD, MB, MI, MS, RD) +#define MMX_PCMPGTBrr(RS, RD) _MMXLrr(X86_MMX_PCMPGTB,RS,RD) +#define MMX_PCMPGTBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPGTB, MD, MB, MI, MS, RD) +#define MMX_PCMPGTWrr(RS, RD) _MMXLrr(X86_MMX_PCMPGTW,RS,RD) +#define MMX_PCMPGTWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPGTW, MD, MB, MI, MS, RD) +#define MMX_PCMPGTDrr(RS, RD) _MMXLrr(X86_MMX_PCMPGTD,RS,RD) +#define MMX_PCMPGTDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PCMPGTD, MD, MB, MI, MS, RD) +#define MMX_PMADDWDrr(RS, RD) _MMXLrr(X86_MMX_PMADDWD,RS,RD) +#define MMX_PMADDWDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMADDWD, MD, MB, MI, MS, RD) +#define MMX_PMAXSWrr(RS, RD) _MMXLrr(X86_MMX_PMAXSW,RS,RD) +#define MMX_PMAXSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMAXSW, MD, MB, MI, MS, RD) +#define MMX_PMAXUBrr(RS, RD) _MMXLrr(X86_MMX_PMAXUB,RS,RD) +#define MMX_PMAXUBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMAXUB, MD, MB, MI, MS, RD) +#define MMX_PMINSWrr(RS, RD) _MMXLrr(X86_MMX_PMINSW,RS,RD) +#define MMX_PMINSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMINSW, MD, MB, MI, MS, RD) +#define MMX_PMINUBrr(RS, RD) _MMXLrr(X86_MMX_PMINUB,RS,RD) +#define MMX_PMINUBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMINUB, MD, MB, MI, MS, RD) +#define MMX_PMULHUWrr(RS, RD) _MMXLrr(X86_MMX_PMULHUW,RS,RD) +#define MMX_PMULHUWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULHUW, MD, MB, MI, MS, RD) +#define MMX_PMULHWrr(RS, RD) _MMXLrr(X86_MMX_PMULHW,RS,RD) +#define MMX_PMULHWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULHW, MD, MB, MI, MS, RD) +#define MMX_PMULLWrr(RS, RD) _MMXLrr(X86_MMX_PMULLW,RS,RD) +#define MMX_PMULLWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULLW, MD, MB, MI, MS, RD) +#define MMX_PMULUDQrr(RS, RD) _MMXLrr(X86_MMX_PMULUDQ,RS,RD) +#define MMX_PMULUDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PMULUDQ, MD, MB, MI, MS, RD) +#define MMX_PORrr(RS, RD) _MMXLrr(X86_MMX_POR,RS,RD) +#define MMX_PORmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_POR, MD, MB, MI, MS, RD) +#define MMX_PSADBWrr(RS, RD) _MMXLrr(X86_MMX_PSADBW,RS,RD) +#define MMX_PSADBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSADBW, MD, MB, MI, MS, RD) +#define MMX_PSLLWir(IM, RD) __MMXLirr(X86_MMX_PSLLWi, IM, RD,_rM, _b110,_rN) +#define MMX_PSLLWrr(RS, RD) _MMXLrr(X86_MMX_PSLLW,RS,RD) +#define MMX_PSLLWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSLLW, MD, MB, MI, MS, RD) +#define MMX_PSLLDir(IM, RD) __MMXLirr(X86_MMX_PSLLDi, IM, RD,_rM, _b110,_rN) +#define MMX_PSLLDrr(RS, RD) _MMXLrr(X86_MMX_PSLLD,RS,RD) +#define MMX_PSLLDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSLLD, MD, MB, MI, MS, RD) +#define MMX_PSLLQir(IM, RD) __MMXLirr(X86_MMX_PSLLQi, IM, RD,_rM, _b110,_rN) +#define MMX_PSLLQrr(RS, RD) _MMXLrr(X86_MMX_PSLLQ,RS,RD) +#define MMX_PSLLQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSLLQ, MD, MB, MI, MS, RD) +#define MMX_PSRAWir(IM, RD) __MMXLirr(X86_MMX_PSRAWi, IM, RD,_rM, _b100,_rN) +#define MMX_PSRAWrr(RS, RD) _MMXLrr(X86_MMX_PSRAW,RS,RD) +#define MMX_PSRAWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRAW, MD, MB, MI, MS, RD) +#define MMX_PSRADir(IM, RD) __MMXLirr(X86_MMX_PSRADi, IM, RD,_rM, _b100,_rN) +#define MMX_PSRADrr(RS, RD) _MMXLrr(X86_MMX_PSRAD,RS,RD) +#define MMX_PSRADmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRAD, MD, MB, MI, MS, RD) +#define MMX_PSRLWir(IM, RD) __MMXLirr(X86_MMX_PSRLWi, IM, RD,_rM, _b010,_rN) +#define MMX_PSRLWrr(RS, RD) _MMXLrr(X86_MMX_PSRLW,RS,RD) +#define MMX_PSRLWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRLW, MD, MB, MI, MS, RD) +#define MMX_PSRLDir(IM, RD) __MMXLirr(X86_MMX_PSRLDi, IM, RD,_rM, _b010,_rN) +#define MMX_PSRLDrr(RS, RD) _MMXLrr(X86_MMX_PSRLD,RS,RD) +#define MMX_PSRLDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRLD, MD, MB, MI, MS, RD) +#define MMX_PSRLQir(IM, RD) __MMXLirr(X86_MMX_PSRLQi, IM, RD,_rM, _b010,_rN) +#define MMX_PSRLQrr(RS, RD) _MMXLrr(X86_MMX_PSRLQ,RS,RD) +#define MMX_PSRLQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSRLQ, MD, MB, MI, MS, RD) +#define MMX_PSUBBrr(RS, RD) _MMXLrr(X86_MMX_PSUBB,RS,RD) +#define MMX_PSUBBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBB, MD, MB, MI, MS, RD) +#define MMX_PSUBWrr(RS, RD) _MMXLrr(X86_MMX_PSUBW,RS,RD) +#define MMX_PSUBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBW, MD, MB, MI, MS, RD) +#define MMX_PSUBDrr(RS, RD) _MMXLrr(X86_MMX_PSUBD,RS,RD) +#define MMX_PSUBDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBD, MD, MB, MI, MS, RD) +#define MMX_PSUBQrr(RS, RD) _MMXLrr(X86_MMX_PSUBQ,RS,RD) +#define MMX_PSUBQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBQ, MD, MB, MI, MS, RD) +#define MMX_PSUBSBrr(RS, RD) _MMXLrr(X86_MMX_PSUBSB,RS,RD) +#define MMX_PSUBSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBSB, MD, MB, MI, MS, RD) +#define MMX_PSUBSWrr(RS, RD) _MMXLrr(X86_MMX_PSUBSW,RS,RD) +#define MMX_PSUBSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBSW, MD, MB, MI, MS, RD) +#define MMX_PSUBUSBrr(RS, RD) _MMXLrr(X86_MMX_PSUBUSB,RS,RD) +#define MMX_PSUBUSBmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBUSB, MD, MB, MI, MS, RD) +#define MMX_PSUBUSWrr(RS, RD) _MMXLrr(X86_MMX_PSUBUSW,RS,RD) +#define MMX_PSUBUSWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PSUBUSW, MD, MB, MI, MS, RD) +#define MMX_PUNPCKHBWrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKHBW,RS,RD) +#define MMX_PUNPCKHBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKHBW, MD, MB, MI, MS, RD) +#define MMX_PUNPCKHWDrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKHWD,RS,RD) +#define MMX_PUNPCKHWDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKHWD, MD, MB, MI, MS, RD) +#define MMX_PUNPCKHDQrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKHDQ,RS,RD) +#define MMX_PUNPCKHDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKHDQ, MD, MB, MI, MS, RD) +#define MMX_PUNPCKLBWrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKLBW,RS,RD) +#define MMX_PUNPCKLBWmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKLBW, MD, MB, MI, MS, RD) +#define MMX_PUNPCKLWDrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKLWD,RS,RD) +#define MMX_PUNPCKLWDmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKLWD, MD, MB, MI, MS, RD) +#define MMX_PUNPCKLDQrr(RS, RD) _MMXLrr(X86_MMX_PUNPCKLDQ,RS,RD) +#define MMX_PUNPCKLDQmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PUNPCKLDQ, MD, MB, MI, MS, RD) +#define MMX_PXORrr(RS, RD) _MMXLrr(X86_MMX_PXOR,RS,RD) +#define MMX_PXORmr(MD,MB,MI,MS,RD) _MMXLmr(X86_MMX_PXOR, MD, MB, MI, MS, RD) + +#define MMX_PSHUFWirr(IM, RS, RD) __MMXLirr(X86_MMX_PSHUFW, IM, RS,_rM, RD,_rM) +#define MMX_PSHUFWimr(IM, MD, MB, MI, MS, RD) __MMXLimr(X86_MMX_PSHUFW, IM, MD, MB, MI, MS, RD,_rM) +#define MMX_PEXTRWLirr(IM, RS, RD) __MMXLirr(X86_MMX_PEXTRW, IM, RS,_rM, RD,_r4) +#define MMX_PEXTRWQirr(IM, RS, RD) __MMXQirr(X86_MMX_PEXTRW, IM, RS,_rM, RD,_r8) +#define MMX_PINSRWLirr(IM, RS, RD) __MMXLirr(X86_MMX_PINSRW, IM, RS,_r4, RD,_rM) +#define MMX_PINSRWLimr(IM, MD, MB, MI, MS, RD) __MMXLimr(X86_MMX_PINSRW, IM, MD, MB, MI, MS, RD,_r4) +#define MMX_PINSRWQirr(IM, RS, RD) __MMXQirr(X86_MMX_PINSRW, IM, RS,_r4, RD,_rM) +#define MMX_PINSRWQimr(IM, MD, MB, MI, MS, RD) __MMXQimr(X86_MMX_PINSRW, IM, MD, MB, MI, MS, RD,_r8) + +// Additionnal MMX instructions, brought by SSSE3 ISA +#define MMX_PABSBrr(RS, RD) _2P_MMXLrr(X86_MMX_PABSB,RS,RD) +#define MMX_PABSBmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PABSB, MD, MB, MI, MS, RD) +#define MMX_PABSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PABSW,RS,RD) +#define MMX_PABSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PABSW, MD, MB, MI, MS, RD) +#define MMX_PABSDrr(RS, RD) _2P_MMXLrr(X86_MMX_PABSD,RS,RD) +#define MMX_PABSDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PABSD, MD, MB, MI, MS, RD) +#define MMX_PHADDWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHADDW,RS,RD) +#define MMX_PHADDWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHADDW, MD, MB, MI, MS, RD) +#define MMX_PHADDDrr(RS, RD) _2P_MMXLrr(X86_MMX_PHADDD,RS,RD) +#define MMX_PHADDDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHADDD, MD, MB, MI, MS, RD) +#define MMX_PHADDSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHADDSW,RS,RD) +#define MMX_PHADDSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHADDSW, MD, MB, MI, MS, RD) +#define MMX_PHSUBWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHSUBW,RS,RD) +#define MMX_PHSUBWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHSUBW, MD, MB, MI, MS, RD) +#define MMX_PHSUBDrr(RS, RD) _2P_MMXLrr(X86_MMX_PHSUBD,RS,RD) +#define MMX_PHSUBDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHSUBD, MD, MB, MI, MS, RD) +#define MMX_PHSUBSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PHSUBSW,RS,RD) +#define MMX_PHSUBSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PHSUBSW, MD, MB, MI, MS, RD) +#define MMX_PMADDUBSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PMADDUBSW,RS,RD) +#define MMX_PMADDUBSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PMADDUBSW, MD, MB, MI, MS, RD) +#define MMX_PMULHRSWrr(RS, RD) _2P_MMXLrr(X86_MMX_PMULHRSW,RS,RD) +#define MMX_PMULHRSWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PMULHRSW, MD, MB, MI, MS, RD) +#define MMX_PSHUFBrr(RS, RD) _2P_MMXLrr(X86_MMX_PSHUFB,RS,RD) +#define MMX_PSHUFBmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSHUFB, MD, MB, MI, MS, RD) +#define MMX_PSIGNBrr(RS, RD) _2P_MMXLrr(X86_MMX_PSIGNB,RS,RD) +#define MMX_PSIGNBmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSIGNB, MD, MB, MI, MS, RD) +#define MMX_PSIGNWrr(RS, RD) _2P_MMXLrr(X86_MMX_PSIGNW,RS,RD) +#define MMX_PSIGNWmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSIGNW, MD, MB, MI, MS, RD) +#define MMX_PSIGNDrr(RS, RD) _2P_MMXLrr(X86_MMX_PSIGND,RS,RD) +#define MMX_PSIGNDmr(MD,MB,MI,MS,RD) _2P_MMXLmr(X86_MMX_PSIGND, MD, MB, MI, MS, RD) + +#define EMMS() _OO (0x0f77 ) + + +/* --- Media 128-bit instructions ------------------------------------------ */ + +enum { + X86_SSE_CC_EQ = 0, + X86_SSE_CC_LT = 1, + X86_SSE_CC_GT = 1, + X86_SSE_CC_LE = 2, + X86_SSE_CC_GE = 2, + X86_SSE_CC_U = 3, + X86_SSE_CC_NEQ = 4, + X86_SSE_CC_NLT = 5, + X86_SSE_CC_NGT = 5, + X86_SSE_CC_NLE = 6, + X86_SSE_CC_NGE = 6, + X86_SSE_CC_O = 7 +}; + +enum { + X86_SSE_UCOMI = 0x2e, + X86_SSE_COMI = 0x2f, + X86_SSE_CMP = 0xc2, + X86_SSE_SQRT = 0x51, + X86_SSE_RSQRT = 0x52, + X86_SSE_RCP = 0x53, + X86_SSE_AND = 0x54, + X86_SSE_ANDN = 0x55, + X86_SSE_OR = 0x56, + X86_SSE_XOR = 0x57, + X86_SSE_ADD = 0x58, + X86_SSE_MUL = 0x59, + X86_SSE_SUB = 0x5c, + X86_SSE_MIN = 0x5d, + X86_SSE_DIV = 0x5e, + X86_SSE_MAX = 0x5f, + X86_SSE_CVTDQ2PD = 0xe6, + X86_SSE_CVTDQ2PS = 0x5b, + X86_SSE_CVTPD2DQ = 0xe6, + X86_SSE_CVTPD2PI = 0x2d, + X86_SSE_CVTPD2PS = 0x5a, + X86_SSE_CVTPI2PD = 0x2a, + X86_SSE_CVTPI2PS = 0x2a, + X86_SSE_CVTPS2DQ = 0x5b, + X86_SSE_CVTPS2PD = 0x5a, + X86_SSE_CVTPS2PI = 0x2d, + X86_SSE_CVTSD2SI = 0x2d, + X86_SSE_CVTSD2SS = 0x5a, + X86_SSE_CVTSI2SD = 0x2a, + X86_SSE_CVTSI2SS = 0x2a, + X86_SSE_CVTSS2SD = 0x5a, + X86_SSE_CVTSS2SI = 0x2d, + X86_SSE_CVTTPD2PI = 0x2c, + X86_SSE_CVTTPD2DQ = 0xe6, + X86_SSE_CVTTPS2DQ = 0x5b, + X86_SSE_CVTTPS2PI = 0x2c, + X86_SSE_CVTTSD2SI = 0x2c, + X86_SSE_CVTTSS2SI = 0x2c, + X86_SSE_MOVMSK = 0x50, + X86_SSE_PACKSSDW = 0x6b, + X86_SSE_PACKSSWB = 0x63, + X86_SSE_PACKUSWB = 0x67, + X86_SSE_PADDB = 0xfc, + X86_SSE_PADDD = 0xfe, + X86_SSE_PADDQ = 0xd4, + X86_SSE_PADDSB = 0xec, + X86_SSE_PADDSW = 0xed, + X86_SSE_PADDUSB = 0xdc, + X86_SSE_PADDUSW = 0xdd, + X86_SSE_PADDW = 0xfd, + X86_SSE_PAND = 0xdb, + X86_SSE_PANDN = 0xdf, + X86_SSE_PAVGB = 0xe0, + X86_SSE_PAVGW = 0xe3, + X86_SSE_PCMPEQB = 0x74, + X86_SSE_PCMPEQD = 0x76, + X86_SSE_PCMPEQW = 0x75, + X86_SSE_PCMPGTB = 0x64, + X86_SSE_PCMPGTD = 0x66, + X86_SSE_PCMPGTW = 0x65, + X86_SSE_PMADDWD = 0xf5, + X86_SSE_PMAXSW = 0xee, + X86_SSE_PMAXUB = 0xde, + X86_SSE_PMINSW = 0xea, + X86_SSE_PMINUB = 0xda, + X86_SSE_PMOVMSKB = 0xd7, + X86_SSE_PMULHUW = 0xe4, + X86_SSE_PMULHW = 0xe5, + X86_SSE_PMULLW = 0xd5, + X86_SSE_PMULUDQ = 0xf4, + X86_SSE_POR = 0xeb, + X86_SSE_PSADBW = 0xf6, + X86_SSE_PSLLD = 0xf2, + X86_SSE_PSLLQ = 0xf3, + X86_SSE_PSLLW = 0xf1, + X86_SSE_PSRAD = 0xe2, + X86_SSE_PSRAW = 0xe1, + X86_SSE_PSRLD = 0xd2, + X86_SSE_PSRLQ = 0xd3, + X86_SSE_PSRLW = 0xd1, + X86_SSE_PSUBB = 0xf8, + X86_SSE_PSUBD = 0xfa, + X86_SSE_PSUBQ = 0xfb, + X86_SSE_PSUBSB = 0xe8, + X86_SSE_PSUBSW = 0xe9, + X86_SSE_PSUBUSB = 0xd8, + X86_SSE_PSUBUSW = 0xd9, + X86_SSE_PSUBW = 0xf9, + X86_SSE_PUNPCKHBW = 0x68, + X86_SSE_PUNPCKHDQ = 0x6a, + X86_SSE_PUNPCKHQDQ = 0x6d, + X86_SSE_PUNPCKHWD = 0x69, + X86_SSE_PUNPCKLBW = 0x60, + X86_SSE_PUNPCKLDQ = 0x62, + X86_SSE_PUNPCKLQDQ = 0x6c, + X86_SSE_PUNPCKLWD = 0x61, + X86_SSE_PXOR = 0xef, + X86_SSSE3_PSHUFB = 0x00, +}; + +/* _format Opcd ,Mod ,r ,m ,mem=dsp+sib ,imm... */ + +#define _SSSE3Lrr(OP1,OP2,RS,RSA,RD,RDA) (_B(0x66), _REXLrr(RD,RD), _B(0x0f), _OO_Mrm (((OP1)<<8)|(OP2) ,_b11,RDA(RD),RSA(RS) )) +#define _SSSE3Lmr(OP1,OP2,MD,MB,MI,MS,RD,RDA) (_B(0x66), _REXLmr(MB, MI, RD), _B(0x0f), _OO_r_X (((OP1)<<8)|(OP2) ,RDA(RD) ,MD,MB,MI,MS )) +#define _SSSE3Lirr(OP1,OP2,IM,RS,RD) (_B(0x66), _REXLrr(RD, RS), _B(0x0f), _OO_Mrm_B (((OP1)<<8)|(OP2) ,_b11,_rX(RD),_rX(RS) ,_u8(IM))) +#define _SSSE3Limr(OP1,OP2,IM,MD,MB,MI,MS,RD) (_B(0x66), _REXLmr(MB, MI, RD), _B(0x0f), _OO_r_X_B (((OP1)<<8)|(OP2) ,_rX(RD) ,MD,MB,MI,MS ,_u8(IM))) + +#define __SSELir(OP,MO,IM,RD) (_REXLrr(0, RD), _OO_Mrm_B (0x0f00|(OP) ,_b11,MO ,_rX(RD) ,_u8(IM))) +#define __SSELim(OP,MO,IM,MD,MB,MI,MS) (_REXLrm(0, MB, MI), _OO_r_X_B (0x0f00|(OP) ,MO ,MD,MB,MI,MS ,_u8(IM))) +#define __SSELrr(OP,RS,RSA,RD,RDA) (_REXLrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __SSELmr(OP,MD,MB,MI,MS,RD,RDA) (_REXLmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __SSELrm(OP,RS,RSA,MD,MB,MI,MS) (_REXLrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) +#define __SSELirr(OP,IM,RS,RD) (_REXLrr(RD, RS), _OO_Mrm_B (0x0f00|(OP) ,_b11,_rX(RD),_rX(RS) ,_u8(IM))) +#define __SSELimr(OP,IM,MD,MB,MI,MS,RD) (_REXLmr(MB, MI, RD), _OO_r_X_B (0x0f00|(OP) ,_rX(RD) ,MD,MB,MI,MS ,_u8(IM))) + +#define __SSEQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) )) +#define __SSEQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS )) +#define __SSEQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS )) + +#define _SSELrr(PX,OP,RS,RSA,RD,RDA) (_B(PX), __SSELrr(OP, RS, RSA, RD, RDA)) +#define _SSELmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_B(PX), __SSELmr(OP, MD, MB, MI, MS, RD, RDA)) +#define _SSELrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_B(PX), __SSELrm(OP, RS, RSA, MD, MB, MI, MS)) +#define _SSELir(PX,OP,MO,IM,RD) (_B(PX), __SSELir(OP, MO, IM, RD)) +#define _SSELim(PX,OP,MO,IM,MD,MB,MI,MS) (_B(PX), __SSELim(OP, MO, IM, MD, MB, MI, MS)) +#define _SSELirr(PX,OP,IM,RS,RD) (_B(PX), __SSELirr(OP, IM, RS, RD)) +#define _SSELimr(PX,OP,IM,MD,MB,MI,MS,RD) (_B(PX), __SSELimr(OP, IM, MD, MB, MI, MS, RD)) + +#define _SSEQrr(PX,OP,RS,RSA,RD,RDA) (_B(PX), __SSEQrr(OP, RS, RSA, RD, RDA)) +#define _SSEQmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_B(PX), __SSEQmr(OP, MD, MB, MI, MS, RD, RDA)) +#define _SSEQrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_B(PX), __SSEQrm(OP, RS, RSA, MD, MB, MI, MS)) + +#define _SSEPSrr(OP,RS,RD) __SSELrr( OP, RS,_rX, RD,_rX) +#define _SSEPSmr(OP,MD,MB,MI,MS,RD) __SSELmr( OP, MD, MB, MI, MS, RD,_rX) +#define _SSEPSrm(OP,RS,MD,MB,MI,MS) __SSELrm( OP, RS,_rX, MD, MB, MI, MS) +#define _SSEPSirr(OP,IM,RS,RD) __SSELirr( OP, IM, RS, RD) +#define _SSEPSimr(OP,IM,MD,MB,MI,MS,RD) __SSELimr( OP, IM, MD, MB, MI, MS, RD) + +#define _SSEPDrr(OP,RS,RD) _SSELrr(0x66, OP, RS,_rX, RD,_rX) +#define _SSEPDmr(OP,MD,MB,MI,MS,RD) _SSELmr(0x66, OP, MD, MB, MI, MS, RD,_rX) +#define _SSEPDrm(OP,RS,MD,MB,MI,MS) _SSELrm(0x66, OP, RS,_rX, MD, MB, MI, MS) +#define _SSEPDirr(OP,IM,RS,RD) _SSELirr(0x66, OP, IM, RS, RD) +#define _SSEPDimr(OP,IM,MD,MB,MI,MS,RD) _SSELimr(0x66, OP, IM, MD, MB, MI, MS, RD) + +#define _SSESSrr(OP,RS,RD) _SSELrr(0xf3, OP, RS,_rX, RD,_rX) +#define _SSESSmr(OP,MD,MB,MI,MS,RD) _SSELmr(0xf3, OP, MD, MB, MI, MS, RD,_rX) +#define _SSESSrm(OP,RS,MD,MB,MI,MS) _SSELrm(0xf3, OP, RS,_rX, MD, MB, MI, MS) +#define _SSESSirr(OP,IM,RS,RD) _SSELirr(0xf3, OP, IM, RS, RD) +#define _SSESSimr(OP,IM,MD,MB,MI,MS,RD) _SSELimr(0xf3, OP, IM, MD, MB, MI, MS, RD) + +#define _SSESDrr(OP,RS,RD) _SSELrr(0xf2, OP, RS,_rX, RD,_rX) +#define _SSESDmr(OP,MD,MB,MI,MS,RD) _SSELmr(0xf2, OP, MD, MB, MI, MS, RD,_rX) +#define _SSESDrm(OP,RS,MD,MB,MI,MS) _SSELrm(0xf2, OP, RS,_rX, MD, MB, MI, MS) +#define _SSESDirr(OP,IM,RS,RD) _SSELirr(0xf2, OP, IM, RS, RD) +#define _SSESDimr(OP,IM,MD,MB,MI,MS,RD) _SSELimr(0xf2, OP, IM, MD, MB, MI, MS, RD) + +#define ADDPSrr(RS, RD) _SSEPSrr(X86_SSE_ADD, RS, RD) +#define ADDPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_ADD, MD, MB, MI, MS, RD) +#define ADDPDrr(RS, RD) _SSEPDrr(X86_SSE_ADD, RS, RD) +#define ADDPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_ADD, MD, MB, MI, MS, RD) + +#define ADDSSrr(RS, RD) _SSESSrr(X86_SSE_ADD, RS, RD) +#define ADDSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_ADD, MD, MB, MI, MS, RD) +#define ADDSDrr(RS, RD) _SSESDrr(X86_SSE_ADD, RS, RD) +#define ADDSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_ADD, MD, MB, MI, MS, RD) + +#define ANDNPSrr(RS, RD) _SSEPSrr(X86_SSE_ANDN, RS, RD) +#define ANDNPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_ANDN, MD, MB, MI, MS, RD) +#define ANDNPDrr(RS, RD) _SSEPDrr(X86_SSE_ANDN, RS, RD) +#define ANDNPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_ANDN, MD, MB, MI, MS, RD) + +#define ANDPSrr(RS, RD) _SSEPSrr(X86_SSE_AND, RS, RD) +#define ANDPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_AND, MD, MB, MI, MS, RD) +#define ANDPDrr(RS, RD) _SSEPDrr(X86_SSE_AND, RS, RD) +#define ANDPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_AND, MD, MB, MI, MS, RD) + +#define CMPPSrr(IM, RS, RD) _SSEPSirr(X86_SSE_CMP, IM, RS, RD) +#define CMPPSmr(IM, MD, MB, MI, MS, RD) _SSEPSimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) +#define CMPPDrr(IM, RS, RD) _SSEPDirr(X86_SSE_CMP, IM, RS, RD) +#define CMPPDmr(IM, MD, MB, MI, MS, RD) _SSEPDimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) + +#define CMPSSrr(IM, RS, RD) _SSESSirr(X86_SSE_CMP, IM, RS, RD) +#define CMPSSmr(IM, MD, MB, MI, MS, RD) _SSESSimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) +#define CMPSDrr(IM, RS, RD) _SSESDirr(X86_SSE_CMP, IM, RS, RD) +#define CMPSDmr(IM, MD, MB, MI, MS, RD) _SSESDimr(X86_SSE_CMP, IM, MD, MB, MI, MS, RD) + +#define DIVPSrr(RS, RD) _SSEPSrr(X86_SSE_DIV, RS, RD) +#define DIVPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_DIV, MD, MB, MI, MS, RD) +#define DIVPDrr(RS, RD) _SSEPDrr(X86_SSE_DIV, RS, RD) +#define DIVPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_DIV, MD, MB, MI, MS, RD) + +#define DIVSSrr(RS, RD) _SSESSrr(X86_SSE_DIV, RS, RD) +#define DIVSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_DIV, MD, MB, MI, MS, RD) +#define DIVSDrr(RS, RD) _SSESDrr(X86_SSE_DIV, RS, RD) +#define DIVSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_DIV, MD, MB, MI, MS, RD) + +#define MAXPSrr(RS, RD) _SSEPSrr(X86_SSE_MAX, RS, RD) +#define MAXPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MAX, MD, MB, MI, MS, RD) +#define MAXPDrr(RS, RD) _SSEPDrr(X86_SSE_MAX, RS, RD) +#define MAXPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MAX, MD, MB, MI, MS, RD) + +#define MAXSSrr(RS, RD) _SSESSrr(X86_SSE_MAX, RS, RD) +#define MAXSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MAX, MD, MB, MI, MS, RD) +#define MAXSDrr(RS, RD) _SSESDrr(X86_SSE_MAX, RS, RD) +#define MAXSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MAX, MD, MB, MI, MS, RD) + +#define MINPSrr(RS, RD) _SSEPSrr(X86_SSE_MIN, RS, RD) +#define MINPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MIN, MD, MB, MI, MS, RD) +#define MINPDrr(RS, RD) _SSEPDrr(X86_SSE_MIN, RS, RD) +#define MINPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MIN, MD, MB, MI, MS, RD) + +#define MINSSrr(RS, RD) _SSESSrr(X86_SSE_MIN, RS, RD) +#define MINSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MIN, MD, MB, MI, MS, RD) +#define MINSDrr(RS, RD) _SSESDrr(X86_SSE_MIN, RS, RD) +#define MINSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MIN, MD, MB, MI, MS, RD) + +#define MULPSrr(RS, RD) _SSEPSrr(X86_SSE_MUL, RS, RD) +#define MULPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_MUL, MD, MB, MI, MS, RD) +#define MULPDrr(RS, RD) _SSEPDrr(X86_SSE_MUL, RS, RD) +#define MULPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_MUL, MD, MB, MI, MS, RD) + +#define MULSSrr(RS, RD) _SSESSrr(X86_SSE_MUL, RS, RD) +#define MULSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_MUL, MD, MB, MI, MS, RD) +#define MULSDrr(RS, RD) _SSESDrr(X86_SSE_MUL, RS, RD) +#define MULSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_MUL, MD, MB, MI, MS, RD) + +#define ORPSrr(RS, RD) _SSEPSrr(X86_SSE_OR, RS, RD) +#define ORPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_OR, MD, MB, MI, MS, RD) +#define ORPDrr(RS, RD) _SSEPDrr(X86_SSE_OR, RS, RD) +#define ORPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_OR, MD, MB, MI, MS, RD) + +#define RCPPSrr(RS, RD) _SSEPSrr(X86_SSE_RCP, RS, RD) +#define RCPPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_RCP, MD, MB, MI, MS, RD) +#define RCPSSrr(RS, RD) _SSESSrr(X86_SSE_RCP, RS, RD) +#define RCPSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_RCP, MD, MB, MI, MS, RD) + +#define RSQRTPSrr(RS, RD) _SSEPSrr(X86_SSE_RSQRT, RS, RD) +#define RSQRTPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_RSQRT, MD, MB, MI, MS, RD) +#define RSQRTSSrr(RS, RD) _SSESSrr(X86_SSE_RSQRT, RS, RD) +#define RSQRTSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_RSQRT, MD, MB, MI, MS, RD) + +#define SQRTPSrr(RS, RD) _SSEPSrr(X86_SSE_SQRT, RS, RD) +#define SQRTPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) +#define SQRTPDrr(RS, RD) _SSEPDrr(X86_SSE_SQRT, RS, RD) +#define SQRTPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) + +#define SQRTSSrr(RS, RD) _SSESSrr(X86_SSE_SQRT, RS, RD) +#define SQRTSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) +#define SQRTSDrr(RS, RD) _SSESDrr(X86_SSE_SQRT, RS, RD) +#define SQRTSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_SQRT, MD, MB, MI, MS, RD) + +#define SUBPSrr(RS, RD) _SSEPSrr(X86_SSE_SUB, RS, RD) +#define SUBPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_SUB, MD, MB, MI, MS, RD) +#define SUBPDrr(RS, RD) _SSEPDrr(X86_SSE_SUB, RS, RD) +#define SUBPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_SUB, MD, MB, MI, MS, RD) + +#define SUBSSrr(RS, RD) _SSESSrr(X86_SSE_SUB, RS, RD) +#define SUBSSmr(MD, MB, MI, MS, RD) _SSESSmr(X86_SSE_SUB, MD, MB, MI, MS, RD) +#define SUBSDrr(RS, RD) _SSESDrr(X86_SSE_SUB, RS, RD) +#define SUBSDmr(MD, MB, MI, MS, RD) _SSESDmr(X86_SSE_SUB, MD, MB, MI, MS, RD) + +#define XORPSrr(RS, RD) _SSEPSrr(X86_SSE_XOR, RS, RD) +#define XORPSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_XOR, MD, MB, MI, MS, RD) +#define XORPDrr(RS, RD) _SSEPDrr(X86_SSE_XOR, RS, RD) +#define XORPDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_XOR, MD, MB, MI, MS, RD) + +#define COMISSrr(RS, RD) _SSEPSrr(X86_SSE_COMI, RS, RD) +#define COMISSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_COMI, MD, MB, MI, MS, RD) +#define COMISDrr(RS, RD) _SSEPDrr(X86_SSE_COMI, RS, RD) +#define COMISDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_COMI, MD, MB, MI, MS, RD) + +#define UCOMISSrr(RS, RD) _SSEPSrr(X86_SSE_UCOMI, RS, RD) +#define UCOMISSmr(MD, MB, MI, MS, RD) _SSEPSmr(X86_SSE_UCOMI, MD, MB, MI, MS, RD) +#define UCOMISDrr(RS, RD) _SSEPDrr(X86_SSE_UCOMI, RS, RD) +#define UCOMISDmr(MD, MB, MI, MS, RD) _SSEPDmr(X86_SSE_UCOMI, MD, MB, MI, MS, RD) + +#define MOVAPSrr(RS, RD) _SSEPSrr(0x28, RS, RD) +#define MOVAPSmr(MD, MB, MI, MS, RD) _SSEPSmr(0x28, MD, MB, MI, MS, RD) +#define MOVAPSrm(RS, MD, MB, MI, MS) _SSEPSrm(0x29, RS, MD, MB, MI, MS) + +#define MOVAPDrr(RS, RD) _SSEPDrr(0x28, RS, RD) +#define MOVAPDmr(MD, MB, MI, MS, RD) _SSEPDmr(0x28, MD, MB, MI, MS, RD) +#define MOVAPDrm(RS, MD, MB, MI, MS) _SSEPDrm(0x29, RS, MD, MB, MI, MS) + +#define CVTDQ2PDrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTDQ2PD, RS,_rX, RD,_rX) +#define CVTDQ2PDmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTDQ2PD, MD, MB, MI, MS, RD,_rX) +#define CVTDQ2PSrr(RS, RD) __SSELrr( X86_SSE_CVTDQ2PS, RS,_rX, RD,_rX) +#define CVTDQ2PSmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTDQ2PS, MD, MB, MI, MS, RD,_rX) +#define CVTPD2DQrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTPD2DQ, RS,_rX, RD,_rX) +#define CVTPD2DQmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTPD2DQ, MD, MB, MI, MS, RD,_rX) +#define CVTPD2PIrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPD2PI, RS,_rX, RD,_rM) +#define CVTPD2PImr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPD2PI, MD, MB, MI, MS, RD,_rM) +#define CVTPD2PSrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPD2PS, RS,_rX, RD,_rX) +#define CVTPD2PSmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPD2PS, MD, MB, MI, MS, RD,_rX) +#define CVTPI2PDrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPI2PD, RS,_rM, RD,_rX) +#define CVTPI2PDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPI2PD, MD, MB, MI, MS, RD,_rX) +#define CVTPI2PSrr(RS, RD) __SSELrr( X86_SSE_CVTPI2PS, RS,_rM, RD,_rX) +#define CVTPI2PSmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTPI2PS, MD, MB, MI, MS, RD,_rX) +#define CVTPS2DQrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTPS2DQ, RS,_rX, RD,_rX) +#define CVTPS2DQmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTPS2DQ, MD, MB, MI, MS, RD,_rX) +#define CVTPS2PDrr(RS, RD) __SSELrr( X86_SSE_CVTPS2PD, RS,_rX, RD,_rX) +#define CVTPS2PDmr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTPS2PD, MD, MB, MI, MS, RD,_rX) +#define CVTPS2PIrr(RS, RD) __SSELrr( X86_SSE_CVTPS2PI, RS,_rX, RD,_rM) +#define CVTPS2PImr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTPS2PI, MD, MB, MI, MS, RD,_rM) +#define CVTSD2SILrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSD2SI, RS,_rX, RD,_r4) +#define CVTSD2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSD2SI, MD, MB, MI, MS, RD,_r4) +#define CVTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSD2SI, RS,_rX, RD,_r8) +#define CVTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSD2SI, MD, MB, MI, MS, RD,_r8) +#define CVTSD2SSrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSD2SS, RS,_rX, RD,_rX) +#define CVTSD2SSmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSD2SS, MD, MB, MI, MS, RD,_rX) +#define CVTSI2SDLrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTSI2SD, RS,_r4, RD,_rX) +#define CVTSI2SDLmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTSI2SD, MD, MB, MI, MS, RD,_rX) +#define CVTSI2SDQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSI2SD, RS,_r8, RD,_rX) +#define CVTSI2SDQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSI2SD, MD, MB, MI, MS, RD,_rX) +#define CVTSI2SSLrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSI2SS, RS,_r4, RD,_rX) +#define CVTSI2SSLmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSI2SS, MD, MB, MI, MS, RD,_rX) +#define CVTSI2SSQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSI2SS, RS,_r8, RD,_rX) +#define CVTSI2SSQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSI2SS, MD, MB, MI, MS, RD,_rX) +#define CVTSS2SDrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSS2SD, RS,_rX, RD,_rX) +#define CVTSS2SDmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSS2SD, MD, MB, MI, MS, RD,_rX) +#define CVTSS2SILrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTSS2SI, RS,_rX, RD,_r4) +#define CVTSS2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTSS2SI, MD, MB, MI, MS, RD,_r4) +#define CVTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSS2SI, RS,_rX, RD,_r8) +#define CVTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSS2SI, MD, MB, MI, MS, RD,_r8) +#define CVTTPD2PIrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTTPD2PI, RS,_rX, RD,_rM) +#define CVTTPD2PImr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTTPD2PI, MD, MB, MI, MS, RD,_rM) +#define CVTTPD2DQrr(RS, RD) _SSELrr(0x66, X86_SSE_CVTTPD2DQ, RS,_rX, RD,_rX) +#define CVTTPD2DQmr(MD, MB, MI, MS, RD) _SSELmr(0x66, X86_SSE_CVTTPD2DQ, MD, MB, MI, MS, RD,_rX) +#define CVTTPS2DQrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTTPS2DQ, RS,_rX, RD,_rX) +#define CVTTPS2DQmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTTPS2DQ, MD, MB, MI, MS, RD,_rX) +#define CVTTPS2PIrr(RS, RD) __SSELrr( X86_SSE_CVTTPS2PI, RS,_rX, RD,_rM) +#define CVTTPS2PImr(MD, MB, MI, MS, RD) __SSELmr( X86_SSE_CVTTPS2PI, MD, MB, MI, MS, RD,_rM) +#define CVTTSD2SILrr(RS, RD) _SSELrr(0xf2, X86_SSE_CVTTSD2SI, RS,_rX, RD,_r4) +#define CVTTSD2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf2, X86_SSE_CVTTSD2SI, MD, MB, MI, MS, RD,_r4) +#define CVTTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTTSD2SI, RS,_rX, RD,_r8) +#define CVTTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTTSD2SI, MD, MB, MI, MS, RD,_r8) +#define CVTTSS2SILrr(RS, RD) _SSELrr(0xf3, X86_SSE_CVTTSS2SI, RS,_rX, RD,_r4) +#define CVTTSS2SILmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, X86_SSE_CVTTSS2SI, MD, MB, MI, MS, RD,_r4) +#define CVTTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTTSS2SI, RS,_rX, RD,_r8) +#define CVTTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTTSS2SI, MD, MB, MI, MS, RD,_r8) + +#define MOVDXDrr(RS, RD) _SSELrr(0x66, 0x6e, RS,_r4, RD,_rX) +#define MOVDXDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX) +#define MOVQXDrr(RS, RD) _SSEQrr(0x66, 0x6e, RS,_r8, RD,_rX) +#define MOVQXDmr(MD, MB, MI, MS, RD) _SSEQmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX) + +#define MOVDXSrr(RS, RD) _SSELrr(0x66, 0x7e, RD,_r4, RS,_rX) +#define MOVDXSrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS) +#define MOVQXSrr(RS, RD) _SSEQrr(0x66, 0x7e, RD,_r8, RS,_rX) +#define MOVQXSrm(RS, MD, MB, MI, MS) _SSEQrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS) + +#define MOVDLMrr(RS, RD) __SSELrr( 0x6e, RS,_r4, RD,_rM) +#define MOVDLMmr(MD, MB, MI, MS, RD) __SSELmr( 0x6e, MD, MB, MI, MS, RD,_rM) +#define MOVDQMrr(RS, RD) __SSEQrr( 0x6e, RS,_r8, RD,_rM) +#define MOVDQMmr(MD, MB, MI, MS, RD) __SSEQmr( 0x6e, MD, MB, MI, MS, RD,_rM) + +#define MOVDMLrr(RS, RD) __SSELrr( 0x7e, RS,_rM, RD,_r4) +#define MOVDMLrm(RS, MD, MB, MI, MS) __SSELrm( 0x7e, RS,_rM, MD, MB, MI, MS) +#define MOVDMQrr(RS, RD) __SSEQrr( 0x7e, RS,_rM, RD,_r8) +#define MOVDMQrm(RS, MD, MB, MI, MS) __SSEQrm( 0x7e, RS,_rM, MD, MB, MI, MS) + +#define MOVDQ2Qrr(RS, RD) _SSELrr(0xf2, 0xd6, RS,_rX, RD,_rM) +#define MOVMSKPSrr(RS, RD) __SSELrr( 0x50, RS,_rX, RD,_r4) +#define MOVMSKPDrr(RS, RD) _SSELrr(0x66, 0x50, RS,_rX, RD,_r4) + +#define MOVHLPSrr(RS, RD) __SSELrr( 0x12, RS,_rX, RD,_rX) +#define MOVLHPSrr(RS, RD) __SSELrr( 0x16, RS,_rX, RD,_rX) + +#define MOVDQArr(RS, RD) _SSELrr(0x66, 0x6f, RS,_rX, RD,_rX) +#define MOVDQAmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x6f, MD, MB, MI, MS, RD,_rX) +#define MOVDQArm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x7f, RS,_rX, MD, MB, MI, MS) + +#define MOVDQUrr(RS, RD) _SSELrr(0xf3, 0x6f, RS,_rX, RD,_rX) +#define MOVDQUmr(MD, MB, MI, MS, RD) _SSELmr(0xf3, 0x6f, MD, MB, MI, MS, RD,_rX) +#define MOVDQUrm(RS, MD, MB, MI, MS) _SSELrm(0xf3, 0x7f, RS,_rX, MD, MB, MI, MS) + +#define MOVHPDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x16, MD, MB, MI, MS, RD,_rX) +#define MOVHPDrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x17, RS,_rX, MD, MB, MI, MS) +#define MOVHPSmr(MD, MB, MI, MS, RD) __SSELmr( 0x16, MD, MB, MI, MS, RD,_rX) +#define MOVHPSrm(RS, MD, MB, MI, MS) __SSELrm( 0x17, RS,_rX, MD, MB, MI, MS) + +#define MOVLPDmr(MD, MB, MI, MS, RD) _SSELmr(0x66, 0x12, MD, MB, MI, MS, RD,_rX) +#define MOVLPDrm(RS, MD, MB, MI, MS) _SSELrm(0x66, 0x13, RS,_rX, MD, MB, MI, MS) +#define MOVLPSmr(MD, MB, MI, MS, RD) __SSELmr( 0x12, MD, MB, MI, MS, RD,_rX) +#define MOVLPSrm(RS, MD, MB, MI, MS) __SSELrm( 0x13, RS,_rX, MD, MB, MI, MS) + + +/* --- Floating-Point instructions ----------------------------------------- */ + +enum { + X86_F2XM1 = 0xd9f0, + X86_FABS = 0xd9e1, + X86_FADD = 0xd8c0, // m32fp, m64fp, sti0, st0i, pst0i + X86_FIADD = 0xda00, // m32int, m16int + X86_FBLD = 0xdf04, // mem + X86_FBSTP = 0xdf06, // mem + X86_FCHS = 0xd9e0, + X86_FCMOVB = 0xdac0, // sti0 + X86_FCMOVE = 0xdac8, // sti0 + X86_FCMOVBE = 0xdad0, // sti0 + X86_FCMOVU = 0xdad8, // sti0 + X86_FCMOVNB = 0xdbc0, // sti0 + X86_FCMOVNE = 0xdbc8, // sti0 + X86_FCMOVNBE = 0xdbd0, // sti0 + X86_FCMOVNU = 0xdbd8, // sti0 + X86_FCOM = 0xd8d2, // m32fp, m64fp, sti + X86_FCOMP = 0xd8db, // m32fp, m64fp, sti + X86_FCOMPP = 0xded9, + X86_FCOMI = 0xdbf0, // sti0 + X86_FCOMIP = 0xdff0, // sti0 + X86_FUCOMI = 0xdbe8, // sti0 + X86_FUCOMIP = 0xdfe8, // sti0 + X86_FCOS = 0xd9ff, + X86_FDECSTP = 0xd9f6, + X86_FDIV = 0xd8f6, // m32fp, m64fp, sti0, st0i, pst0i + X86_FIDIV = 0xda06, // m32int, m16int + X86_FDIVR = 0xd8ff, // m32fp, m64fp, sti0, st0i, pst0i + X86_FIDIVR = 0xda07, // m32int, m16int + X86_FFREE = 0xddc0, // sti + X86_FICOM = 0xda02, // m32int, m16int + X86_FICOMP = 0xda03, // m32int, m16int + X86_FILD = 0xdb00, // m32int, m16int + X86_FILDQ = 0xdf05, // mem + X86_FINCSTP = 0xd9f7, + X86_FIST = 0xdb02, // m32int, m16int + X86_FISTP = 0xdb03, // m32int, m16int + X86_FISTPQ = 0xdf07, // mem + X86_FISTTP = 0xdb01, // m32int, m16int + X86_FISTTPQ = 0xdd01, // mem + X86_FLD = 0xd900, // m32fp, m64fp + X86_FLDT = 0xdb05, // mem + X86_FLD1 = 0xd9e8, + X86_FLDL2T = 0xd9e9, + X86_FLDL2E = 0xd9ea, + X86_FLDPI = 0xd9eb, + X86_FLDLG2 = 0xd9ec, + X86_FLDLN2 = 0xd9ed, + X86_FLDZ = 0xd9ee, + X86_FMUL = 0xd8c9, // m32fp, m64fp, sti0, st0i, pst0i + X86_FIMUL = 0xda01, // m32int, m16int + X86_FNOP = 0xd9d0, + X86_FPATAN = 0xd9f3, + X86_FPREM = 0xd9f8, + X86_FPREM1 = 0xd9f5, + X86_FPTAN = 0xd9f2, + X86_FRNDINT = 0xd9fc, + X86_FSCALE = 0xd9fd, + X86_FSIN = 0xd9fe, + X86_FSINCOS = 0xd9fb, + X86_FSQRT = 0xd9fa, + X86_FSTS = 0xd902, // mem + X86_FSTD = 0xdd02, // mem + X86_FST = 0xddd0, // sti + X86_FSTPS = 0xd903, // mem + X86_FSTPD = 0xdd03, // mem + X86_FSTPT = 0xdb07, // mem + X86_FSTP = 0xddd8, // sti + X86_FSUB = 0xd8e4, // m32fp, m64fp, sti0, st0i, pst0i + X86_FISUB = 0xda04, // m32int, m16int + X86_FSUBR = 0xd8ed, // m32fp, m64fp, sti0, st0i, pst0i + X86_FISUBR = 0xda05, // m32int, m16int + X86_FTST = 0xd9e4, + X86_FUCOM = 0xdde0, // sti + X86_FUCOMP = 0xdde8, // sti + X86_FUCOMPP = 0xdae9, + X86_FXAM = 0xd9e5, + X86_FXCH = 0xd9c8, // sti + X86_FXTRACT = 0xd9f4, + X86_FYL2X = 0xd9f1, + X86_FYL2XP1 = 0xd9f9, +}; + +#define _FPU(OP) _OO(OP) +#define _FPUm(OP, MD, MB, MI, MS) (_REXLrm(0, MB, MI), _O_r_X((OP)>>8, (OP)&7, MD, MB, MI, MS)) +#define _FPUSm(OP, MD, MB, MI, MS) _FPUm(OP, MD, MB, MI, MS) +#define _FPUDm(OP, MD, MB, MI, MS) _FPUm((OP)|0x400, MD, MB, MI, MS) +#define _FPULm(OP, MD, MB, MI, MS) _FPUm(OP, MD, MB, MI, MS) +#define _FPUWm(OP, MD, MB, MI, MS) _FPUm((OP)|0x400, MD, MB, MI, MS) +#define _FPUr(OP, RR) _OOr((OP)&0xfff8, _rF(RR)) +#define _FPU0r(OP, RD) _FPUr((OP)|0x400, RD) +#define _FPUr0(OP, RS) _FPUr((OP) , RS) +#define _FPUrr(OP, RS, RD) (_rST0P(RS) ? _FPU0r(OP, RD) : (_rST0P(RD) ? _FPUr0(OP, RS) : x86_emit_failure("FPU instruction without st0"))) +#define _FPUP0r(OP, RD) _FPU0r((OP)|0x200, RD) + +#define F2XM1() _FPU(X86_F2XM1) +#define FABS() _FPU(X86_FABS) +#define FADDSm(MD, MB, MI, MS) _FPUSm(X86_FADD, MD, MB, MI, MS) +#define FADDDm(MD, MB, MI, MS) _FPUDm(X86_FADD, MD, MB, MI, MS) +#define FADDP0r(RD) _FPUP0r(X86_FADD, RD) +#define FADDrr(RS, RD) _FPUrr(X86_FADD, RS, RD) +#define FADD0r(RD) _FPU0r(X86_FADD, RD) +#define FADDr0(RS) _FPUr0(X86_FADD, RS) +#define FIADDWm(MD, MB, MI, MS) _FPUWm(X86_FIADD, MD, MB, MI, MS) +#define FIADDLm(MD, MB, MI, MS) _FPULm(X86_FIADD, MD, MB, MI, MS) +#define FBLDm(MD, MB, MI, MS) _FPUm(X86_FBLD, MD, MB, MI, MS) +#define FBSTPm(MD, MB, MI, MS) _FPUm(X86_FBSTP, MD, MB, MI, MS) +#define FCHS() _FPU(X86_FCHS) +#define FCMOVBr0(RS) _FPUr0(X86_FCMOVB, RS) +#define FCMOVEr0(RS) _FPUr0(X86_FCMOVE, RS) +#define FCMOVBEr0(RS) _FPUr0(X86_FCMOVBE, RS) +#define FCMOVUr0(RS) _FPUr0(X86_FCMOVU, RS) +#define FCMOVNBr0(RS) _FPUr0(X86_FCMOVNB, RS) +#define FCMOVNEr0(RS) _FPUr0(X86_FCMOVNE, RS) +#define FCMOVNBEr0(RS) _FPUr0(X86_FCMOVNBE, RS) +#define FCMOVNUr0(RS) _FPUr0(X86_FCMOVNU, RS) +#define FCOMSm(MD, MB, MI, MS) _FPUSm(X86_FCOM, MD, MB, MI, MS) +#define FCOMDm(MD, MB, MI, MS) _FPUDm(X86_FCOM, MD, MB, MI, MS) +#define FCOMr(RD) _FPUr(X86_FCOM, RD) +#define FCOMPSm(MD, MB, MI, MS) _FPUSm(X86_FCOMP, MD, MB, MI, MS) +#define FCOMPDm(MD, MB, MI, MS) _FPUDm(X86_FCOMP, MD, MB, MI, MS) +#define FCOMPr(RD) _FPUr(X86_FCOMP, RD) +#define FCOMPP() _FPU(X86_FCOMPP) +#define FCOMIr0(RS) _FPUr0(X86_FCOMI, RS) +#define FCOMIPr0(RS) _FPUr0(X86_FCOMIP, RS) +#define FUCOMIr0(RS) _FPUr0(X86_FUCOMI, RS) +#define FUCOMIPr0(RS) _FPUr0(X86_FUCOMIP, RS) +#define FCOS() _FPU(X86_FCOS) +#define FDECSTP() _FPU(X86_FDECSTP) +#define FDIVSm(MD, MB, MI, MS) _FPUSm(X86_FDIV, MD, MB, MI, MS) +#define FDIVDm(MD, MB, MI, MS) _FPUDm(X86_FDIV, MD, MB, MI, MS) +#define FDIVP0r(RD) _FPUP0r(X86_FDIV, RD) +#define FDIVrr(RS, RD) _FPUrr(X86_FDIV, RS, RD) +#define FDIV0r(RD) _FPU0r(X86_FDIV, RD) +#define FDIVr0(RS) _FPUr0(X86_FDIV, RS) +#define FIDIVWm(MD, MB, MI, MS) _FPUWm(X86_FIDIV, MD, MB, MI, MS) +#define FIDIVLm(MD, MB, MI, MS) _FPULm(X86_FIDIV, MD, MB, MI, MS) +#define FDIVRSm(MD, MB, MI, MS) _FPUSm(X86_FDIVR, MD, MB, MI, MS) +#define FDIVRDm(MD, MB, MI, MS) _FPUDm(X86_FDIVR, MD, MB, MI, MS) +#define FDIVRP0r(RD) _FPUP0r(X86_FDIVR, RD) +#define FDIVRrr(RS, RD) _FPUrr(X86_FDIVR, RS, RD) +#define FDIVR0r(RD) _FPU0r(X86_FDIVR, RD) +#define FDIVRr0(RS) _FPUr0(X86_FDIVR, RS) +#define FIDIVRWm(MD, MB, MI, MS) _FPUWm(X86_FIDIVR, MD, MB, MI, MS) +#define FIDIVRLm(MD, MB, MI, MS) _FPULm(X86_FIDIVR, MD, MB, MI, MS) +#define FFREEr(RD) _FPUr(X86_FFREE, RD) +#define FICOMWm(MD, MB, MI, MS) _FPUWm(X86_FICOM, MD, MB, MI, MS) +#define FICOMLm(MD, MB, MI, MS) _FPULm(X86_FICOM, MD, MB, MI, MS) +#define FICOMPWm(MD, MB, MI, MS) _FPUWm(X86_FICOMP, MD, MB, MI, MS) +#define FICOMPLm(MD, MB, MI, MS) _FPULm(X86_FICOMP, MD, MB, MI, MS) +#define FILDWm(MD, MB, MI, MS) _FPUWm(X86_FILD, MD, MB, MI, MS) +#define FILDLm(MD, MB, MI, MS) _FPULm(X86_FILD, MD, MB, MI, MS) +#define FILDQm(MD, MB, MI, MS) _FPUm(X86_FILDQ, MD, MB, MI, MS) +#define FINCSTP() _FPU(X86_FINCSTP) +#define FISTWm(MD, MB, MI, MS) _FPUWm(X86_FIST, MD, MB, MI, MS) +#define FISTLm(MD, MB, MI, MS) _FPULm(X86_FIST, MD, MB, MI, MS) +#define FISTPWm(MD, MB, MI, MS) _FPUWm(X86_FISTP, MD, MB, MI, MS) +#define FISTPLm(MD, MB, MI, MS) _FPULm(X86_FISTP, MD, MB, MI, MS) +#define FISTPQm(MD, MB, MI, MS) _FPUm(X86_FISTPQ, MD, MB, MI, MS) +#define FISTTPWm(MD, MB, MI, MS) _FPUWm(X86_FISTTP, MD, MB, MI, MS) +#define FISTTPLm(MD, MB, MI, MS) _FPULm(X86_FISTTP, MD, MB, MI, MS) +#define FISTTPQm(MD, MB, MI, MS) _FPUm(X86_FISTTPQ, MD, MB, MI, MS) +#define FLDSm(MD, MB, MI, MS) _FPUSm(X86_FLD, MD, MB, MI, MS) +#define FLDDm(MD, MB, MI, MS) _FPUDm(X86_FLD, MD, MB, MI, MS) +#define FLDTm(MD, MB, MI, MS) _FPUm(X86_FLDT, MD, MB, MI, MS) +#define FLD1() _FPU(X86_FLD1) +#define FLDL2T() _FPU(X86_FLDL2T) +#define FLDL2E() _FPU(X86_FLDL2E) +#define FLDPI() _FPU(X86_FLDPI) +#define FLDLG2() _FPU(X86_FLDLG2) +#define FLDLN2() _FPU(X86_FLDLN2) +#define FLDZ() _FPU(X86_FLDZ) +#define FMULSm(MD, MB, MI, MS) _FPUSm(X86_FMUL, MD, MB, MI, MS) +#define FMULDm(MD, MB, MI, MS) _FPUDm(X86_FMUL, MD, MB, MI, MS) +#define FMULP0r(RD) _FPUP0r(X86_FMUL, RD) +#define FMULrr(RS, RD) _FPUrr(X86_FMUL, RS, RD) +#define FMUL0r(RD) _FPU0r(X86_FMUL, RD) +#define FMULr0(RS) _FPUr0(X86_FMUL, RS) +#define FIMULWm(MD, MB, MI, MS) _FPUWm(X86_FIMUL, MD, MB, MI, MS) +#define FIMULLm(MD, MB, MI, MS) _FPULm(X86_FIMUL, MD, MB, MI, MS) +#define FNOP() _FPU(X86_FNOP) +#define FPATAN() _FPU(X86_FPATAN) +#define FPREM() _FPU(X86_FPREM) +#define FPREM1() _FPU(X86_FPREM1) +#define FPTAN() _FPU(X86_FPTAN) +#define FRNDINT() _FPU(X86_FRNDINT) +#define FSCALE() _FPU(X86_FSCALE) +#define FSIN() _FPU(X86_FSIN) +#define FSINCOS() _FPU(X86_FSINCOS) +#define FSQRT() _FPU(X86_FSQRT) +#define FSTSm(MD, MB, MI, MS) _FPUm(X86_FSTS, MD, MB, MI, MS) +#define FSTDm(MD, MB, MI, MS) _FPUm(X86_FSTD, MD, MB, MI, MS) +#define FSTr(RD) _FPUr(X86_FST, RD) +#define FSTPSm(MD, MB, MI, MS) _FPUm(X86_FSTPS, MD, MB, MI, MS) +#define FSTPDm(MD, MB, MI, MS) _FPUm(X86_FSTPD, MD, MB, MI, MS) +#define FSTPTm(MD, MB, MI, MS) _FPUm(X86_FSTPT, MD, MB, MI, MS) +#define FSTPr(RD) _FPUr(X86_FSTP, RD) +#define FSUBSm(MD, MB, MI, MS) _FPUSm(X86_FSUB, MD, MB, MI, MS) +#define FSUBDm(MD, MB, MI, MS) _FPUDm(X86_FSUB, MD, MB, MI, MS) +#define FSUBP0r(RD) _FPUP0r(X86_FSUB, RD) +#define FSUBrr(RS, RD) _FPUrr(X86_FSUB, RS, RD) +#define FSUB0r(RD) _FPU0r(X86_FSUB, RD) +#define FSUBr0(RS) _FPUr0(X86_FSUB, RS) +#define FISUBWm(MD, MB, MI, MS) _FPUWm(X86_FISUB, MD, MB, MI, MS) +#define FISUBLm(MD, MB, MI, MS) _FPULm(X86_FISUB, MD, MB, MI, MS) +#define FSUBRSm(MD, MB, MI, MS) _FPUSm(X86_FSUBR, MD, MB, MI, MS) +#define FSUBRDm(MD, MB, MI, MS) _FPUDm(X86_FSUBR, MD, MB, MI, MS) +#define FSUBRP0r(RD) _FPUP0r(X86_FSUBR, RD) +#define FSUBRrr(RS, RD) _FPUrr(X86_FSUBR, RS, RD) +#define FSUBR0r(RD) _FPU0r(X86_FSUBR, RD) +#define FSUBRr0(RS) _FPUr0(X86_FSUBR, RS) +#define FISUBRWm(MD, MB, MI, MS) _FPUWm(X86_FISUBR, MD, MB, MI, MS) +#define FISUBRLm(MD, MB, MI, MS) _FPULm(X86_FISUBR, MD, MB, MI, MS) +#define FTST() _FPU(X86_FTST) +#define FUCOMr(RD) _FPUr(X86_FUCOM, RD) +#define FUCOMPr(RD) _FPUr(X86_FUCOMP, RD) +#define FUCOMPP() _FPU(X86_FUCOMPP) +#define FXAM() _FPU(X86_FXAM) +#define FXCHr(RD) _FPUr(X86_FXCH, RD) +#define FXTRACT() _FPU(X86_FXTRACT) +#define FYL2X() _FPU(X86_FYL2X) +#define FYL2XP1() _FPU(X86_FYL2XP1) + +#endif /* X86_RTASM_H */ diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp index 4654a86af..39a31ecb1 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.cpp @@ -64,6 +64,12 @@ int register_info_compare(const void *e1, const void *e2) static int ppc_refcount = 0; +#ifdef DO_CONVENTION_CALL_STATICS +template<> bool nv_mem_fun1_t::do_convention_call_init_done = false; +template<> int nv_mem_fun1_t::do_convention_call_code_len = 0; +template<> int nv_mem_fun1_t::do_convention_call_pf_offset = 0; +#endif + void powerpc_cpu::set_register(int id, any_register const & value) { if (id >= powerpc_registers::GPR(0) && id <= powerpc_registers::GPR(31)) { @@ -366,6 +372,7 @@ powerpc_cpu::powerpc_cpu(task_struct *parent_task) #if PPC_ENABLE_JIT use_jit = false; #endif + spcflags().init(); ++ppc_refcount; initialize(); } @@ -542,7 +549,12 @@ bool powerpc_cpu::check_spcflags() } #if DYNGEN_DIRECT_BLOCK_CHAINING -void *powerpc_cpu::compile_chain_block(block_info *sbi) +void * powerpc_cpu::call_compile_chain_block(powerpc_cpu * the_cpu, block_info *sbi) +{ + return the_cpu->compile_chain_block(sbi); +} + +void * PF_CONVENTION powerpc_cpu::compile_chain_block(block_info *sbi) { // Block index is stuffed into the source basic block pointer, // which is aligned at least on 4-byte boundaries @@ -719,7 +731,11 @@ void powerpc_cpu::execute(uint32 entry) if (is_logging()) record_step(opcode); #endif +#ifdef __MINGW32__ + assert(ii->execute.default_call_conv_ptr() != 0); +#else assert(ii->execute.ptr() != 0); +#endif ii->execute(this, opcode); #if PPC_EXECUTE_DUMP_STATE if (dump_state) diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp index c418386ed..f1739a5f3 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp @@ -371,8 +371,10 @@ class powerpc_cpu friend class powerpc_jit; powerpc_jit codegen; block_info *compile_block(uint32 entry); + static void call_do_record_step(powerpc_cpu * cpu, uint32 pc, uint32 opcode); #if DYNGEN_DIRECT_BLOCK_CHAINING void *compile_chain_block(block_info *sbi); + static void * call_compile_chain_block(powerpc_cpu * the_cpu, block_info *sbi); #endif #endif @@ -389,6 +391,7 @@ class powerpc_cpu // Instruction handlers void execute_nop(uint32 opcode); void execute_illegal(uint32 opcode); + static void call_execute_illegal(powerpc_cpu * cpu, uint32 opcode); template< class RA, class RB, class RC, class CA, class OE, class Rc > void execute_addition(uint32 opcode); template< class OP, class RD, class RA, class RB, class RC, class OE, class Rc > @@ -453,6 +456,7 @@ class powerpc_cpu void execute_icbi(uint32 opcode); void execute_isync(uint32 opcode); void execute_invalidate_cache_range(); + static void call_execute_invalidate_cache_range(powerpc_cpu * cpu); template< class RA, class RB > void execute_dcbz(uint32 opcode); template< bool SL > diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp index 972f26ec6..6c5c7ad92 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-decode.cpp @@ -470,11 +470,21 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = { PPC_I(FNMSUBS), A_form, 59, 30, CFLOW_NORMAL }, + { "fres", + EXECUTE_FP_ARITH(double, fres, RD, RB, NONE, NONE, RC_BIT_G, true), + PPC_I(FRES), + A_form, 59, 24, CFLOW_NORMAL + }, { "frsp", EXECUTE_1(fp_round, RC_BIT_G), PPC_I(FRSP), X_form, 63, 12, CFLOW_NORMAL }, + { "frsqrte", + EXECUTE_FP_ARITH(double, frsqrte, RD, RB, NONE, NONE, RC_BIT_G, true), + PPC_I(FRSQRTE), + A_form, 63, 26, CFLOW_NORMAL + }, { "fsel", EXECUTE_FP_ARITH(double, fsel, RD, RA, RC, RB, RC_BIT_G, false), PPC_I(FSEL), @@ -1551,7 +1561,7 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = { VX_form, 4, 132, CFLOW_NORMAL }, { "vrsqrtefp", - EXECUTE_VECTOR_ARITH(frsqrt, V4SF, NONE, V4SF, NONE), + EXECUTE_VECTOR_ARITH(frsqrte, V4SF, NONE, V4SF, NONE), PPC_I(VRSQRTEFP), VX_form, 4, 330, CFLOW_NORMAL }, diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp index 8d8451cb1..84b70891b 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-dyngen.cpp @@ -19,6 +19,9 @@ */ #include "sysdeps.h" + +#if ENABLE_DYNGEN + #include "utils/utils-cpuinfo.hpp" #include "cpu/ppc/ppc-dyngen.hpp" #include "cpu/ppc/ppc-bitfields.hpp" @@ -311,3 +314,5 @@ void powerpc_dyngen::gen_store_vect_VS_T0(int vS) gen_load_ad_VD_VR(vS); gen_op_store_vect_VD_T0(); } + +#endif //ENABLE_DYNGEN diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp index 7154a5af2..8e2ccac0f 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp @@ -90,6 +90,7 @@ static inline int ppc_to_native_rounding_mode(int round) case 2: return FE_UPWARD; case 3: return FE_DOWNWARD; } + return FE_TONEAREST; } /** @@ -894,11 +895,19 @@ void powerpc_cpu::execute_fp_int_convert(uint32 opcode) * Rc Predicate to record CR1 **/ +#ifndef FPCLASSIFY_RETURN_T +#ifdef __MINGW32__ +#define FPCLASSIFY_RETURN_T int +#else +#define FPCLASSIFY_RETURN_T uint8 +#endif +#endif + template< class FP > void powerpc_cpu::fp_classify(FP x) { uint32 c = fpscr() & ~FPSCR_FPRF_field::mask(); - uint8 fc = fpclassify(x); + FPCLASSIFY_RETURN_T fc = fpclassify(x); switch (fc) { case FP_NAN: c |= FPSCR_FPRF_FU_field::mask() | FPSCR_FPRF_C_field::mask(); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-instructions.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-instructions.hpp index c42b61d18..6e5b98910 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-instructions.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-instructions.hpp @@ -99,7 +99,9 @@ enum powerpc_instruction { PPC_I(FNMADDS), PPC_I(FNMSUB), PPC_I(FNMSUBS), + PPC_I(FRES), PPC_I(FRSP), + PPC_I(FRSQRTE), PPC_I(FSEL), PPC_I(FSUB), PPC_I(FSUBS), diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.cpp index 4b294401e..27d3e2c92 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.cpp @@ -19,6 +19,9 @@ */ #include "sysdeps.h" + +#if ENABLE_DYNGEN + #include "cpu/jit/dyngen-exec.h" #include "cpu/ppc/ppc-jit.hpp" #include "cpu/ppc/ppc-cpu.hpp" @@ -36,6 +39,11 @@ powerpc_jit::powerpc_jit(dyngen_cpu_base cpu) { } +// An operand that refers to an address relative to the emulated machine +static x86_memory_operand vm_memory_operand(int32 d, int b, int i = X86_NOREG, int s = 1) { + return x86_memory_operand(d + VMBaseDiff, b, i, s); +} + bool powerpc_jit::initialize(void) { if (!powerpc_dyngen::initialize()) @@ -239,21 +247,25 @@ bool powerpc_jit::initialize(void) // Dispatch mid-level code generators bool powerpc_jit::gen_vector_1(int mnemo, int vD) { + if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false; return (this->*((bool (powerpc_jit::*)(int, int))jit_info[mnemo]->handler))(mnemo, vD); } bool powerpc_jit::gen_vector_2(int mnemo, int vD, int vA, int vB) { + if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false; return (this->*((bool (powerpc_jit::*)(int, int, int, int))jit_info[mnemo]->handler))(mnemo, vD, vA, vB); } bool powerpc_jit::gen_vector_3(int mnemo, int vD, int vA, int vB, int vC) { + if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false; return (this->*((bool (powerpc_jit::*)(int, int, int, int, int))jit_info[mnemo]->handler))(mnemo, vD, vA, vB, vC); } bool powerpc_jit::gen_vector_compare(int mnemo, int vD, int vA, int vB, bool Rc) { + if (jit_info[mnemo]->handler == (gen_handler_t)&powerpc_jit::gen_not_available) return false; return (this->*((bool (powerpc_jit::*)(int, int, int, int, bool))jit_info[mnemo]->handler))(mnemo, vD, vA, vB, Rc); } @@ -395,8 +407,8 @@ bool powerpc_jit::gen_x86_lvx(int mnemo, int vD, int rA, int rB) gen_add_32(x86_memory_operand(xPPC_GPR(rA), REG_CPU_ID), REG_T0_ID); gen_and_32(x86_immediate_operand(-16), REG_T0_ID); #if SIZEOF_VOID_P == 8 - gen_mov_64(x86_memory_operand(0, REG_T0_ID), REG_T1_ID); - gen_mov_64(x86_memory_operand(8, REG_T0_ID), REG_T2_ID); + gen_mov_64(vm_memory_operand(0, REG_T0_ID), REG_T1_ID); + gen_mov_64(vm_memory_operand(8, REG_T0_ID), REG_T2_ID); gen_bswap_64(REG_T1_ID); gen_bswap_64(REG_T2_ID); gen_rol_64(x86_immediate_operand(32), REG_T1_ID); @@ -404,14 +416,14 @@ bool powerpc_jit::gen_x86_lvx(int mnemo, int vD, int rA, int rB) gen_mov_64(REG_T1_ID, x86_memory_operand(xPPC_VR(vD) + 0, REG_CPU_ID)); gen_mov_64(REG_T2_ID, x86_memory_operand(xPPC_VR(vD) + 8, REG_CPU_ID)); #else - gen_mov_32(x86_memory_operand(0*4, REG_T0_ID), REG_T1_ID); - gen_mov_32(x86_memory_operand(1*4, REG_T0_ID), REG_T2_ID); + gen_mov_32(vm_memory_operand(0*4, REG_T0_ID), REG_T1_ID); + gen_mov_32(vm_memory_operand(1*4, REG_T0_ID), REG_T2_ID); gen_bswap_32(REG_T1_ID); gen_bswap_32(REG_T2_ID); gen_mov_32(REG_T1_ID, x86_memory_operand(xPPC_VR(vD) + 0*4, REG_CPU_ID)); gen_mov_32(REG_T2_ID, x86_memory_operand(xPPC_VR(vD) + 1*4, REG_CPU_ID)); - gen_mov_32(x86_memory_operand(2*4, REG_T0_ID), REG_T1_ID); - gen_mov_32(x86_memory_operand(3*4, REG_T0_ID), REG_T2_ID); + gen_mov_32(vm_memory_operand(2*4, REG_T0_ID), REG_T1_ID); + gen_mov_32(vm_memory_operand(3*4, REG_T0_ID), REG_T2_ID); gen_bswap_32(REG_T1_ID); gen_bswap_32(REG_T2_ID); gen_mov_32(REG_T1_ID, x86_memory_operand(xPPC_VR(vD) + 2*4, REG_CPU_ID)); @@ -435,8 +447,8 @@ bool powerpc_jit::gen_x86_stvx(int mnemo, int vS, int rA, int rB) gen_and_32(x86_immediate_operand(-16), REG_T0_ID); gen_rol_64(x86_immediate_operand(32), REG_T1_ID); gen_rol_64(x86_immediate_operand(32), REG_T2_ID); - gen_mov_64(REG_T1_ID, x86_memory_operand(0, REG_T0_ID)); - gen_mov_64(REG_T2_ID, x86_memory_operand(8, REG_T0_ID)); + gen_mov_64(REG_T1_ID, vm_memory_operand(0, REG_T0_ID)); + gen_mov_64(REG_T2_ID, vm_memory_operand(8, REG_T0_ID)); #else gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 0*4, REG_CPU_ID), REG_T1_ID); gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 1*4, REG_CPU_ID), REG_T2_ID); @@ -445,14 +457,14 @@ bool powerpc_jit::gen_x86_stvx(int mnemo, int vS, int rA, int rB) gen_bswap_32(REG_T1_ID); gen_bswap_32(REG_T2_ID); gen_and_32(x86_immediate_operand(-16), REG_T0_ID); - gen_mov_32(REG_T1_ID, x86_memory_operand(0*4, REG_T0_ID)); - gen_mov_32(REG_T2_ID, x86_memory_operand(1*4, REG_T0_ID)); + gen_mov_32(REG_T1_ID, vm_memory_operand(0*4, REG_T0_ID)); + gen_mov_32(REG_T2_ID, vm_memory_operand(1*4, REG_T0_ID)); gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 2*4, REG_CPU_ID), REG_T1_ID); gen_mov_32(x86_memory_operand(xPPC_VR(vS) + 3*4, REG_CPU_ID), REG_T2_ID); gen_bswap_32(REG_T1_ID); gen_bswap_32(REG_T2_ID); - gen_mov_32(REG_T1_ID, x86_memory_operand(2*4, REG_T0_ID)); - gen_mov_32(REG_T2_ID, x86_memory_operand(3*4, REG_T0_ID)); + gen_mov_32(REG_T1_ID, vm_memory_operand(2*4, REG_T0_ID)); + gen_mov_32(REG_T2_ID, vm_memory_operand(3*4, REG_T0_ID)); #endif return true; } @@ -667,7 +679,7 @@ void powerpc_jit::gen_sse2_vsplat(int vD, int rValue) } // vspltisb -bool powerpc_jit::gen_sse2_vspltisb(int mnemo, int vD, int SIMM) +bool powerpc_jit::gen_sse2_vspltisb(int mnemo, int vD, int SIMM, int unused) { switch (SIMM) { case 0: @@ -718,7 +730,7 @@ bool powerpc_jit::gen_sse2_vspltisb(int mnemo, int vD, int SIMM) } // vspltish -bool powerpc_jit::gen_sse2_vspltish(int mnemo, int vD, int SIMM) +bool powerpc_jit::gen_sse2_vspltish(int mnemo, int vD, int SIMM, int unused) { switch (SIMM) { case 0: @@ -764,7 +776,7 @@ bool powerpc_jit::gen_sse2_vspltish(int mnemo, int vD, int SIMM) } // vspltisw -bool powerpc_jit::gen_sse2_vspltisw(int mnemo, int vD, int SIMM) +bool powerpc_jit::gen_sse2_vspltisw(int mnemo, int vD, int SIMM, int unused) { switch (SIMM) { case 0: @@ -866,7 +878,7 @@ bool powerpc_jit::gen_ssse3_lvx(int mnemo, int vD, int rA, int rB) gen_and_32(x86_immediate_operand(-16), REG_T0_ID); x86_memory_operand vswapmask(gen_ssse3_vswap_mask(), X86_NOREG); - gen_movdqa(x86_memory_operand(0, REG_T0_ID), REG_V0_ID); + gen_movdqa(vm_memory_operand(0, REG_T0_ID), REG_V0_ID); gen_insn(X86_INSN_SSE_3P, X86_SSSE3_PSHUFB, vswapmask, REG_V0_ID); gen_movdqa(REG_V0_ID, x86_memory_operand(xPPC_VR(vD), REG_CPU_ID)); return true; @@ -883,7 +895,7 @@ bool powerpc_jit::gen_ssse3_stvx(int mnemo, int vS, int rA, int rB) x86_memory_operand vswapmask(gen_ssse3_vswap_mask(), X86_NOREG); gen_movdqa(x86_memory_operand(xPPC_VR(vS), REG_CPU_ID), REG_V0_ID); gen_insn(X86_INSN_SSE_3P, X86_SSSE3_PSHUFB, vswapmask, REG_V0_ID); - gen_movdqa(REG_V0_ID, x86_memory_operand(0, REG_T0_ID)); + gen_movdqa(REG_V0_ID, vm_memory_operand(0, REG_T0_ID)); return true; } @@ -940,3 +952,5 @@ bool powerpc_jit::gen_ssse3_vperm(int mnemo, int vD, int vA, int vB, int vC) return true; } #endif + +#endif //ENABLE_DYNGEN diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.hpp index a8e563ae1..2117c5a71 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-jit.hpp @@ -90,9 +90,9 @@ struct powerpc_jit bool gen_sse2_vsel(int mnemo, int vD, int vA, int vB, int vC); bool gen_sse2_vsldoi(int mnemo, int vD, int vA, int vB, int SH); void gen_sse2_vsplat(int vD, int rValue); - bool gen_sse2_vspltisb(int mnemo, int vD, int SIMM); - bool gen_sse2_vspltish(int mnemo, int vD, int SIMM); - bool gen_sse2_vspltisw(int mnemo, int vD, int SIMM); + bool gen_sse2_vspltisb(int mnemo, int vD, int SIMM, int unused); + bool gen_sse2_vspltish(int mnemo, int vD, int SIMM, int unused); + bool gen_sse2_vspltisw(int mnemo, int vD, int SIMM, int unused); bool gen_sse2_vspltb(int mnemo, int vD, int UIMM, int vB); bool gen_sse2_vsplth(int mnemo, int vD, int UIMM, int vB); bool gen_sse2_vspltw(int mnemo, int vD, int UIMM, int vB); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-operations.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-operations.hpp index 47b56493e..50719ffa1 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-operations.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-operations.hpp @@ -153,7 +153,7 @@ DEFINE_OP2(fsubs, float, x - y); DEFINE_OP1(exp2, float, exp2f(x)); DEFINE_OP1(log2, float, log2f(x)); DEFINE_OP1(fres, float, 1 / x); -DEFINE_OP1(frsqrt, float, 1 / sqrt(x)); +DEFINE_OP1(frsqrte, float, 1 / sqrt(x)); DEFINE_OP1(frsim, float, floorf(x)); DEFINE_OP1(frsin, float, roundf(x)); DEFINE_OP1(frsip, float, ceilf(x)); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-translate.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-translate.cpp index 7d0231474..fe882373b 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-translate.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-translate.cpp @@ -125,6 +125,22 @@ static void disasm_translation(uint32 src_addr, uint32 src_len, **/ #if PPC_ENABLE_JIT + +void +powerpc_cpu::call_do_record_step(powerpc_cpu * cpu, uint32 param1, uint32 param2) { + cpu->do_record_step(param1, param2); +} + +void +powerpc_cpu::call_execute_invalidate_cache_range(powerpc_cpu * cpu) { + cpu->execute_invalidate_cache_range(); +} + +void +powerpc_cpu::call_execute_illegal(powerpc_cpu * cpu, uint32 param1) { + cpu->execute_illegal(param1); +} + powerpc_cpu::block_info * powerpc_cpu::compile_block(uint32 entry_point) { @@ -169,7 +185,7 @@ powerpc_cpu::compile_block(uint32 entry_point) #if PPC_FLIGHT_RECORDER if (is_logging()) { typedef void (*func_t)(dyngen_cpu_base, uint32, uint32); - func_t func = (func_t)nv_mem_fun((execute_pmf)&powerpc_cpu::do_record_step).ptr(); + func_t func = &powerpc_cpu::call_do_record_step; dg.gen_invoke_CPU_im_im(func, dpc, opcode); } #endif @@ -1120,7 +1136,7 @@ powerpc_cpu::compile_block(uint32 entry_point) case PPC_I(ISYNC): // Instruction synchronize { typedef void (*func_t)(dyngen_cpu_base); - func_t func = (func_t)nv_mem_fun(&powerpc_cpu::execute_invalidate_cache_range).ptr(); + func_t func = &powerpc_cpu::call_execute_invalidate_cache_range; dg.gen_invoke_CPU(func); break; } @@ -1377,10 +1393,17 @@ powerpc_cpu::compile_block(uint32 entry_point) case PPC_I(STVEWX): case PPC_I(STVX): case PPC_I(STVXL): + { assert(vD_field::mask() == vS_field::mask()); assert(vA_field::mask() == rA_field::mask()); assert(vB_field::mask() == rB_field::mask()); - // fall-through + const int vD = vD_field::extract(opcode); + const int vA = vA_field::extract(opcode); + const int vB = vB_field::extract(opcode); + if (!dg.gen_vector_2(ii->mnemo, vD, vA, vB)) + goto do_generic; + break; + } case PPC_I(VCMPEQFP): case PPC_I(VCMPEQUB): case PPC_I(VCMPEQUH): @@ -1488,10 +1511,14 @@ powerpc_cpu::compile_block(uint32 entry_point) typedef void (*func_t)(dyngen_cpu_base, uint32); func_t func; do_generic: + #ifdef __MINGW32__ + func = (func_t)ii->execute.default_call_conv_ptr(); + #else func = (func_t)ii->execute.ptr(); + #endif goto do_invoke; do_illegal: - func = (func_t)nv_mem_fun(&powerpc_cpu::execute_illegal).ptr(); + func = &powerpc_cpu::call_execute_illegal; goto do_invoke; do_invoke: #if PPC_PROFILE_GENERIC_CALLS @@ -1554,7 +1581,7 @@ powerpc_cpu::compile_block(uint32 entry_point) // Generate backpatch trampolines if (use_direct_block_chaining) { typedef void *(*func_t)(dyngen_cpu_base); - func_t func = (func_t)nv_mem_fun(&powerpc_cpu::compile_chain_block).ptr(); + func_t func = (func_t)&powerpc_cpu::call_compile_chain_block; for (int i = 0; i < block_info::MAX_TARGETS; i++) { if (bi->li[i].jmp_pc != block_info::INVALID_PC) { uint8 *p = dg.gen_align(16); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/spcflags.hpp b/SheepShaver/src/kpx_cpu/src/cpu/spcflags.hpp index 0b521d534..d379f1cb1 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/spcflags.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/spcflags.hpp @@ -41,8 +41,10 @@ class basic_spcflags public: basic_spcflags() - : mask(0), lock(SPIN_LOCK_UNLOCKED) - { } + { init(); } + + void init() + { mask = 0; lock = SPIN_LOCK_UNLOCKED; } bool empty() const { return (mask == 0); } diff --git a/SheepShaver/src/kpx_cpu/src/cpu/vm.hpp b/SheepShaver/src/kpx_cpu/src/cpu/vm.hpp old mode 100644 new mode 100755 index 55f30ec36..c01dc6ac8 --- a/SheepShaver/src/kpx_cpu/src/cpu/vm.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/vm.hpp @@ -205,7 +205,13 @@ const uintptr VMBaseDiff = NATMEM_OFFSET; #if REAL_ADDRESSING || DIRECT_ADDRESSING static inline uint8 * vm_do_get_real_address(vm_addr_t addr) { - return (uint8 *)vm_wrap_address(VMBaseDiff + addr); + uintptr a = vm_wrap_address(addr); +#if defined(__APPLE__) && defined(__x86_64__) + extern uint8 gZeroPage[0x3000], gKernelData[0x2000]; + if (a < 0x3000) return &gZeroPage[a]; + else if ((a & ~0x1fff) == 0x68ffe000 || (a & ~0x1fff) == 0x5fffe000) return &gKernelData[a & 0x1fff]; +#endif + return (uint8 *)(VMBaseDiff + a); } static inline vm_addr_t vm_do_get_virtual_address(uint8 *addr) { diff --git a/SheepShaver/src/kpx_cpu/src/mathlib/mathlib.cpp b/SheepShaver/src/kpx_cpu/src/mathlib/mathlib.cpp index d51a8db27..dc8a8d948 100644 --- a/SheepShaver/src/kpx_cpu/src/mathlib/mathlib.cpp +++ b/SheepShaver/src/kpx_cpu/src/mathlib/mathlib.cpp @@ -88,6 +88,7 @@ int mathlib_fpclassify (double x) int mathlib_fpclassifyl(long double x) { unimplemented("fpclassifyl"); + return -1; } @@ -114,6 +115,7 @@ int mathlib_signbit (double x) int mathlib_signbitl(long double x) { unimplemented("signbitl"); + return -1; } diff --git a/SheepShaver/src/macos_util.cpp b/SheepShaver/src/macos_util.cpp index bb33ace53..d6fe84297 100644 --- a/SheepShaver/src/macos_util.cpp +++ b/SheepShaver/src/macos_util.cpp @@ -28,6 +28,8 @@ #include "emul_op.h" #include "macos_util.h" #include "thunks.h" +#include "prefs.h" +#include #define DEBUG 0 #include "debug.h" @@ -101,6 +103,32 @@ void Enqueue(uint32 elem, uint32 list) } } +static void InsertQueueEntry(uint32 elem, uint32 at, uint32 list) { + uint32 next = ReadMacInt32(at); + WriteMacInt32(at, elem); + WriteMacInt32(elem + qLink, next); + if (next == 0) { + // inserted at end + WriteMacInt32(list + qTail, elem); + } +} + +static void RemoveQueueEntry(uint32 at, uint32 list) { + uint32 e = ReadMacInt32(at); + uint32 next = ReadMacInt32(e + qLink); + + if (next == 0) { + // removing from end + if (at == list + qHead) { + WriteMacInt32(list + qTail, 0); + } else { + WriteMacInt32(list + qTail, at - qLink); + } + } + + WriteMacInt32(at, next); + WriteMacInt32(e + qLink, 0); +} /* * Find first free drive number, starting at num @@ -125,6 +153,37 @@ int FindFreeDriveNumber(int num) return num; } +/* + * Move drives of the given driver to the front of the drive queue + */ +void MoveDrivesFromDriverToFront(uint32 driverRefNum) { + + const uint32 DrvQHdr = 0x308; // drive queue address + + uint32 nextInsertPos = DrvQHdr + qHead; + + uint32 ptrToElem = DrvQHdr + qHead; + uint32 e = ReadMacInt32(ptrToElem); + while (e) { + uint32 next = ReadMacInt32(e + qLink); + + uint32 d = e - dsQLink; + uint32 curRefNum = ReadMacInt16(d + dsQRefNum); + + if ((curRefNum & 0xffff) == (driverRefNum & 0xffff)) { + RemoveQueueEntry(ptrToElem, DrvQHdr); + InsertQueueEntry(e, nextInsertPos, DrvQHdr); + + nextInsertPos = e + qLink; + + // after the removal, ptrToElem already points to next + } else { + ptrToElem = e + qLink; + } + + e = next; + } +} /* * Mount volume with given file handle (call this function when you are unable to @@ -324,9 +383,21 @@ uint32 TimeToMacTime(time_t t) // This code is taken from glibc 2.2 // Convert to number of seconds elapsed since 1-Jan-1904 +#ifdef WIN32 + if (t == -1) { + // failsafe as this will segfault + return 0; + } struct tm *local = localtime(&t); +#else + struct tm result; + localtime_r(&t, &result); + struct tm *local = &result; +#endif const int TM_EPOCH_YEAR = 1900; const int MAC_EPOCH_YEAR = 1904; + // Clip year and day offsets to prevent dates earlier than 1-Jan-1904 + local->tm_year = std::max(MAC_EPOCH_YEAR - TM_EPOCH_YEAR, local->tm_year + PrefsFindInt32("yearofs")); int a4 = ((local->tm_year + TM_EPOCH_YEAR) >> 2) - !(local->tm_year & 3); int b4 = (MAC_EPOCH_YEAR >> 2) - !(MAC_EPOCH_YEAR & 3); int a100 = a4 / 25 - (a4 % 25 < 0); @@ -335,7 +406,10 @@ uint32 TimeToMacTime(time_t t) int b400 = b100 >> 2; int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); uint32 days = local->tm_yday + 365 * (local->tm_year - 4) + intervening_leap_days; - return local->tm_sec + 60 * (local->tm_min + 60 * (local->tm_hour + 24 * days)); + int32 dayofs = -PrefsFindInt32("dayofs"); + if(dayofs > 0 && dayofs > days) + dayofs = days; + return local->tm_sec + 60 * (local->tm_min + 60 * (local->tm_hour + 24 * (days - dayofs))); } diff --git a/SheepShaver/src/main.cpp b/SheepShaver/src/main.cpp old mode 100644 new mode 100755 index 1224fbe1a..b725e08f6 --- a/SheepShaver/src/main.cpp +++ b/SheepShaver/src/main.cpp @@ -164,63 +164,62 @@ bool InitAll(const char *vmdir) } // Initialize Kernel Data - KernelData *kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE); - memset(kernel_data, 0, sizeof(KernelData)); + Mac_memset(KERNEL_DATA_BASE, 0, sizeof(KernelData)); if (ROMType == ROMTYPE_NEWWORLD) { uint32 of_dev_tree = SheepMem::Reserve(4 * sizeof(uint32)); Mac_memset(of_dev_tree, 0, 4 * sizeof(uint32)); uint32 vector_lookup_tbl = SheepMem::Reserve(128); uint32 vector_mask_tbl = SheepMem::Reserve(64); - memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80); + Mac_memset(KERNEL_DATA_BASE + 0xb80, 0x3d, 0x80); Mac_memset(vector_lookup_tbl, 0, 128); Mac_memset(vector_mask_tbl, 0, 64); - kernel_data->v[0xb80 >> 2] = htonl(ROMBase); - kernel_data->v[0xb84 >> 2] = htonl(of_dev_tree); // OF device tree base - kernel_data->v[0xb90 >> 2] = htonl(vector_lookup_tbl); - kernel_data->v[0xb94 >> 2] = htonl(vector_mask_tbl); - kernel_data->v[0xb98 >> 2] = htonl(ROMBase); // OpenPIC base - kernel_data->v[0xbb0 >> 2] = htonl(0); // ADB base - kernel_data->v[0xc20 >> 2] = htonl(RAMSize); - kernel_data->v[0xc24 >> 2] = htonl(RAMSize); - kernel_data->v[0xc30 >> 2] = htonl(RAMSize); - kernel_data->v[0xc34 >> 2] = htonl(RAMSize); - kernel_data->v[0xc38 >> 2] = htonl(0x00010020); - kernel_data->v[0xc3c >> 2] = htonl(0x00200001); - kernel_data->v[0xc40 >> 2] = htonl(0x00010000); - kernel_data->v[0xc50 >> 2] = htonl(RAMBase); - kernel_data->v[0xc54 >> 2] = htonl(RAMSize); - kernel_data->v[0xf60 >> 2] = htonl(PVR); - kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); // clock-frequency - kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); // bus-frequency - kernel_data->v[0xf6c >> 2] = htonl(TimebaseSpeed); // timebase-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xb80, ROMBase); + WriteMacInt32(KERNEL_DATA_BASE + 0xb84, of_dev_tree); // OF device tree base + WriteMacInt32(KERNEL_DATA_BASE + 0xb90, vector_lookup_tbl); + WriteMacInt32(KERNEL_DATA_BASE + 0xb94, vector_mask_tbl); + WriteMacInt32(KERNEL_DATA_BASE + 0xb98, ROMBase); // OpenPIC base + WriteMacInt32(KERNEL_DATA_BASE + 0xbb0, 0); // ADB base + WriteMacInt32(KERNEL_DATA_BASE + 0xc20, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc24, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc30, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc34, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc38, 0x00010020); + WriteMacInt32(KERNEL_DATA_BASE + 0xc3c, 0x00200001); + WriteMacInt32(KERNEL_DATA_BASE + 0xc40, 0x00010000); + WriteMacInt32(KERNEL_DATA_BASE + 0xc50, RAMBase); + WriteMacInt32(KERNEL_DATA_BASE + 0xc54, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xf60, PVR); + WriteMacInt32(KERNEL_DATA_BASE + 0xf64, CPUClockSpeed); // clock-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xf68, BusClockSpeed); // bus-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xf6c, TimebaseSpeed); // timebase-frequency } else if (ROMType == ROMTYPE_GOSSAMER) { - kernel_data->v[0xc80 >> 2] = htonl(RAMSize); - kernel_data->v[0xc84 >> 2] = htonl(RAMSize); - kernel_data->v[0xc90 >> 2] = htonl(RAMSize); - kernel_data->v[0xc94 >> 2] = htonl(RAMSize); - kernel_data->v[0xc98 >> 2] = htonl(0x00010020); - kernel_data->v[0xc9c >> 2] = htonl(0x00200001); - kernel_data->v[0xca0 >> 2] = htonl(0x00010000); - kernel_data->v[0xcb0 >> 2] = htonl(RAMBase); - kernel_data->v[0xcb4 >> 2] = htonl(RAMSize); - kernel_data->v[0xf60 >> 2] = htonl(PVR); - kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); // clock-frequency - kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); // bus-frequency - kernel_data->v[0xf6c >> 2] = htonl(TimebaseSpeed); // timebase-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xc80, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc84, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc90, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc94, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc98, 0x00010020); + WriteMacInt32(KERNEL_DATA_BASE + 0xc9c, 0x00200001); + WriteMacInt32(KERNEL_DATA_BASE + 0xca0, 0x00010000); + WriteMacInt32(KERNEL_DATA_BASE + 0xcb0, RAMBase); + WriteMacInt32(KERNEL_DATA_BASE + 0xcb4, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xf60, PVR); + WriteMacInt32(KERNEL_DATA_BASE + 0xf64, CPUClockSpeed); // clock-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xf68, BusClockSpeed); // bus-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xf6c, TimebaseSpeed); // timebase-frequency } else { - kernel_data->v[0xc80 >> 2] = htonl(RAMSize); - kernel_data->v[0xc84 >> 2] = htonl(RAMSize); - kernel_data->v[0xc90 >> 2] = htonl(RAMSize); - kernel_data->v[0xc94 >> 2] = htonl(RAMSize); - kernel_data->v[0xc98 >> 2] = htonl(0x00010020); - kernel_data->v[0xc9c >> 2] = htonl(0x00200001); - kernel_data->v[0xca0 >> 2] = htonl(0x00010000); - kernel_data->v[0xcb0 >> 2] = htonl(RAMBase); - kernel_data->v[0xcb4 >> 2] = htonl(RAMSize); - kernel_data->v[0xf80 >> 2] = htonl(PVR); - kernel_data->v[0xf84 >> 2] = htonl(CPUClockSpeed); // clock-frequency - kernel_data->v[0xf88 >> 2] = htonl(BusClockSpeed); // bus-frequency - kernel_data->v[0xf8c >> 2] = htonl(TimebaseSpeed); // timebase-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xc80, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc84, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc90, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc94, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xc98, 0x00010020); + WriteMacInt32(KERNEL_DATA_BASE + 0xc9c, 0x00200001); + WriteMacInt32(KERNEL_DATA_BASE + 0xca0, 0x00010000); + WriteMacInt32(KERNEL_DATA_BASE + 0xcb0, RAMBase); + WriteMacInt32(KERNEL_DATA_BASE + 0xcb4, RAMSize); + WriteMacInt32(KERNEL_DATA_BASE + 0xf80, PVR); + WriteMacInt32(KERNEL_DATA_BASE + 0xf84, CPUClockSpeed); // clock-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xf88, BusClockSpeed); // bus-frequency + WriteMacInt32(KERNEL_DATA_BASE + 0xf8c, TimebaseSpeed); // timebase-frequency } // Initialize extra low memory @@ -265,6 +264,17 @@ bool InitAll(const char *vmdir) return true; } +void CDROMOpenDone() { + // At this point, any initial CD-ROM drives have been added to the drive queue. + if (ROMType == ROMTYPE_NEWWORLD) { + // The PRAM boot device setting has no apparent effect, + // but we can achieve a boot with the specified device by reordering the drive queue ourselves. + int bootdriver = PrefsFindInt32("bootdriver"); + if (bootdriver) { + MoveDrivesFromDriverToFront(bootdriver); + } + } +} /* * Deinitialize everything diff --git a/SheepShaver/src/prefs_items.cpp b/SheepShaver/src/prefs_items.cpp index 1d4758dc9..b5ea6763c 100644 --- a/SheepShaver/src/prefs_items.cpp +++ b/SheepShaver/src/prefs_items.cpp @@ -58,6 +58,21 @@ prefs_desc common_prefs_items[] = { {"jit", TYPE_BOOLEAN, false, "enable JIT compiler"}, {"jit68k", TYPE_BOOLEAN, false, "enable 68k DR emulator"}, {"keyboardtype", TYPE_INT32, false, "hardware keyboard type"}, + {"hardcursor", TYPE_BOOLEAN, false, "hardware mouse cursor"}, + {"hotkey", TYPE_INT32, false, "hotkey modifier"}, + {"scale_nearest",TYPE_BOOLEAN,false,"nearest neighbor scaling"}, + {"scale_integer",TYPE_BOOLEAN,false,"integer scaling"}, + {"cpuclock", TYPE_INT32, 0, "CPU clock [MHz] of system info"}, + {"yearofs", TYPE_INT32, 0, "year offset"}, + {"dayofs", TYPE_INT32, 0, "day offset"}, + {"mag_rate", TYPE_INT32, 0, "rate of magnification"}, + {"gammaramp", TYPE_STRING, false, "gamma ramp (on, off or fullscreen)"}, + {"swap_opt_cmd", TYPE_BOOLEAN, false, "swap option and command key"}, + {"host_domain", TYPE_STRING, true, "handle DNS requests for this domain on the host (slirp only)"}, + {"redir", TYPE_STRING, true, "port forwarding for slirp"}, + {"title", TYPE_STRING, false, "window title"}, + {"sound_buffer", TYPE_INT32, false, "sound buffer length"}, + {"name_encoding", TYPE_INT32, false, "file name encoding"}, {NULL, TYPE_END, false, NULL} // End of list }; @@ -80,7 +95,7 @@ void AddPrefsDefaults(void) PrefsAddBool("nosound", false); PrefsAddBool("nogui", false); PrefsAddBool("noclipconversion", false); - PrefsAddBool("ignoresegv", false); + PrefsAddBool("ignoresegv", true); PrefsAddBool("ignoreillegal", false); #if USE_JIT @@ -92,4 +107,10 @@ void AddPrefsDefaults(void) PrefsAddBool("jit68k", false); PrefsAddInt32("keyboardtype", 5); + +#ifdef __APPLE__ + PrefsAddBool("swap_opt_cmd", false); +#else + PrefsAddBool("swap_opt_cmd", true); +#endif } diff --git a/SheepShaver/src/rom_patches.cpp b/SheepShaver/src/rom_patches.cpp index 83d6f17d2..b9ccc9868 100644 --- a/SheepShaver/src/rom_patches.cpp +++ b/SheepShaver/src/rom_patches.cpp @@ -411,12 +411,12 @@ static const uint8 sony_driver[] = { // Replacement for .Sony driver static const uint8 disk_driver[] = { // Generic disk driver // Driver header DiskDriverFlags >> 8, DiskDriverFlags & 0xff, 0, 0, 0, 0, 0, 0, - 0x00, 0x18, // Open() offset - 0x00, 0x1c, // Prime() offset - 0x00, 0x20, // Control() offset - 0x00, 0x2c, // Status() offset - 0x00, 0x52, // Close() offset - 0x05, 0x2e, 0x44, 0x69, 0x73, 0x6b, // ".Disk" + 0x00, 0x1c, // Open() offset + 0x00, 0x20, // Prime() offset + 0x00, 0x24, // Control() offset + 0x00, 0x30, // Status() offset + 0x00, 0x56, // Close() offset + 0x08, 0x2e, 0x41, 0x54, 0x41, 0x44, 0x69, 0x73, 0x6b, 0x00, // ".ATADisk" // Open() M68K_EMUL_OP_DISK_OPEN >> 8, M68K_EMUL_OP_DISK_OPEN & 0xff, @@ -693,7 +693,7 @@ bool PatchROM(void) ROMType = ROMTYPE_NEWWORLD; else return false; - + // Check that other ROM addresses point to really free regions if (!check_rom_patch_space(CHECK_LOAD_PATCH_SPACE, 0x40)) return false; @@ -2362,6 +2362,7 @@ static bool patch_68k(void) *wp++ = htons(0x4e74); *wp++ = htons(0x0008); // rtd #8 } } + return true; } @@ -2418,7 +2419,7 @@ void InstallDrivers(void) WriteMacInt16(dce + dCtlFlags, DiskDriverFlags); // Open disk driver - SheepString disk_str("\005.Disk"); + SheepString disk_str("\010.ATADisk"); WriteMacInt32(pb + ioNamePtr, disk_str.addr()); r.a[0] = pb; Execute68kTrap(0xa000, &r); // Open() diff --git a/SheepShaver/src/rsrc_patches.cpp b/SheepShaver/src/rsrc_patches.cpp index 8bf0ac4ff..ec6fcc2c4 100644 --- a/SheepShaver/src/rsrc_patches.cpp +++ b/SheepShaver/src/rsrc_patches.cpp @@ -517,12 +517,11 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size) D(bug(" patch applied\n")); } - } else if (type == FOURCC('D','R','V','R') && (id == -16501 || id == -16500)) { + } else if (type == FOURCC('D','R','V','R') && (id == -16501 || id == -16500)) { // patch over native sound input driver and trap out to code in audio.cpp D(bug("DRVR -16501/-16500 found\n")); // Install sound input driver memcpy(p, sound_input_driver, sizeof(sound_input_driver)); D(bug(" patch 1 applied\n")); - } else if (type == FOURCC('I','N','I','T') && id == 1 && size == (2416 >> 1)) { D(bug("INIT 1 (size 2416) found\n")); size >>= 1; @@ -627,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)); @@ -647,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) @@ -664,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) @@ -681,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); @@ -921,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) { @@ -937,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() @@ -954,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() @@ -971,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() @@ -988,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() @@ -1005,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() @@ -1022,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() @@ -1039,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/timer.cpp b/SheepShaver/src/timer.cpp index 3edd6ca0d..f8a52ecc4 100644 --- a/SheepShaver/src/timer.cpp +++ b/SheepShaver/src/timer.cpp @@ -375,8 +375,8 @@ int16 RmvTime(uint32 tm) thread_suspend(timer_thread); #endif #if PRECISE_TIMING_POSIX - timer_thread_suspend(); pthread_mutex_lock(&wakeup_time_lock); + timer_thread_suspend(); #endif if (ReadMacInt16(tm + qType) & 0x8000) { @@ -492,8 +492,8 @@ int16 PrimeTime(uint32 tm, int32 time) thread_suspend(timer_thread); #endif #if PRECISE_TIMING_POSIX - timer_thread_suspend(); pthread_mutex_lock(&wakeup_time_lock); + timer_thread_suspend(); #endif WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000); enqueue_tm(tm); @@ -647,8 +647,8 @@ void TimerInterrupt(void) thread_suspend(timer_thread); #endif #if PRECISE_TIMING_POSIX - timer_thread_suspend(); pthread_mutex_lock(&wakeup_time_lock); + timer_thread_suspend(); #endif wakeup_time = wakeup_time_max; for (TMDesc *d = tmDescList; d; d = d->next) diff --git a/SheepShaver/src/user_strings.cpp b/SheepShaver/src/user_strings.cpp index 7da1a8d89..d54f335c4 100644 --- a/SheepShaver/src/user_strings.cpp +++ b/SheepShaver/src/user_strings.cpp @@ -32,18 +32,13 @@ #include "sysdeps.h" #include "user_strings.h" +#include "version.h" -#ifdef __BEOS__ -#define ELLIPSIS "\xE2\x80\xA6" -#else #define ELLIPSIS "..." -#endif - // 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"}, @@ -76,7 +71,7 @@ user_string_def common_strings[] = { {STR_SCSI_BUFFER_ERR, "Cannot allocate SCSI buffer (requested %d bytes). Giving up."}, {STR_SCSI_SG_FULL_ERR, "SCSI scatter/gather table full. Giving up."}, - {STR_SMALL_RAM_WARN, "Selected less than 8MB Mac RAM, using 8MB."}, + {STR_SMALL_RAM_WARN, "Selected less than 16MB Mac RAM, using 16MB."}, {STR_CANNOT_UNMOUNT_WARN, "The volume '%s' could not be unmounted. SheepShaver will not use it."}, {STR_CREATE_VOLUME_WARN, "Cannot create hardfile (%s)."}, @@ -142,6 +137,12 @@ user_string_def common_strings[] = { {STR_SIZE_1024_LAB, "1024"}, {STR_SIZE_MAX_LAB, "Maximum"}, {STR_NOSOUND_CTRL, "Disable Sound Output"}, + {STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL, "Render Driver"}, + {STR_SOFTWARE_LAB, "Software"}, + {STR_OPENGL_LAB, "OpenGL"}, + {STR_DIRECT3D_LAB, "Direct3D"}, + {STR_GRAPHICS_SDL_VSYNC_CTRL, "Vertical Sync (Software)"}, + {STR_DEFAULT_LAB, "Default"}, {STR_SERIAL_NETWORK_PANE_TITLE, "Serial/Network"}, {STR_SERPORTA_CTRL, "Modem Port"}, @@ -171,11 +172,9 @@ user_string_def common_strings[] = { {STR_JIT_68K_CTRL, "Enable built-in 68k DR Emulator (EXPERIMENTAL)"}, {STR_WINDOW_TITLE, "SheepShaver"}, - {STR_WINDOW_TITLE_FROZEN, "SheepShaver *** FROZEN ***"}, - {STR_WINDOW_TITLE_GRABBED, "SheepShaver (mouse grabbed, press Ctrl-F5 to release)"}, - {STR_WINDOW_TITLE_GRABBED0, "SheepShaver (mouse grabbed, press "}, + {STR_WINDOW_TITLE_GRABBED0, " (mouse grabbed, press "}, {STR_WINDOW_TITLE_GRABBED1, "Ctrl-"}, -#ifdef __MACOSX__ +#ifdef __APPLE__ {STR_WINDOW_TITLE_GRABBED2, "Opt-"}, {STR_WINDOW_TITLE_GRABBED3, "Cmd-"}, #else diff --git a/SheepShaver/src/video.cpp b/SheepShaver/src/video.cpp index 60ef8c135..bcdeb3601 100644 --- a/SheepShaver/src/video.cpp +++ b/SheepShaver/src/video.cpp @@ -46,6 +46,7 @@ uint32 screen_base = 0; // Frame buffer base address int cur_mode; // Number of current video mode (index in VModes array) int display_type = DIS_INVALID; // Current display type rgb_color mac_pal[256]; +rgb_color mac_gamma[256]; uint8 remap_mac_be[256]; uint8 MacCursor[68] = {16, 1}; // Mac cursor image @@ -110,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; } @@ -125,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 b? a : b; + } + static int16 set_gamma(VidLocals *csSave, uint32 gamma) { if (gamma == 0) { // Build linear ramp, 256 entries @@ -229,9 +234,12 @@ static int16 set_gamma(VidLocals *csSave, uint32 gamma) // Build the linear ramp uint32 p = csSave->gammaTable + gFormulaData; - for (int i=0; i<256; i++) + + for (int i=0; i<256; i++) { WriteMacInt8(p + i, i); - + mac_gamma[i].red = mac_gamma[i].green = mac_gamma[i].blue = i; + } + video_set_gamma(256); } else { // User-supplied gamma table // Validate header @@ -256,6 +264,39 @@ static int16 set_gamma(VidLocals *csSave, uint32 gamma) // Copy table Mac2Mac_memcpy(csSave->gammaTable, gamma, size); + + // Save new gamma data for video impl + if (data_width != 8) { + // FIXME: handle bit-packed data + } else { + uint32 p = csSave->gammaTable + gFormulaData + gFormulaSize; + + uint32 p_red; + uint32 p_green; + uint32 p_blue; + + // make values increasing as some implementations really don't like it when gamma tables aren't + uint8 max_red = 0; + uint8 max_green = 0; + uint8 max_blue = 0; + + if (chan_cnt == 3) { + p_red = p; + p_green = p + data_cnt; + p_blue = p + data_cnt * 2; + } else { + p_red = p_green = p_blue = p; + } + for (int i=0; i < data_cnt; i++) { + max_red = max(max_red, ReadMacInt8(p_red++)); + max_green = max(max_green, ReadMacInt8(p_green++)); + max_blue = max(max_blue, ReadMacInt8(p_blue++)); + mac_gamma[i].red = max_red; + mac_gamma[i].green = max_green; + mac_gamma[i].blue = max_blue; + } + } + video_set_gamma(data_cnt); } return noErr; } @@ -283,7 +324,7 @@ static int16 VideoControl(uint32 pb, VidLocals *csSave) return video_mode_change(csSave, param); case cscSetEntries: { // SetEntries - D(bug("SetEntries\n")); + D(bug("SetEntries\n")); if (VModes[cur_mode].viAppleMode > APPLE_8_BIT) return controlErr; uint32 s_pal = ReadMacInt32(param + csTable); uint16 start = ReadMacInt16(param + csStart); @@ -297,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)); @@ -634,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); @@ -709,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))); @@ -824,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)) { @@ -838,46 +875,47 @@ static int16 VideoStatus(uint32 pb, VidLocals *csSave) WriteMacInt16(vpb + vpVersion, 0); // Pixel Map version number WriteMacInt16(vpb + vpPackType, 0); WriteMacInt32(vpb + vpPackSize, 0); + WriteMacInt32(vpb + vpPlaneBytes, 0); WriteMacInt32(vpb + vpHRes, 0x00480000); // horiz res of the device (ppi) 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); diff --git a/cxmon/autogen.sh b/cxmon/autogen.sh deleted file mode 100755 index 29f68f58d..000000000 --- a/cxmon/autogen.sh +++ /dev/null @@ -1,57 +0,0 @@ -#! /bin/sh -# Run this to generate all the initial makefiles, etc. -# This was lifted from the Gimp, and adapted slightly by -# Christian Bauer. - -DIE=0 - -PROG="cxmon" - -# Check how echo works in this /bin/sh -case `echo -n` in --n) _echo_n= _echo_c='\c';; -*) _echo_n=-n _echo_c=;; -esac - -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have autoconf installed to compile $PROG." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" - DIE=1 -} - -(aclocal --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "**Error**: Missing aclocal. The version of automake" - echo "installed doesn't appear recent enough." - echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" - echo "(or a newer version if it is available)" - DIE=1 -} - -if test "$DIE" -eq 1; then - exit 1 -fi - -aclocalinclude="$ACLOCAL_FLAGS"; \ -(echo $_echo_n " + Running aclocal: $_echo_c"; \ - aclocal $aclocalinclude; \ - echo "done.") && \ -(echo $_echo_n " + Running autoheader: $_echo_c"; \ - autoheader; \ - echo "done.") && \ -(echo $_echo_n " + Running autoconf: $_echo_c"; \ - autoconf; \ - echo "done.") - -rm -f config.cache - -if [ x"$NO_CONFIGURE" = "x" ]; then - echo " + Running 'configure $@':" - if [ -z "$*" ]; then - echo " ** If you wish to pass arguments to ./configure, please" - echo " ** specify them on the command line." - fi - ./configure "$@" -fi diff --git a/cxmon/configure.ac b/cxmon/configure.ac index a2e7abcba..f93e6c853 100644 --- a/cxmon/configure.ac +++ b/cxmon/configure.ac @@ -31,8 +31,7 @@ dnl Checks for libraries. AC_SEARCH_LIBS([tgetent], [ncurses termcap termlib terminfo Hcurses curses], [], [ AC_MSG_ERROR([unable to find the tgetent() function]) ]) -AC_SEARCH_LIBS([readline], [readline], [ - AC_DEFINE([HAVE_LIBREADLINE], 1, [Define if you have the Readline library])], [ +AC_SEARCH_LIBS([readline], [readline], [], [ AC_MSG_ERROR([unable to find the readline() function]) ]) diff --git a/cxmon/src/main.cpp b/cxmon/src/main.cpp index 0a82c73cb..3f40d8a6b 100644 --- a/cxmon/src/main.cpp +++ b/cxmon/src/main.cpp @@ -100,7 +100,7 @@ static bool open_stdio(const char *title) #endif // Main program -int main(int argc, const char **argv) +int main(int argc, char **argv) { #ifdef __BEOS__ // Launched from Tracker? Then open terminal window