From d28578f7258d4823827f05bfe77c8d8b22ebe4d6 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Mon, 3 Feb 2020 15:43:58 -0600 Subject: [PATCH 1/7] basically 0.14 updated with cmake, networking modules, and packaging via github actions - osx/ubuntu --- .github/workflows/release.yml | 143 ++ .gitignore | 1 + CMakeLists.txt | 9 + COPYRIGHT.txt | 2 +- assets/Info.plist | 33 - assets/control | 2 +- doc/Developer-QuickStart-MacOSX.txt | 4 + make_dist_mac.sh | 20 - make_dmg_mac.sh | 21 - scripts/package-osx.sh | 49 + src/CMakeLists.txt | 263 +++ src/assets/GSBug.Templates | 2556 ++++++++++++++++++++++++ src/assets/NList.Data | 2653 +++++++++++++++++++++++++ src/assets/config.txt | 46 + {assets => src/assets}/gsp-icons.icns | Bin src/atbridge/CMakeLists.txt | 9 + src/atbridge/aarp.c | 2 +- src/atbridge/atbridge.c | 2 +- src/atbridge/elap.c | 10 +- src/atbridge/pcap_delay.h | 6 - src/config.txt | 45 - src/rawnet/CMakeLists.txt | 28 + src/rawnet/Networking.txt | 35 + src/rawnet/cs8900.c | 1675 ++++++++++++++++ src/rawnet/cs8900.h | 64 + src/rawnet/rawnet.c | 85 + src/rawnet/rawnet.h | 77 + src/rawnet/rawnetarch.c | 144 ++ src/rawnet/rawnetarch.h | 77 + src/rawnet/rawnetarch_tap.c | 481 +++++ src/rawnet/rawnetarch_unix.c | 511 +++++ src/rawnet/rawnetarch_vmnet.c | 281 +++ src/rawnet/rawnetarch_vmnet_helper.c | 512 +++++ src/rawnet/rawnetarch_win32.c | 579 ++++++ src/rawnet/rawnetsupp.c | 372 ++++ src/rawnet/rawnetsupp.h | 62 + src/rawnet/vmnet_helper.c | 331 +++ src/sim65816.c | 3 +- src/string_extra.c | 33 + src/string_extra.h.in | 20 + src/version.h.in | 1 + 41 files changed, 11112 insertions(+), 135 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 CMakeLists.txt delete mode 100644 assets/Info.plist delete mode 100755 make_dist_mac.sh delete mode 100755 make_dmg_mac.sh create mode 100755 scripts/package-osx.sh create mode 100644 src/CMakeLists.txt create mode 100644 src/assets/GSBug.Templates create mode 100644 src/assets/NList.Data create mode 100644 src/assets/config.txt rename {assets => src/assets}/gsp-icons.icns (100%) create mode 100644 src/atbridge/CMakeLists.txt delete mode 100644 src/config.txt create mode 100644 src/rawnet/CMakeLists.txt create mode 100644 src/rawnet/Networking.txt create mode 100644 src/rawnet/cs8900.c create mode 100644 src/rawnet/cs8900.h create mode 100644 src/rawnet/rawnet.c create mode 100644 src/rawnet/rawnet.h create mode 100644 src/rawnet/rawnetarch.c create mode 100644 src/rawnet/rawnetarch.h create mode 100644 src/rawnet/rawnetarch_tap.c create mode 100644 src/rawnet/rawnetarch_unix.c create mode 100644 src/rawnet/rawnetarch_vmnet.c create mode 100644 src/rawnet/rawnetarch_vmnet_helper.c create mode 100644 src/rawnet/rawnetarch_win32.c create mode 100644 src/rawnet/rawnetsupp.c create mode 100644 src/rawnet/rawnetsupp.h create mode 100644 src/rawnet/vmnet_helper.c create mode 100644 src/string_extra.c create mode 100644 src/string_extra.h.in create mode 100644 src/version.h.in diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..98e2c68 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,143 @@ +name: Create Release + +on: push + +jobs: + # Maybe this should go after the successful build :P + create-release: + name: Create Release Job + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Create Release + id: create_release + uses: actions/create-release@v1.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }}-testing + draft: true + prerelease: true + # Workaround to preserve the release_url generated above for our next job + - name: Store Release URL + env: + UPLOAD_URL: ${{ toJson( steps.create_release.outputs.upload_url )}} + run: | + echo "$UPLOAD_URL" > release_url.txt + echo "UPLOAD_URL= $UPLOAD_URL" + - name: Upload URL for later use + uses: actions/upload-artifact@v1 + with: + name: data + path: release_url.txt + + build-and-upload: + name: Build + needs: create-release + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ macos-latest, ubuntu-latest ] + steps: + - name: Download Release Data + uses: actions/download-artifact@v1 + with: + name: data + - name: Get Tag Name + id: get_data + shell: bash + run: | + URL=`cat data/release_url.txt | tr -d '"'` + echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/} + echo ::set-output name=RELEASE_URL::$URL + echo "URL = $URL" + echo name=SOURCE_TAG::${GITHUB_REF#refs/tags/} + - uses: actions/checkout@v1 + - uses: ilammy/msvc-dev-cmd@v1 + - name: Prep MacOSX + if: matrix.os == 'macos-latest' + shell: bash + run: | + export MACOSX_DEPLOYMENT_TARGET=10.14 + # see: https://gist.github.com/fabianfett/fd811d7921eb856bb100c5c15565077f + sudo xcode-select -s /Applications/Xcode_11.app/Contents/Developer + xcode-select -p + brew update + + # BREW PACKAGES - Note we only seem to need to get the ones we link against for Mojave + # dylibbundler--0.4.5.mojave.bottle.1.tar.gz + # sdl2--2.0.10.mojave.bottle.1.tar.gz <-- + # freetype--2.10.1.mojave.bottle.1.tar.gz <-- + # sdl2_image--2.0.5.mojave.bottle.1.tar.gz <-- + # pkg-config--0.29.2.mojave.bottle.tar.gz + + brew install dylibbundler + brew install pkg-config + + curl -L https://bintray.com/homebrew/bottles/download_file?file_path=sdl2-2.0.10.mojave.bottle.tar.gz -o sdl2-2.0.10.mojave.bottle.tar.gz + brew install -f sdl2-2.0.10.mojave.bottle.tar.gz + curl -L https://bintray.com/homebrew/bottles/download_file?file_path=sdl2_image-2.0.5.mojave.bottle.tar.gz -o sdl2_image-2.0.5.mojave.bottle.tar.gz + brew install -f sdl2_image-2.0.5.mojave.bottle.tar.gz + curl -L https://bintray.com/homebrew/bottles/download_file?file_path=freetype-2.10.1.mojave.bottle.tar.gz -o freetype-2.10.1.mojave.bottle.tar.gz + brew install -f freetype-2.10.1.mojave.bottle.tar.gz + - name: Prep Ubuntu + if: matrix.os == 'ubuntu-latest' + shell: bash + run: | + sudo apt-get -y update + #sudo apt-get -y upgrade + sudo apt-get -y install libpcap0.8-dev libfreetype6-dev libsdl2-dev libsdl2-image-dev + + - name: Build MacOS/Ubuntu + if: matrix.os != 'windows-latest' + #working-directory: ./ + run: | + echo "${{ matrix.os }} BUILD" + mkdir build ; cd build + cmake .. + make + pwd ; ls -al + shell: bash + # - name: Package NonWindows + # if: matrix.os != 'windows-latest' + # run: | + # zip --junk-paths merlin32.zip Source/merlin32 README.md + - name: Package MacOS + if: matrix.os == 'macos-latest' + run: cd build ; chmod +x ../scripts/package-osx.sh ; ../scripts/package-osx.sh + - name: Package Ubuntu + if: matrix.os == 'ubuntu-latest' + run: | + PACKAGE_DIR=gsplus-ubuntu-sdl + mkdir $PACKAGE_DIR + mkdir $PACKAGE_DIR/doc + cp build/src/GSplus $PACKAGE_DIR/gsplus + cp build/src/to_pro $PACKAGE_DIR/to_pro + cp src/assets/config.txt $PACKAGE_DIR + cp LICENSE.txt $PACKAGE_DIR/doc/ + cp doc/gsplusmanual.pdf $PACKAGE_DIR/doc/ + cp doc/README.txt $PACKAGE_DIR/doc/ + tar -cvjf gsplus-ubuntu-sdl.tar.bz2 $PACKAGE_DIR + - name: Upload Release Asset MacOSX + if: matrix.os == 'macos-latest' + #id: upload-release-asset + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.get_data.outputs.RELEASE_URL }} + asset_path: ./build/GSplus-Install.dmg + asset_name: ${{ format('GSplus-Install-{0}-{1}.dmg', matrix.os, steps.get_data.outputs.SOURCE_TAG ) }} + asset_content_type: application/x-apple-diskimage + - name: Upload Release Asset Ubuntu + if: matrix.os == 'ubuntu-latest' + #id: upload-release-asset + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.get_data.outputs.RELEASE_URL }} + asset_path: ./gsplus-ubuntu-sdl.tar.bz2 + asset_name: ${{ format('gsplus-ubuntu-sdl2-{0}.tar.bz2', steps.get_data.outputs.SOURCE_TAG ) }} + asset_content_type: application/x-bzip2 diff --git a/.gitignore b/.gitignore index d52c73c..a1abe3b 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,5 @@ images/ screens/ # build tools that are often kept/tested locally as well as on the ci machines +build/ yoursway-create-dmg/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ee2b5eb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.10) + +# set the project name and version +project(gsplus VERSION 0.15) + +add_subdirectory(src) + + + diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 33eb373..a145d24 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -1,6 +1,6 @@ GSPLUS - Advanced Apple IIGS Emulator Environment Based on the KEGS emulator written by Kent Dickey -Copyright (C) 2016 - 2018 Dagen Brock +Copyright (C) 2016 - 2020 Dagen Brock Copyright (C) 2010 - 2014 GSport contributors Copyright (C) 2003 Kent Dickey diff --git a/assets/Info.plist b/assets/Info.plist deleted file mode 100644 index e0b8c7a..0000000 --- a/assets/Info.plist +++ /dev/null @@ -1,33 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - gsplus - CFBundleGetInfoString - 0.14, Copyright 2018 Dagen Brock - CFBundleIconFile - gsp-icons.icns - CFBundleIdentifier - com.dagenbrock.gsplus - CFBundleDocumentTypes - - - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.14 - CFBundleSignature - gsplus - CFBundleVersion - 0.14 - NSHumanReadableCopyright - Copyright 2018 Dagen Brock - LSMinimumSystemVersion - 10.3 - - diff --git a/assets/control b/assets/control index 6f878f7..37f50b0 100644 --- a/assets/control +++ b/assets/control @@ -1,5 +1,5 @@ Package: gsplus -Version: 0.14-0 +Version: 0.15-0 Section: base Priority: optional Architecture: amd64 diff --git a/doc/Developer-QuickStart-MacOSX.txt b/doc/Developer-QuickStart-MacOSX.txt index b5e41c6..99f8257 100644 --- a/doc/Developer-QuickStart-MacOSX.txt +++ b/doc/Developer-QuickStart-MacOSX.txt @@ -23,3 +23,7 @@ git clone git@github.com:digarok/gsplus.git cd gsplus/src ln -s vars_osx_sdl2 vars make clean ; make + + +# Packaging +brew install dylibbundler diff --git a/make_dist_mac.sh b/make_dist_mac.sh deleted file mode 100755 index 502e993..0000000 --- a/make_dist_mac.sh +++ /dev/null @@ -1,20 +0,0 @@ -DEXTRAS=gsplus-osx/ -DDIR=$DEXTRAS/GSplus.app -ADIR=assets -mkdir -p $DEXTRAS/license -mkdir -p $DDIR/Contents/MacOS -mkdir -p $DDIR/Contents/Resources - -cp gsplus $DDIR/Contents/MacOS -cp config.txt $DDIR/Contents/MacOS -cp $ADIR/Info.plist $DDIR/Contents -cp $ADIR/gsp-icons.icns $DDIR/Contents/Resources -dylibbundler -od -b -x $DDIR/Contents/MacOS/gsplus -d $DDIR/Contents/libs/ - -# files to include in dmg -cp doc/gsplusmanual.pdf $DEXTRAS -cp doc/README.txt $DEXTRAS -cp LICENSE.txt $DEXTRAS/license -cp COPYRIGHT.txt $DEXTRAS/license - -# packaging now in DMG script diff --git a/make_dmg_mac.sh b/make_dmg_mac.sh deleted file mode 100755 index f0181bb..0000000 --- a/make_dmg_mac.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -git clone https://github.com/andreyvit/yoursway-create-dmg.git -cd yoursway-create-dmg - -test -f GSplus-Install.dmg && rm GSplus-Install.dmg -./create-dmg \ - --volname "GSplus" \ - --volicon "../assets/gsp-dmg-icons.icns" \ - --background "../assets/gsback.png" \ - --window-pos 200 120 \ - --window-size 710 600 \ - --icon-size 64 \ - --icon GSplus.app 250 210 \ - --hide-extension GSplus.app \ - --app-drop-link 440 210 \ - --icon README.txt 225 350 \ - --icon gsplusmanual.pdf 350 350 \ - --icon license 470 350 \ - GSplus-Install.dmg \ - ../gsplus-osx/ -cp GSplus-Install.dmg .. diff --git a/scripts/package-osx.sh b/scripts/package-osx.sh new file mode 100755 index 0000000..efc2708 --- /dev/null +++ b/scripts/package-osx.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# run me from `build` subdirectory + +# Create package directory and put any remaining files in place +PDIR=package-osx +rm -rf $PDIR #start empty +mkdir $PDIR +cp -r ../build/src/GSplus.app $PDIR + +DDIR=$PDIR/GSplus.app + +mkdir -p $PDIR/license +cp ../LICENSE.txt $PDIR/license +cp ../COPYRIGHT.txt $PDIR/license +cp ../doc/gsplusmanual.pdf $PDIR +cp ../doc/README.txt $PDIR + +# Bundle dynamic libraries +dylibbundler -od -b -x $DDIR/Contents/MacOS/gsplus -d $DDIR/Contents/libs/ + + + + + +# taken out DMG CI/CD for now as it requires keychain/UI interaction :( +#exit + +# Make DMG +git clone https://github.com/digarok/create-dmg.git +cd create-dmg + +test -f GSplus-Install.dmg && rm GSplus-Install.dmg +./create-dmg \ + --volname "GSplus" \ + --volicon "../../assets/gsp-dmg-icons.icns" \ + --background "../../assets/gsback.png" \ + --window-pos 200 120 \ + --window-size 710 600 \ + --icon-size 64 \ + --icon GSplus.app 250 210 \ + --hide-extension GSplus.app \ + --app-drop-link 440 210 \ + --icon README.txt 225 350 \ + --icon gsplusmanual.pdf 350 350 \ + --icon license 470 350 \ + --skip-jenkins \ + GSplus-Install.dmg \ + ../package-osx/ +mv GSplus-Install.dmg .. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..30e18f1 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,263 @@ + +INCLUDE (CheckFunctionExists) +INCLUDE (CheckLibraryExists) +INCLUDE (CheckTypeSize) +INCLUDE (CheckIncludeFile) +INCLUDE (CheckCSourceCompiles) + +INCLUDE (FindPkgConfig) +INCLUDE (TestBigEndian) + + +set(PACKAGE_NAME "GSplus") +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED TRUE) + +set(__MSVC__ ${MSVC}) +set(__CLANG__ FALSE) +set(__GCC__ FALSE) + +if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + set(__CLANG__ TRUE) +endif() + +if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + set(__GCC__ TRUE) +endif() + +if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) +endif() + +if(__CLANG__) + add_compile_options( + -Wall -fomit-frame-pointer + ) +endif() + + +if(__GCC__) + add_compile_options( + -Wall -fomit-frame-pointer + ) +endif() + + +TEST_BIG_ENDIAN(IS_BIG_ENDIAN) +if(NOT IS_BIG_ENDIAN) + add_definitions(-DGSPLUS_LITTLE_ENDIAN) +endif() + + +pkg_check_modules(SDL2 sdl2) +pkg_check_modules(FREETYPE2 freetype2) + + +find_program(PERL perl) + +if (PERL-NOTFOUND) + message(FATAL_ERROR "unable to find perl") +endif() + + +# +# run ccmake, cmake -LH, or cmake -D... +# +set(DRIVER "SDL" CACHE STRING "Driver (SDL, X11, WIN32, FB, or HEADLESS") +option(WITH_DEBUGGER "Enable the debugger" OFF) +option(WITH_HOST_FST "Enable host fst support" ON) +option(TOGGLE_STATUS "Enable F10 Toggle Status support (win32/x11)" OFF) +option(WITH_RAWNET "Enable Uthernet emulation" OFF) +option(WITH_ATBRIDGE "Enable AT Bridge" OFF) +option(WITH_BACKTRACE "Enable PC Backtracing" OFF) +option(WITH_STATIC "Enable static link" OFF) +set(READLINE "AUTO" CACHE STRING "Readline library (AUTO, NONE, READLINE, LIBEDIT)") + +set(CMAKE_REQUIRED_INCLUDES string.h) +check_function_exists(strcasecmp HAVE_STRCASECMP) +check_function_exists(strncasecmp HAVE_STRNCASECMP) +check_function_exists(strcasestr HAVE_STRCASESTR) + +configure_file(string_extra.h.in string_extra.h) +configure_file(version.h.in version.h) + +set(generated_headers 8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h size_c.h size_s.h 8size_s.h 16size_s.h) +add_custom_command( + OUTPUT 8inst_c.h 16inst_c.h 8inst_s.h ${CMAKE_CURRENT_BINARY_DIR}/16inst_s.h + COMMAND perl make_inst c 8 instable.h > ${CMAKE_CURRENT_BINARY_DIR}/8inst_c.h + COMMAND perl make_inst c 16 instable.h > ${CMAKE_CURRENT_BINARY_DIR}/16inst_c.h + COMMAND perl make_inst s 8 instable.h > ${CMAKE_CURRENT_BINARY_DIR}/8inst_s.h + COMMAND perl make_inst s 16 instable.h > ${CMAKE_CURRENT_BINARY_DIR}/16inst_s.h + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/instable.h + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + + +add_custom_command( + OUTPUT size_c.h size_s.h 8size_s.h 16size_s.h + COMMAND perl make_size c size_tab.h > ${CMAKE_CURRENT_BINARY_DIR}/size_c.h + COMMAND perl make_size s size_tab.h > ${CMAKE_CURRENT_BINARY_DIR}/size_s.h + COMMAND perl make_size 8 size_tab.h > ${CMAKE_CURRENT_BINARY_DIR}/8size_s.h + COMMAND perl make_size 16 size_tab.h > ${CMAKE_CURRENT_BINARY_DIR}/16size_s.h + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/size_tab.h + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + + +if (WITH_STATIC) + if(__CLANG__ OR __GCC__) + #add_link_options(-static) # 3.13 + link_libraries(-static) + endif() +endif() + + +add_executable(to_pro to_pro.c) +#add_executable(partls partls.c) + +add_subdirectory(atbridge) +#add_subdirectory(tfe) +add_subdirectory(rawnet) + +if (DRIVER MATCHES "SDL") + set(driver_code sdl2_driver.c sdl2snd_driver.c) +elseif(DRIVER MATCHES "X11") + set(driver_code xdriver.c) +elseif(DRIVER MATCHES "FB") + set(driver_code fbdriver.c) +elseif(DRIVER MATCHES "WIN32") + set(driver_code win32snd_driver.c win_console.c win_generic.c) +elseif(DRIVER MATCHES "HEADLESS") + set(driver_code headless_driver.c) +else() + message(FATAL_ERROR "Invalid driver ${DRIVER}") +endif() + +if (WIN32) + set(host_fst_code host_common.c host_mli.c win32_host_fst.c win32_host_common.c) +else() + set(host_fst_code host_common.c host_mli.c host_fst.c unix_host_common.c) +endif() + +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) + +# https://cmake.org/cmake/help/latest/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.html +set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_VERSION}, Copyright 2020 Dagen Brock") +set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2020 Dagen Brock") +set(MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION}) +set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) +set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) +set(MACOSX_BUNDLE_ICON_FILE gsp-icons.icns) +set(MACOSX_BUNDLE_GUI_IDENTIFIER com.dagenbrock.gsplus) + + +# https://cmake.org/Wiki/CMake:Bundles_And_Frameworks +# OS X properties. +add_executable(GSplus WIN32 MACOSX_BUNDLE + adb.c clock.c config.c engine_c.c scc.c iwm.c + joystick_driver.c moremem.c paddles.c parallel.c printer.cpp sim65816.c + smartport.c sound.c sound_driver.c video.c scc_socket_driver.c glog.c + imagewriter.cpp scc_imagewriter.c scc_llap.c options.c + + string_extra.c + dis.c + debug.c + #$<$:debug.c> + + $<$:${host_fst_code}> + ${driver_code} + ${generated_headers} + + + $<$:scc_windriver.c> + $<$:win32.rc> + $<$:assets/config.txt> + $<$:assets/gsp-icons.icns> + $<$:assets/GSBug.Templates> + $<$:assets/NList.Data> + $<$:fix_mac_menu.m> +) + + +SET_SOURCE_FILES_PROPERTIES( + assets/gsp-icons.icns + PROPERTIES + MACOSX_PACKAGE_LOCATION Resources +) + +SET_SOURCE_FILES_PROPERTIES( + assets/GSBug.Templates + assets/NList.Data + assets/config.txt + PROPERTIES + MACOSX_PACKAGE_LOCATION Resources +) + + +if(APPLE) + add_custom_command(TARGET GSplus POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${CMAKE_CURRENT_BINARY_DIR}/rawnet/vmnet_helper" + "${CMAKE_CURRENT_BINARY_DIR}/GSplus.app/Contents/MacOS/vmnet_helper" + ) + add_dependencies(GSplus vmnet_helper) +endif() +# SET_SOURCE_FILES_PROPERTIES(vmnet_helper PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + + +if (WITH_RAWNET) + target_link_libraries(GSplus rawnet) +endif() + +if (WITH_ATBRIDGE) + target_link_libraries(GSplus atbridge) +endif() + +if (WIN32) + target_link_libraries(GSplus comdlg32 Shlwapi IPHlpApi + winmm gdi32 dsound comctl32 ws2_32 shell32 + ) +endif() + +if (DRIVER MATCHES "SDL") + target_link_libraries(GSplus ${SDL2_LDFLAGS} ${FREETYPE2_LDFLAGS} SDL2_image) + target_compile_options(GSplus PUBLIC ${SDL2_CFLAGS} ${FREETYPE2_CFLAGS} -DHAVE_SDL) +endif() + +if (APPLE) + target_link_libraries(GSplus "-framework Cocoa") +endif() + +if (TOGGLE_STATUS) + target_compile_definitions(GSplus PUBLIC TOGGLE_STATUS) +endif() + +if (WITH_BACKTRACE) + target_compile_definitions(GSplus PUBLIC GSPLUS_BACKTRACE) +endif() + +if (WITH_DEBUGGER) + target_compile_definitions(GSplus PRIVATE GSPLUS_DEBUGGER) +endif() + + + +#if (APPLE AND DRIVER MATCHES "SDL") +# target_compile_options(GSplus PRIVATE -F${CMAKE_CURRENT_SOURCE_DIR} ) +# target_link_libraries(GSplus -F${CMAKE_CURRENT_SOURCE_DIR} "-framework SDL2" -Wl,-rpath,@executable_path/../Frameworks) +#endif() + + +if (APPLE) + add_custom_target(bundle + DEPENDS GSplus + COMMAND dylibbundler -od -b -x GSplus.app/Contents/MacOS/GSplus -d GSplus.app/Contents/libs + COMMENT bundling libraries... + ) + add_custom_target(setuid + COMMAND sudo chown root GSplus.app/Contents/MacOS/vmnet_helper + COMMAND sudo chmod +s GSplus.app/Contents/MacOS/vmnet_helper + USES_TERMINAL) + add_dependencies(setuid vmnet_helper) +endif() diff --git a/src/assets/GSBug.Templates b/src/assets/GSBug.Templates new file mode 100644 index 0000000..b1bba95 --- /dev/null +++ b/src/assets/GSBug.Templates @@ -0,0 +1,2556 @@ +; +; template: Template Master Index +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + + +_START Templates +ADB +AppleShareFST +Controls +Dialogs +Events +Fonts +GSOS +HighSierraFST +LineEdit +Lists +Locator +Menus +MiscTool +NoteSeq +NoteSyn +Print +ProDOS16 +ProDOSFST +QDAux +QuickDraw +Resources +SANE +Sound +StdFile +TextEdit +Windows +_END + +; +; template: Apple Desktop Bus Tool Set +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START ADB +ReadConfigRec +ScaleRec +SetConfigRec +SynchRec +_END + +_START ReadConfigRec +rcADBAddr BYTE +rcLayoutOrLang BYTE +rcRepeatDelay BYTE +_END + +_START SetConfigRec +scADBAddr BYTE +scLayoutOrLang BYTE +scRepeatDelay BYTE +_END + +_START SynchRec +synchMode BYTE +synchKybdMouseAddr BYTE +synchLayoutOrLang BYTE +synchRepeatDelay BYTE +_END + +_START ScaleRec +xDivide WORD +yDivide WORD +xOffset WORD +yOffset WORD +xMultiply WORD +yMultiply WORD +_END + + +; +; template: Control Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Controls +BarColors +BoxColors +BttnColors +CheckCtlRec +CtlRec +EditLineCtlRec +EditTextCtlRec +GrowCtlRec +IconButtonCtlRec +LimitBlk +ListCtlRec +PictureCtlRec +PopUpCtlRec +RadioColors +RadioCtlRec +ScrollCtlRec +SimpleButtonCtlRec +StatTextCtlRec +_END + +; generic extended control record +_START CtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +ctlReserved BYTE 16 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +; extended control records +_START SimpleButtonCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +keyEquiv +>key1 BYTE +>key2 BYTE +>keymodifiers WORD +>keyCareBits WORD +ctlReserved BYTE 10 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START CheckCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +keyEquiv +>key1 BYTE +>key2 BYTE +>keymodifiers WORD +>keyCareBits WORD +ctlReserved BYTE 10 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START IconButtonCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +keyEquiv +>key1 BYTE +>key2 BYTE +>keymodifiers WORD +>keyCareBits WORD +ctlReserved BYTE 10 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +iconRef LONG +displayMode WORD +_END + +_START EditLineCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +ctlReserved BYTE 16 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START ListCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +ctlMemDraw LONG +ctlMemHeight WORD +ctlMemSize WORD +ctlListRef LONG +ctlListBar LONG +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START PictureCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +ctlReserved BYTE 16 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START PopUpCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +menuRef LONG +menuEnd LONG +popUpRect WORD 4 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +titleWidth WORD +_END + +_START RadioCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +keyEquiv +>key1 BYTE +>key2 BYTE +>keymodifiers WORD +>keyCareBits WORD +ctlReserved BYTE 10 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START ScrollCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +thumbRect WORD 4 +pageRegion WORD 4 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START GrowCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +ctlReserved BYTE 16 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START StatTextCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +ctlJust WORD +ctlReserved BYTE 14 +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +_END + +_START EditTextCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +textFlags LONG +textLength LONG +blockList +>cachedHandle LONG +>cachedOffset LONG +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +viewRect WORD 4 +totalHeight LONG +lineSuper +>cachedHandle LONG +>cachedOffset LONG +>cachedIndex WORD +>itemsPerBlock WORD +styleSuper +>cachedHandle LONG +>cachedOffset LONG +>cachedIndex WORD +>itemsPerBlock WORD +styleList LONG +rulerList LONG +lineAtEndFlag WORD +selectionStart LONG +selectionEnd LONG +selectionActive WORD +selectionState WORD +caretTime LONG +nullStyleActive WORD +nullStyle +>fontID LONG +>foreColor WORD +>backColor WORD +>userData LONG +topTextOffset LONG +topTextVPos WORD +vertScrollBar LONG +vertScrollPos LONG +vertScrollMax LONG +vertScrollAmount WORD +horzScrollBar LONG +horzScrollPos LONG +horxScrollMax LONG +horzScrollAmount WORD +growBoxHandle LONG +maximumChars LONG +maximumLines LONG +maxCharsPerLine WORD +maximumHeight WORD +textDrawMode WORD +wordBreakHook LONG +wordWrapHook LONG +keyFilter LONG +theFilterRect WORD 4 +theBufferVPos WORD +theBufferHPos WORD +theKeyRecord +>theChar WORD +>theModifiers WORD +>theInputHandle LONG +>cursorOffset LONG +>theOpcode WORD +cachedSelcOffset LONG +cachedSelcVPos WORD +cachedSelcHPos WORD +mouseRect WORD 4 +mouseTime LONG +mouseKind WORD +lastClick WORD 2 +savedHPos WORD +anchorPoint LONG +_END + +_START BarColors +barOutline WORD +barNorArrow WORD +barSelArrow WORD +barArrowBack WORD +barNorThumb WORD +barSelThumb WORD +barPageRgn WORD +barInactive WORD +_END + +_START BoxColors +boxReserved WORD +boxNor WORD +boxSel WORD +boxTitle WORD +_END + +_START BttnColors +bttnOutline WORD +bttnNorBack WORD +bttnSelBack WORD +bttnNorText WORD +bttnSelText WORD +_END + +_START LimitBlk +boundRect WORD 4 +slopRect WORD 4 +axisParam WORD +dragPatt LONG +_END + +_START RadioColors +radReserved WORD +radNor WORD +radSel WORD +radTitle WORD +_END + + +; +; template: Dialog Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Dialogs +AlertTemplate +DialogTemplate +ItemTemplate +UserCtlItemPB +_END + +_START AlertTemplate +atBoundsRect WORD 4 +atAlertID WORD +atStage1 BYTE +atStage2 BYTE +atStage3 BYTE +atStage4 BYTE +atItemList LONG +_END + +_START DialogTemplate +dtBoundsRect WORD 4 +dtVisible WORD +dtRefCon LONG +dtItemList LONG +_END + +_START ItemTemplate +itemID WORD +itemRect WORD 4 +itemType WORD +itemDescr LONG +itemValue WORD +itemFlag WORD +itemColor LONG +_END + +_START UserCtlItemPB +defProcParm LONG +titleParm LONG +param1 WORD +param2 WORD +_END + + +; +; template: Event Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Events +EventRecord +_END + +_START EventRecord +what WORD +message LONG +when LONG +where WORD 2 +modifiers WORD +_END + + +; +; template: Font Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Fonts +FontID +FontStatRec +_END + +_START FontID +famNum WORD +fontStyle BYTE +fontSize BYTE +_END + +_START FontStatRec +resultID +>famNum WORD +>fontStyle BYTE +>fontSize BYTE +resultStats WORD +_END + + +; +; template: LineEdit Tool Set +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START LineEdit +LERec +_END + +_START LERec +leLineHandle LONG +leLength WORD +leMaxLength WORD +leDestRect WORD 4 +leViewRect WORD 4 +lePort LONG +leLineHite WORD +leBaseHite WORD +leSelStart WORD +leSelEnd WORD +leActFlg WORD +leCarAct WORD +leCarOn WORD +leCarTime LONG +leHiliteHook LONG +leCaretHook LONG +leJust WORD +lePWChar WORD +_END + + +; +; template: List Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Lists +LColorTable +ListRec +MemRec +_END + +_START ListRec +listRect WORD 4 +listSize WORD +listView WORD +listType WORD +listStart WORD +listCtl LONG +listDraw LONG +listMemHeight WORD +listMemSize WORD +listPointer LONG +listRefCon LONG +listScrollClr LONG +_END + +; ListCtlRec can be found in the Control Manager templates. + +_START MemRec +memPtr LONG +memFlag BYTE +_END + +_START LColorTable +listFrameClr WORD +listNorTextClr WORD +listSelTextClr WORD +listNorBackClr WORD +listSelBackClr WORD +_END + + +; +; template: Menu Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Menus +Menu +MenuBarTemplate +MenuItemTemplate +MenuTemplate +_END + +_START Menu +menuID WORD +menuWidth WORD +menuHeight WORD +menuProc LONG +menuFlag BYTE +menuRes BYTE +firstItem BYTE +numOfItems BYTE +titleWidth WORD +titleName LONG +menuCache LONG +_END + +_START MenuItemTemplate +version WORD +itemID WORD +itemChar BYTE +itemAltChar BYTE +itemCheck WORD +itemFlag WORD +itemTitleRef LONG +_END + +_START MenuTemplate +version WORD +menuID WORD +menuFlag WORD +menuTitleRef LONG +itemRefArray LONG +_END + +_START MenuBarTemplate +version WORD +menuBarFlag WORD +menuRefArray LONG +_END + + +; +; template: Miscellaneous Tool Set +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START MiscTool +ClampRec +FWRec +InterruptStateRec +MouseRec +QueueHeader +TimeRec +_END + +_START QueueHeader +reserved LONG +reserved WORD +signature WORD +_END + +_START InterruptStateRec +irq_A WORD +irq_X WORD +irq_Y WORD +irq_S WORD +irq_D WORD +irq_P BYTE +irq_DB BYTE +irq_e BYTE +irq_K BYTE +irq_PC WORD +irq_state BYTE +irq_shadow WORD +irq_mslot BYTE +_END + +_START TimeRec +second BYTE +minute BYTE +hour BYTE +year BYTE +day BYTE +month BYTE +extra BYTE +weekday BYTE +_END + +_START MouseRec +mouseMode BYTE +mouseStatus BYTE +yPos WORD +xPos WORD +_END + +_START ClampRec +yMaxClamp WORD +yMinClamp WORD +xMaxClamp WORD +xMinClamp WORD +_END + +_START FWRec +yRegExit WORD +xRegExit WORD +aRegExit WORD +status WORD +_END + + +; +; template: Note Sequencer +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START NoteSeq +InstTable +_END + +_START InstTable +instNumber WORD +instArray LONG +_END + + +; +; template: Note Synthesizer +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START NoteSyn +Envelope +GCBRecord +Instrument +WaveEntry +_END + +_START Envelope +breakpoint0 BYTE +increment0 WORD +breakpoint1 BYTE +increment1 WORD +breakpoint2 BYTE +increment2 WORD +breakpoint3 BYTE +increment3 WORD +breakpoint4 BYTE +increment4 WORD +breakpoint5 BYTE +increment5 WORD +breakpoint6 BYTE +increment6 WORD +breakpoint7 BYTE +increment7 WORD +_END + +_START Instrument +envelope +>breakpoint0 BYTE +>increment0 WORD +>breakpoint1 BYTE +>increment1 WORD +>breakpoint2 BYTE +>increment2 WORD +>breakpoint3 BYTE +>increment3 WORD +>breakpoint4 BYTE +>increment4 WORD +>breakpoint5 BYTE +>increment5 WORD +>breakpoint6 BYTE +>increment6 WORD +>breakpoint7 BYTE +>increment7 WORD +releaseSegment BYTE +priorityIncrement BYTE +pitchBendRange BYTE +vibratoDepth BYTE +vibratoSpeed BYTE +inSpare BYTE +aWaveCount BYTE +bWaveCount BYTE +aWaveList... +bWaveList... +_END + +_START WaveEntry +topKey BYTE +waveAddress BYTE +waveSize BYTE +DOCMode BYTE +relPitch WORD +_END + +_START GCBRecord +synthID BYTE +genNum BYTE +semiTone BYTE +volume BYTE +pitchbend BYTE +vibratoDepth BYTE +reserved BYTE 10 +_END + + +; +; template: Print Manager +; 7/7/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Print +PrInfoRec +PrJobRec +PrRec +PrStatusRec +PrStyleRec +_END + +_START PrRec +prVersion WORD +prInfo +>iDev WORD +>iVRes WORD +>iHRes WORD +>rPage WORD 4 +rPaper WORD 4 +prStl +>wDev WORD +>internA WORD 3 +>feed WORD +>paperType WORD +>crWidth WORD +>reduction WORD +>internB WORD +prInfoPT BYTE 14 +prXInfo BYTE 24 +prJob +>iFstPage WORD +>iLstPage WORD +>iCopies WORD +>bJDocLoop BYTE +>fFromUser BYTE +>pIdleProc LONG +>pFileName LONG +>iFileVol WORD +>bFileVers BYTE +>bJobX BYTE +printX BYTE 38 +iReserved WORD +_END + +_START PrInfoRec +iDev WORD +iVRes WORD +iHRes WORD +rPage WORD 4 +_END + +_START PrStyleRec +wDev WORD +internA WORD 3 +feed WORD +paperType WORD +crWidth WORD +reduction WORD +internB WORD +_END + +_START PrJobRec +iFstPage WORD +iLstPage WORD +iCopies WORD +bJDocLoop BYTE +fFromUser BYTE +pIdleProc LONG +pFileName LONG +iFileVol WORD +bFileVers BYTE +bJobX BYTE +_END + +_START PrStatusRec +iTotPages WORD +iCurPage WORD +iTotCopies WORD +iCurCopy WORD +iTotBands WORD +iCurBand WORD +iPgDirty WORD +fImaging WORD +hPrint LONG +pPrPort LONG +hPic LONG +_END + + +; +; template: QuickDraw II +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START QuickDraw +BufDimRec +Font +FontGlobalsRecord +FontInfoRecord +GrafPort +LocInfo +PaintParam +PenStateRecord +ROMFontRecord +_END + +_START BufDimRec +buffer_sizing_record +maxWidth WORD +textBufHeight WORD +textBufferWords WORD +fontWidth WORD +_END + +_START Font +font_record +offseToMF WORD +family WORD +style WORD +size WORD +version WORD +fbrExtent WORD +highowTLoc WORD +_END + +_START FontGlobalsRecord +fgFontID WORD +fgStyle WORD +fgSize WORD +fgVersion WORD +fgWidMax WORD +fgFBRExtent WORD +_END + +_START FontInfoRecord +ascent WORD +descent WORD +widMax WORD +leading WORD +_END + +_START GrafPort +portInfo +>portSCB WORD +>ptrToPixImage LONG +>width WORD +>boundsRect WORD 4 +portRect WORD 4 +clipRgn LONG +visRgn LONG +bkPat BYTE 32 +pnLoc WORD 2 +pnSize WORD 2 +pnMode WORD +pnPat BYTE 32 +pnMask BYTE 8 +pnVis WORD +fontHandle LONG +fontID LONG +fontFlags WORD +txSize WORD +txFace WORD +txMode WORD +spExtra LONG +chExtra LONG +fgColor WORD +bgColor WORD +picSave LONG +rgnSave LONG +polySave LONG +grafProcs LONG +arcRot WORD +userField LONG +sysField LONG +_END + +_START LocInfo +portSCB WORD +ptrToPixImage LONG +width WORD +boundsRect WORD 4 +_END + +_START PaintParam +PaintPixels_parameter_block +ptrToSourceLocInfo LONG +ptrToDestLocInfo LONG +ptrToSourceRect LONG +ptrToDestPoint LONG +mode WORD +maskHandle LONG +_END + +_START PenStateRecord +psPenLoc WORD 2 +psPnSize WORD 2 +psPnMode WORD +psPnPat BYTE 32 +psPnMask BYTE 8 +_END + +_START ROMFontRecord +rfFamNum WORD +rfFamStyle WORD +rfSize WORD +rfFontHandle LONG +rfNamePtr LONG +rfFBRExtent WORD +_END + +; +; template: QuickDraw II Auxiliary +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START QDAux +IconRecord +_END + +_START IconRecord +iconType WORD +iconSize WORD +iconHeight WORD +iconWidth WORD +image/mask +_END + + +; +; template: SANE +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START SANE +HaltDPage +_END + +_START HaltDPage +returnAddrs BYTE 6 +callerDpage WORD +callerDB WORD +opword WORD +cAddress LONG +bAddress LONG +aAddress LONG +haltVector LONG +environment WORD +pendingExceptions WORD +pendingXlo BYTE +pendingXhiYlo BYTE +pendingYhi BYTE +_END + + +; +; template: Resource Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Resources +FreeBlockRec +MapRec +ResHeaderRec +ResRefRec +_END + +_START ResHeaderRec +rFileVersion LONG +rFileToMap LONG +rFileMapSize LONG +rFileMemo BYTE 128 +_END + +_START MapRec +mapNext LONG +mapFlag WORD +mapOffset LONG +mapSize LONG +mapToIndex WORD +mapFileNum WORD +mapID WORD +mapIndexSize LONG +mapIndexUsed LONG +mapFreeListSize WORD +mapFreeListUsed WORD +mapFreeList/Index +_END + +_START FreeBlockRec +blkOffset LONG +blkSize LONG +_END + +_START ResRefRec +resType WORD +resID LONG +resOffset LONG +resAttr WORD +resSize LONG +resHandle LONG +_END + + +; +; template: Sound Tool Set +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Sound +DOCRegParamBlock +SoundParamBlock +_END + +_START SoundParamBlock +waveStart LONG +waveSize WORD +freqOffset WORD +docBuffer WORD +bufferSize WORD +nextWavePtr LONG +volSetting WORD +_END + +_START DOCRegParamBlock +oscGenTYpe WORD +freqLow1 BYTE +freqHigh1 BYTE +vol1 BYTE +tablePtr1 BYTE +control1 BYTE +tableSize1 BYTE +freqLow2 BYTE +freqHigh2 BYTE +vol2 BYTE +tablePtr2 BYTE +control2 BYTE +tableSize2 BYTE +_END + + +; +; template: Standard File Operations Tool Set +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START StdFile +ReplyRecord +ReplyRecord2 +_END + +_START ReplyRecord +good WORD +fileType WORD +auxFileType WORD +fileName BYTE 16 +fullPathname BYTE 129 +_END + +_START ReplyRecord2 +good WORD +type WORD +auxType LONG +nameRefDesc WORD +nameRef LONG +pathRefDesc WORD +pathRef LONG +_END + + +; +; template: Text Edit +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START TextEdit +KeyRecord +StyleItem +SuperBlock +SuperHandle +SuperItem +TabItem +TEColorTable +TEFormat +TEParamBlock +TERecord +TERuler +TEStyle +TextBlock +TextList +_END + +_START TEColorTable +contentColor WORD +outlineColor WORD +vertColorDescriptor WORD +vertColorRef LONG +horzColorDescriptor WORD +horzColorRef LONG +growColorDescriptor WORD +growColorRef LONG +_END + +_START TEFormat +version WORD +rulerListLength LONG +theRulerList +styleListLength +theStyleList +numberOfStyles +theStyles +_END + +_START TEParamBlock +pCount WORD +ID LONG +rect WORD 4 +procRef LONG +flags WORD +moreFlags WORD +refCon LONG +textFlags LONG +indentRect WORD 4 +vertBar LONG +vertAmount WORD +horzBar LONG +horzAmount WORD +styleRef LONG +textDescriptor WORD +textRef LONG +textLength LONG +maxChars LONG +maxLines LONG +maxCharsPerLine WORD +maxHeight WORD +colorRef LONG +drawMode WORD +filterProc LONG +_END + +_START TERecord +; same as EditTextCtlRec +ctlNext LONG +ctlOwner LONG +ctlRect WORD 4 +ctlFlag BYTE +ctlHilite BYTE +ctlValue WORD +ctlProc LONG +ctlAction LONG +ctlData LONG +ctlRefCon LONG +ctlColor LONG +textFlags LONG +textLength LONG +blockList +>cachedHandle LONG +>cachedOffset LONG +ctlID LONG +ctlMoreFlags WORD +ctlVersion WORD +viewRect WORD 4 +totalHeight LONG +lineSuper +>cachedHandle LONG +>cachedOffset LONG +>cachedIndex WORD +>itemsPerBlock WORD +styleSuper +>cachedHandle LONG +>cachedOffset LONG +>cachedIndex WORD +>itemsPerBlock WORD +styleList LONG +rulerList LONG +lineAtEndFlag WORD +selectionStart LONG +selectionEnd LONG +selectionActive WORD +selectionState WORD +caretTime LONG +nullStyleActive WORD +nullStyle +>fontID LONG +>foreColor WORD +>backColor WORD +>userData LONG +topTextOffset LONG +topTextVPos WORD +vertScrollBar LONG +vertScrollPos LONG +vertScrollMax LONG +vertScrollAmount WORD +horzScrollBar LONG +horzScrollPos LONG +horxScrollMax LONG +horzScrollAmount WORD +growBoxHandle LONG +maximumChars LONG +maximumLines LONG +maxCharsPerLine WORD +maximumHeight WORD +textDrawMode WORD +wordBreakHook LONG +wordWrapHook LONG +keyFilter LONG +theFilterRect WORD 4 +theBufferVPos WORD +theBufferHPos WORD +theKeyRecord +>theChar WORD +>theModifiers WORD +>theInputHandle LONG +>cursorOffset LONG +>theOpcode WORD +cachedSelcOffset LONG +cachedSelcVPos WORD +cachedSelcHPos WORD +mouseRect WORD 4 +mouseTime LONG +mouseKind WORD +lastClick WORD 2 +savedHPos WORD +anchorPoint LONG +_END + +_START TERuler +leftMargin WORD +leftIndent WORD +rightMargin WORD +just WORD +extraLS WORD +flags WORD +userData LONG +tabType WORD +theTabs +tabTerminator +_END + +_START TEStyle +fontID LONG +foreColor WORD +backColor WORD +userData LONG +_END + +_START KeyRecord +theChar WORD +theModifiers WORD +theInputHandle LONG +cursorOffset LONG +theOpCode WORD +_END + +_START StyleItem +length LONG +offset LONG +_END + +_START SuperBlock +nextHandle LONG +prevHandle LONG +textLength LONG +reserved LONG +theItems +_END + +_START SuperHandle +cachedHandle LONG +cachedOffset LONG +cachedIndex WORD +itemsPerBlock WORD +_END + +_START SuperItem +length LONG +data LONG +_END + +_START TabItem +tabKind WORD +tabData WORD +_END + +_START TextBlock +nextHandle LONG +prevHandle LONG +textLength LONG +flags WORD +reserved WORD +theText +_END + +_START TextList +cachedHandle LONG +cachedOffset LONG +_END + + +; +; template: Tool Locator +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Locator +StartStopRec +ToolSpec +ToolTable +_END + +_START ToolTable +numTools WORD +toolArray +>toolNumber1 WORD +>minVersion1 WORD +>toolNumber2 WORD +>minVersion2 WORD +>toolNumber3 WORD +>minVersion3 WORD +>toolNumber4 WORD +>minVersion4 WORD +>toolNumber5 WORD +>minVersion5 WORD +>toolNumber6 WORD +>minVersion6 WORD +>toolNumber7 WORD +>minVersion7 WORD +>toolNumber8 WORD +>minVersion8 WORD +>toolNumber9 WORD +>minVersion9 WORD +>toolNumber10 WORD +>minVersion10 WORD +>toolNumber11 WORD +>minVersion11 WORD +>toolNumber12 WORD +>minVersion12 WORD +>toolNumber13 WORD +>minVersion13 WORD +>toolNumber14 WORD +>minVersion14 WORD +>toolNumber15 WORD +>minVersion15 WORD +>toolNumber16 WORD +>minVersion16 WORD +>toolNumber17 WORD +>minVersion17 WORD +>toolNumber18 WORD +>minVersion18 WORD +>toolNumber19 WORD +>minVersion19 WORD +>toolNumber20 WORD +>minVersion20 WORD +>toolNumber21 WORD +>minVersion21 WORD +>toolNumber22 WORD +>minVersion22 WORD +>toolNumber23 WORD +>minVersion23 WORD +>toolNumber24 WORD +>minVersion24 WORD +>toolNumber25 WORD +>minVersion25 WORD +>toolNumber26 WORD +>minVersion26 WORD +>toolNumber27 WORD +>minVersion27 WORD +>toolNumber28 WORD +>minVersion28 WORD +>toolNumber29 WORD +>minVersion29 WORD +>toolNumber30 WORD +>minVersion30 WORD +>toolNumber31 WORD +>minVersion31 WORD +>toolNumber32 WORD +>minVersion32 WORD +>toolNumber33 WORD +>minVersion33 WORD +>toolNumber34 WORD +>minVersion34 WORD +>toolNumber35 WORD +>minVersion35 WORD +>toolNumber36 WORD +>minVersion36 WORD +>toolNumber37 WORD +>minVersion37 WORD +>toolNumber38 WORD +>minVersion38 WORD +>toolNumber39 WORD +>minVersion39 WORD +>toolNumber40 WORD +>minVersion40 WORD +_END + +_START StartStopRec +flags WORD +videoMode WORD +resFileID WORD +dPageHandle LONG +numTools WORD +toolArray +>toolNumber1 WORD +>minVersion1 WORD +>toolNumber2 WORD +>minVersion2 WORD +>toolNumber3 WORD +>minVersion3 WORD +>toolNumber4 WORD +>minVersion4 WORD +>toolNumber5 WORD +>minVersion5 WORD +>toolNumber6 WORD +>minVersion6 WORD +>toolNumber7 WORD +>minVersion7 WORD +>toolNumber8 WORD +>minVersion8 WORD +>toolNumber9 WORD +>minVersion9 WORD +>toolNumber10 WORD +>minVersion10 WORD +>toolNumber11 WORD +>minVersion11 WORD +>toolNumber12 WORD +>minVersion12 WORD +>toolNumber13 WORD +>minVersion13 WORD +>toolNumber14 WORD +>minVersion14 WORD +>toolNumber15 WORD +>minVersion15 WORD +>toolNumber16 WORD +>minVersion16 WORD +>toolNumber17 WORD +>minVersion17 WORD +>toolNumber18 WORD +>minVersion18 WORD +>toolNumber19 WORD +>minVersion19 WORD +>toolNumber20 WORD +>minVersion20 WORD +>toolNumber21 WORD +>minVersion21 WORD +>toolNumber22 WORD +>minVersion22 WORD +>toolNumber23 WORD +>minVersion23 WORD +>toolNumber24 WORD +>minVersion24 WORD +>toolNumber25 WORD +>minVersion25 WORD +>toolNumber26 WORD +>minVersion26 WORD +>toolNumber27 WORD +>minVersion27 WORD +>toolNumber28 WORD +>minVersion28 WORD +>toolNumber29 WORD +>minVersion29 WORD +>toolNumber30 WORD +>minVersion30 WORD +>toolNumber31 WORD +>minVersion31 WORD +>toolNumber32 WORD +>minVersion32 WORD +>toolNumber33 WORD +>minVersion33 WORD +>toolNumber34 WORD +>minVersion34 WORD +>toolNumber35 WORD +>minVersion35 WORD +>toolNumber36 WORD +>minVersion36 WORD +>toolNumber37 WORD +>minVersion37 WORD +>toolNumber38 WORD +>minVersion38 WORD +>toolNumber39 WORD +>minVersion39 WORD +>toolNumber40 WORD +>minVersion40 WORD +_END + +_START ToolSpec +toolNumber WORD +minVersion WORD +_END + + +; +; template: Window Manager +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START Windows +Paramlist +WindColor +WindRec +WmTaskRec +_END + +_START WindRec +wNext LONG +port +>portInfo +>>portSCB WORD +>>ptrToPixImage LONG +>>width WORD +>>boundsRect WORD 4 +>portRect WORD 4 +>clipRgn LONG +>visRgn LONG +>bkPat BYTE 32 +>pnLoc WORD 2 +>pnSize WORD 2 +>pnMode WORD +>pnPat BYTE 32 +>pnMask BYTE 8 +>pnVis WORD +>fontHandle LONG +>fontID LONG +>fontFlags WORD +>txSize WORD +>txFace WORD +>txMode WORD +>spExtra LONG +>chExtra LONG +>fgColor WORD +>bgColor WORD +>picSave LONG +>rgnSave LONG +>polySave LONG +>grafProcs LONG +>arcRot WORD +>userField LONG +>sysField LONG +wDefProc LONG +wRefCon LONG +wContDraw LONG +wReserved LONG +wStrucRgn LONG +wContRgn LONG +wUpdateRgn LONG +wControls LONG +wFrameCtrls LONG +wFrame WORD +wCustom +_END + +_START WindColor +frameColor WORD +titleColor WORD +tBarColor WORD +growColor WORD +infoColor WORD +_END + +_START Paramlist +paramLength WORD +wFrameBits WORD +wTitle LONG +wRefCon LONG +wZoom WORD 4 +wColor LONG +wYOrigin WORD +wXOrigin WORD +wDataH WORD +wDataW WORD +wMaxH WORD +wMaxW WORD +wScrollVer WORD +wScrollHor WORD +wPageVer WORD +wPageHor WORD +wInfoRefCon LONG +wInfoHeight WORD +wFrameDefProc LONG +wInfoDefProc LONG +wContDefProc LONG +wPosition WORD 4 +wPlane LONG +wStorage LONG +_END + +_START WmTaskRec +wmWhat WORD +wmMessage LONG +wmWhen LONG +wmWhere LONG +wmModifiers WORD +wmTaskData LONG +wmTaskMask LONG +wmLastClickTick LONG +wmClickCount WORD +wmTaskData2 LONG +wmTaskData3 LONG +wmTaskData4 LONG +wmLastClickPt WORD 2 +_END + + +; +; template: GS/OS +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START GSOS +ChangePathRecGS +CreateRecGS +DAccessRecGS +DevNumRecGS +DInfoRecGS +DIORecGS +DirEntryRecGS +DRenameRecGS +EOFRecGS +ExpandPathRecGS +FileInfoRecGS +FormatRecGS +FSTInfoRecGS +GetNameRecGS +InterruptRecGS +IORecGS +LevelRecGS +NameRecGS +NewLineRecGS +NotifyProcRecGS +OpenRecGS +OSShutdownRecGS +PositionRecGS +PrefixRecGS +QuitRecGS +RefInfoRecGS +RefNumRecGS +SessionStatusRecGS +SetPositionRecGS +SetPrefixRecGS +StdRefNumRecGS +SysPrefsRecGS +VersionRecGS +VolumeRecGS +_END + +_START ChangePathRecGS +pCount WORD +pathname GSSTRING +newPathname GSSTRING +_END + +_START CreateRecGS +pCount WORD +pathname GSSTRING +access WORD +fileType WORD +auxType LONG +storageType WORD +eof LONG +resourceEOF LONG +_END + +_START DAccessRecGS +pCount WORD +devNum WORD +code WORD +list LONG +requestCount LONG +transferCount LONG +_END + +_START DevNumRecGS +pCount WORD +devName GSSTRING +devNum WORD +_END + +_START DInfoRecGS +pCount WORD +devNum WORD +devName LONG +characteristics WORD +totalBlocks LONG +slotNum WORD +unitNum WORD +version WORD +deviceID WORD +headLink WORD +forwardLink WORD +extenededDIBPtr LONG +_END + +_START DIORecGS +pCount WORD +devNum WORD +buffer LONG +requestCount LONG +startingBlock LONG +blockSize WORD +transferCount LONG +_END + +_START DirEntryRecGS +pCount WORD +refNum WORD +flags WORD +base WORD +displacement WORD +name LONG +entryNum WORD +fileType WORD +eof LONG +blockCount LONG +createDateTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +modDateTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +access WORD +auxType LONG +fileSysID WORD +optionList LONG +resourceEOF LONG +resourceBlocks LONG +_END + +_START DRenameRecGS +pCount WORD +devNum WORD +strPtr GSSTRING +_END + +_START ExpandPathRecGS +pCount WORD +inputPath GSSTRING +outputPath LONG +flags WORD +_END + +_START FileInfoRecGS +pCount WORD +pathname GSSTRING +fileType WORD +auxType LONG +storageType WORD +createDateTime +modDateTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +optionList LONG +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +eof LONG +blocksUsed LONG +resourceEOF LONG +resourceBlocks LONG +_END + +_START FormatRecGS +pCount WORD +devName GSSTRING +volName GSSTRING +fileSysID WORD +reqFileSysID WORD +_END + +_START FSTInfoRecGS +pCount WORD +fstNum WORD +fileSysID WORD +fstName LONG +version WORD +attributes WORD +blockSize WORD +maxVolSize LONG +maxFileSize LONG +_END + +_START InterruptRecGS +pCount WORD +intNum WORD +vrn WORD +intCode LONG +_END + +_START IORecGS +pCount WORD +refNum WORD +dataBuffer LONG +requestCount LONG +transferCount LONG +cachePriority WORD +_END + +_START LevelRecGS +pCount WORD +level WORD +_END + +_START NameRecGS +pCount WORD +pathname GSSTRING +_END + +_START NotifyProcRecGS +pCount WORD +procPointer LONG +_END + +_START GetNameRecGS +pCount WORD +pathname LONG +_END + +_START NewLineRecGS +pCount WORD +refNum WORD +enableMask WORD +numChars WORD +newlineTable LONG +_END + +_START OpenRecGS +pCount WORD +refNum WORD +pathname GSSTRING +requestAccess WORD +access WORD +fileType WORD +auxType LONG +storageType WORD +createDateTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +modDateTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +optionList LONG +eof LONG +blocksUsed LONG +resourceEOF LONG +resourceBlocks LONG +_END + +_START OSShutdownRecGS +pCount WORD +shutdownFlag WORD +_END + +_START PositionRecGS +pCount WORD +reNum WORD +position LONG +_END + +_START EOFRecGS +pCount WORD +reNum WORD +eof LONG +_END + +_START PrefixRecGS +pCount WORD +prefixNum WORD +prefixPtr LONG +_END + +_START SetPrefixRecGS +pCount WORD +prefixNum WORD +prefixPtr GSSTRING +_END + +_START QuitRecGS +pCount WORD +pathname GSSTRING +flags WORD +_END + +_START RefNumRecGS +pCount WORD +pathname GSSTRING +refNum WORD +access WORD +resNum WORD +caseSense WORD +displacement WORD +_END + +_START StdRefNumRecGS +pCount WORD +prefixNum WORD +refNum WORD +_END + +_START SessionStatusRecGS +pCount WORD +status WORD +_END + +_START SetPositionRecGS +pCount WORD +refNum WORD +base WORD +displacement LONG +_END + +_START SysPrefsRecGS +pCount WORD +preferences WORD +_END + +_START VersionRecGS +pCount WORD +version WORD +_END + +_START VolumeRecGS +pCount WORD +devName GSSTRING +volName LONG +totalBlocks LONG +freeBlocks LONG +fileSysID WORD +blockSize WORD +_END + +_START RefInfoRecGS +pCount WORD +refNum WORD +access WORD +pathname LONG +_END + + +; +; template: AppleShare FST +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START AppleShareFST +ASOptionListRec +BufferControlRec +ByteRangeLockRec +CopyFileRec +DesktopRec +GetCommentRec +GetPrivilegesRec +GetServerNameRec +GetUserPathRec +SetCommentRec +SetPrivilegesRec +SpecialOpenForkRec +UserInfoRec +_END + +_START BufferControlRec +pCount WORD +fstNum WORD +commandNum WORD +refNum WORD +flags WORD +_END + +_START SpecialOpenForkRec +pCount WORD +fstNum WORD +commandNum WORD +pathname LONG +accessMode WORD +forkNum WORD +_END + +_START ByteRangeLockRec +pCount WORD +fstNum WORD +commandNum WORD +refNum WORD +lockFlag WORD +fileOffset LONG +rangeLength LONG +rangeStart LONG +_END + +_START GetPrivilegesRec +pCount WORD +fstNum WORD +commandNum WORD +pathname LONG +accessRights +>reserved BYTE +>world BYTE +>group BYTE +>owner BYTE +ownerName LONG +groupName LONG +_END + +_START SetPrivilegesRec +pCount WORD +fstNum WORD +commandNum WORD +pathname LONG +accessRights +>userSummary BYTE +>world BYTE +>group BYTE +>owner BYTE +ownerName LONG +groupName LONG +_END + +_START UserInfoRec +pCount WORD +fstNum WORD +commandNum WORD +deviceNum WORD +userName LONG +primaryGroupName LONG +_END + +_START CopyFileRec +pCount WORD +fstNum WORD +commandNum WORD +sourcePathname LONG +destPathname LONG +_END + +_START GetUserPathRec +pCount WORD +fstNum WORD +commandNum WORD +prefix LONG +_END + +_START DesktopRec +pCount WORD +fstNum WORD +commandNum WORD +desktopRefNum WORD +pathname LONG +_END + +_START GetCommentRec +pCount WORD +fstNum WORD +commandNum WORD +desktopRefNum WORD +pathname LONG +comment LONG +_END + +_START SetCommentRec +pCount WORD +fstNum WORD +commandNum WORD +desktopRefNum WORD +pathname LONG +comment LONG +_END + +_START GetServerNameRec +pCount WORD +fstNum WORD +commandNum WORD +pathname LONG +serverName LONG +zoneName LONG +_END + +_START ASOptionListRec +bufferSize WORD +dataSize WORD +theFileSysID WORD +finderInfo BYTE 32 +parentDirID LONG +accessRights LONG +_END + + +; +; template: ProDOS FST +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START ProDOSFST +CharCaseRec +TimeStampRec +_END + +_START TimeStampRec +pCount WORD +fstNum WORD +commandNum WORD +timeOption WORD +_END + +_START CharCaseRec +pCount WORD +fstNum WORD +commandNum WORD +caseOption WORD +_END + + +; +; template: High Sierra FST +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START HighSierraFST +GetMapSizeRec +GetMapTableRec +MapEnableRec +SetMapTableRec +_END + +_START MapEnableRec +pCount WORD +fstNum WORD +commandNum WORD +enable WORD +_END + +_START GetMapSizeRec +pCount WORD +fstNum WORD +commandNum WORD +mapSize WORD +_END + +_START GetMapTableRec +pCount WORD +fstNum WORD +commandNum WORD +bufferPtr LONG +_END + +_START SetMapTableRec +pCount WORD +fstNum WORD +commandNum WORD +mapPtr LONG +_END + + +; +; template: ProDOS 16 +; 2/28/90 by J. Luther +; Copyright (c) Apple Computer, Inc. 1990 +; All Rights reserved +; + +_START ProDOS16 +BlockRec +DevNumRec +DInfoRec +DirEntryRec +EOFRec +EraseDiskRec +ExpandPathRec +FileIORec +FileRec +FormatRec +InterruptRec +MarkRec +NewLineRec +OpenRec +PathnameRec +PrefixRec +QuitRec +VolumeRec +_END + +_START BlockRec +blockDevNum WORD +blockDataBuffer LONG +blockNum LONG +_END + +_START DevNumRec +devName LONG +devNum WORD +_END + +_START DInfoRec +devNum WORD +devName LONG +_END + +_START DirEntryRec +refNum WORD +reserved WORD +base WORD +displacement WORD +nameBuffer LONG +entryNum WORD +fileType WORD +endOfFile LONG +blockCount LONG +createTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +modTime +>seconds BYTE +>minutes BYTE +>hour BYTE +>year BYTE +>day BYTE +>month BYTE +>null BYTE +>weekday BYTE +access WORD +auxType LONG +fileSysID WORD +_END + +_START EOFRec +eofRefNum WORD +eofPosition WORD +_END + +_START FileIORec +fileRefNum WORD +dataBuffer LONG +requestCount LONG +transferCount LONG +_END + +_START FileRec +pathName LONG +fAccess WORD +fileType WORD +auxType LONG +storageType WORD +createDate WORD +createTime WORD +modDate WORD +modTime WORD +blocksUsed LONG +_END + +_START FormatRec +devName LONG +volName LONG +fileSysID WORD +_END + +_START EraseDiskRec +devName LONG +volName LONG +fileSysID WORD +_END + +_START InterruptRec +intNum WORD +intCode LONG +_END + +_START MarkRec +markRefNum WORD +position LONG +_END + +_START NewLineRec +newLRefNum WORD +enableMask WORD +newLineChar WORD +_END + +_START OpenRec +openRefNum WORD +openPathname LONG +ioBuffer LONG +_END + +_START PathnameRec +pathname LONG +newPathname LONG +_END + +_START PrefixRec +prefixNum WORD +prefix LONG +_END + +_START QuitRec +quitPathname LONG +flags WORD +_END + +_START VolumeRec +deviceName LONG +volName LONG +totalBlocks LONG +freeBlocks LONG +fileSysID WORD +_END + +_START ExpandPathRec +inputPath LONG +outputPath LONG +flags WORD +_END + diff --git a/src/assets/NList.Data b/src/assets/NList.Data new file mode 100644 index 0000000..b251735 --- /dev/null +++ b/src/assets/NList.Data @@ -0,0 +1,2653 @@ +fff9 | NLIST Data File: Last mod 17-Oct-93 DAL (Loma Prieta + 4) +fffa | Based on Apple IIgs System Disk 6.0.1+UserTool#1,2 +fffb | Dave Lyons +fffc | dlyons@apple.com +0040 P8:ALLOC_INTERRUPT(2:IntNum/1,CodePtr) +0041 P8:DEALLOC_INTERRUPT(1:IntNum/1) +0042 P8:ATLK:AppleTalk(Async/1,Cmd/1,Result,...) +0043 P8:ATLK:SpecialOpenFork(4or84:pn,ioBuff,Ref/1,Mode/1) +0044 P8:ATLK:ByteRangeLock(4:Ref/1,Flag/1,Off/3,Len/3) +0065 P8:QUIT(4:Type/1,Path,zz/1,zz) +0080 P8:READ_BLOCK(3:Unit/1,Buff,BlkNum) +0081 P8:WRITE_BLOCK(3:Unit/1,Buff,BlkNum) +0082 P8:GET_TIME() +00C0 P8:CREATE(7:pn,acc/1,type/1,aux,stt/1,cD,cT) +00C1 P8:DESTROY(1:pn) +00C2 P8:RENAME(2:pn1,pn2) +00C3 P8:SetFileInfo(7:pn,a/1,t/1,aux,nul/3,mD,mT) +00C4 P8:GetFileInfo(10:pn,a/1,t/1,x,s/1,b,mDTcDT) +00C5 P8:ONLINE(2:UnitNum/1,Buff) +00C6 P8:SET_PREFIX(1:pn) +00C7 P8:GET_PREFIX(1:Buff) +00C8 P8:OPEN(3:pn,ioBuff,Ref/1) +00C9 P8:NEWLINE(3:Ref/1,Mask/1,Char/1) +00CA P8:READ(4:Ref/1,Where,reqCount,xfrCount) +00CB P8:WRITE(4:Ref/1,Where,reqCount,xfrCount) +00CC P8:CLOSE(1:Ref/1) +00CD P8:FLUSH(1:Ref/1) +00CE P8:SET_MARK(2:Ref/1,Position/3) +00CF P8:GET_MARK(2:Ref/1,Position/3) +00D0 P8:SET_EOF(2:Ref/1,Position/3) +00D1 P8:GET_EOF(2:Ref/1,Position/3) +00D2 P8:SET_BUF(2:Ref/1,ioBuff) +00D3 P8:GET_BUF(2:Ref/1,ioBuff) +* ProDOS 16 / GS/OS +0001 P16:CREATE(@Path,Acc,Typ,Aux/4,StT,CrD,CrT) +0002 P16:DESTROY(@Path) +0004 P16:CHANGE_PATH(@Path1,@Path2) +0005 P16:SET_FILE_INFO(@P,a,t,xt/4,z,cD,cT,mD,mT) +0006 P16:GET_FILE_INFO(@P,a,t,xt/4,s,cDT,mDT,b/4) +0008 P16:VOLUME(@DevN,@VolN,Blks/4,FreeBlks/4,fsID) +0009 P16:SET_PREFIX(Pfx#,@Prefix) +000A P16:GET_PREFIX(Pfx#,@Buff) +000B P16:CLEAR_BACKUP_BIT(@Path) +0010 P16:OPEN(Ref,@Path,xxx/4) +0011 P16:NEWLINE(Ref,Mask,Char) +0012 P16:READ(Ref,@Where,Count/4,xfCount/4) +0013 P16:WRITE(Ref,@Where,Count/4,xfCount/4) +0014 P16:CLOSE(Ref) +0015 P16:FLUSH(Ref) +0016 P16:SET_MARK(Ref,Pos/4) +0017 P16:GET_MARK(Ref,Pos/4) +0018 P16:SET_EOF(Ref,EOF/4) +0019 P16:GET_EOF(Ref,EOF/4) +001A P16:SET_LEVEL(Level) +001B P16:GET_LEVEL(Level) +001C P16:GET_DIR_ENTRY(Ref#,z,Bs,Dis,@Bf,dEnt/36) +0020 P16:GET_DEV_NUM(@DevName,Dev#) +0021 P16:GET_LAST_DEV(Dev#) +0022 P16:READ_BLOCK(Dev#,@Where,Blk#/4) +0023 P16:WRITE_BLOCK(Dev#,@Where,Blk#/4) +0024 P16:FORMAT(@DevName,@VolName,fsID) +0025 P16:ERASE_DISK(@DevName,@VolName,fsID) +0027 P16:GET_NAME(@Buff) +0028 P16:GET_BOOT_VOL(@Buff) +0029 P16:QUIT(@Path,Flags) +002A P16:GET_VERSION(Version) +002C P16:D_INFO(Dev#,@DevName) +0031 P16:ALLOC_INTERRUPT(Int#,@Code) +0032 P16:DEALLOCATE_INTERRUPT(Int#) +0101 Shell:Get_LInfo (...) +0102 Shell:Set_LInfo (...) +0103 Shell:Get_Lang(Lang) +0104 Shell:Set_Lang(Lang) +0105 Shell:Error(Error) +0106 Shell:Set_Variable(@VarName,Val/4) +0107 Shell:Version(Vers/4) +0108 Shell:Read_Indexed(@VarName,Val/4,Index) +0109 Shell:Init_Wildcard(@File,Flags) +010A Shell:Next_Wildcard(@NextFile) +010B Shell:Read_Variable(@VarName,Value/4) +010C Shell:ChangeVector(res,vec,@proc,@old) +010D Shell:Execute(Flag,@CmdStr) +010E Shell:FastFile(act,ind,flg,H,L/4,@n,...) +010F Shell:Direction(Dev,Direct) +0110 Shell:Redirect(Dev,ApndFlg,@File) +0113 Shell:Stop(StopFlag) +0114 Shell:ExpandDevices(@name) +0115 Shell:UnsetVariable(@var) +0116 Shell:Export(@var,flags) +0117 Shell:PopVariables() +0118 Shell:PushVariables() +0119 Shell:SetStopFlag(stopFlag) +011A Shell:ConsoleOut(Char) +011B Shell:SetIODevices(OutT,@out,ErrT,@err,InT,@in) +011C Shell:GetIODevices(OutT,@out,ErrT,@err,InT,@in) +011D Shell:GetCommand(idx,restart,rsv,cmd,name/16) +2001 GS/OS:Create(1-7:@P,Acc,Typ,Aux/4,Stg,EOF/4,rEOF/4) +2002 GS/OS:Destroy(1:@P) +2003 GS/OS:OSShutdown(1:Flags) +2004 GS/OS:ChangePath(2-3:@P1,@P2,TrustMeFlag) +2005 GS/OS:SetFileInfo(2-12:@P,A,T,X/4,,c/8,m/8,@Opt,,,,) +2006 GS/OS:GetFileInfo(2-12:@P,A,T,X/4,S,c/8,m/8,@Opt,EOF/4,B/4,rEOF/4,rB/4) +2007 GS/OS:JudgeName(3-6:fileSysID,Descr,@Rules,MaxLen,@Path,Result) +2008 GS/OS:Volume(2-8:@DevN,@vnOut,blks/4,free/4,fSys,BlkSz,char,devID) +2009 GS/OS:SetPrefix(1-2:pfxNum,@Pfx) +200A GS/OS:GetPrefix(2:pfxNum,@Pfx) +200B GS/OS:ClearBackup(1:@P) +200C GS/OS:SetSysPrefs(1:prefs) +200D GS/OS:Null(0:) +200E GS/OS:ExpandPath(2-3:@InPath,@OutPath,UpcaseFlg) +200F GS/OS:GetSysPrefs(1:prefs) +2010 GS/OS:Open(2-15:ref,@P,Acc,fork,gotAcc,+GET_FILE_INFO) +2011 GS/OS:NewLine(4:ref,ANDmask,NumChars,@NLtable) +2012 GS/OS:Read(4-5:ref,@buff,count/4,xfer/4,cacheFlg) +2013 GS/OS:Write(4-5:ref,@buff,count/4,xfer/4,cacheFlg) +2014 GS/OS:Close(1:ref) +2015 GS/OS:Flush(1-2:ref,flags) +2016 GS/OS:SetMark(3:ref,base,displ/4) +2017 GS/OS:GetMark(2:ref,pos/4) +2018 GS/OS:SetEOF(3:ref,base,displ/4) +2019 GS/OS:GetEOF(2:ref,eof/4) +201A GS/OS:SetLevel(1-2:level,levelMode) +201B GS/OS:GetLevel(1-2:level,levelMode) +201C GS/OS:GetDirEntry(5-17:rf,fl,bs,ds,@n,n,T,EOF/4,b/4,c/8,m/8,A,X/4,FS,@o,resEOF/4,resBk/4) +201D GS/OS:BeginSession(0:) +201E GS/OS:EndSession(0:) +201F GS/OS:SessionStatus(1:status) +2020 GS/OS:GetDevNumber(2:@DevN,devnum) +2024 GS/OS:Format(1-6:@DevN,@VolN,gotFS,wantFS,flags,realVolName) +2025 GS/OS:EraseDisk(1-6:@DevN,@VolN,gotFS,wantFS,flags,realVolName) +2026 GS/OS:ResetCache(0:) +2027 GS/OS:GetName(1:@n) +2028 GS/OS:GetBootvol(1:@n) +2029 GS/OS:Quit(0-2:@P,flags) +202A GS/OS:GetVersion(1:version) +202B GS/OS:GetFSTInfo(2-7:n,fs,@n,ver,attr,bSz,mxV/4,mxF/4) +202C GS/OS:DInfo(2-10:n,@n,chr,B/4,sl,unit,ver,dTyp,@hd,@nx) +202D GS/OS:DStatus(5:n,statusReq,@statList,count/4,xfer/4) +202E GS/OS:DControl(5:n,code,@ctlList,count/4,xfer/4) +202F GS/OS:DRead(6:n,@bf,count/4,blk/4,blkSz,xfer/4) +2030 GS/OS:DWrite(6:n,@bf,count/4,blk/4,blkSz,xfer/4) +2031 GS/OS:BindInt(3:IntNum,VecRefNum,@handler) +2032 GS/OS:UnbindInt(1:IntNum) +2033 GS/OS:FSTSpecific(2+...) +2034 GS/OS:AddNotifyProc(1:@proc) +2035 GS/OS:DelNotifyProc(1:@proc) +2036 GS/OS:DRename(2:n,@newName) +2037 GS/OS:GetStdRefNum(2:pfxNum,refNum) +2038 GS/OS:GetRefNum(2-6:@path,ref,acc,res,case,disp) +2039 GS/OS:GetRefInfo(2-5:ref,acc,@path,resNum,level) +203A GS/OS:SetStdRefNum(2:pfxNum,refNum) +* System tools +0000 === System Tools === +0001 === tool locator === +0101 TLBootInit() +0201 TLStartUp() +0301 TLShutDown() +0401 TLVersion():Vers +0501 TLReset() +0601 TLStatus():ActFlg +0901 GetTSPtr(SysFlg,TS#):@FPT +0A01 SetTSPtr(SysFlg,TS#,@FPT) +0B01 GetFuncPtr(SysFlg,Func):@Func +0C01 GetWAP(SysFlg,TS#):@WAP +0D01 SetWAP(SysFlg,TS#,@WAP) +0E01 LoadTools(@ToolTable) +0F01 LoadOneTool(TS#,MinVers) +1001 UnloadOneTool(TS#) +1101 TLMountVolume(X,Y,@L1,@L2,@B1,@B2):Btn# +1201 TLTextMountVolume(@L1,@L2,@B1,@B2):Btn# +1301 SaveTextState():StateH +1401 RestoreTextState(StateH) +1501 MessageCenter(Action,Type,MsgH) +1601 SetDefaultTPT() +1701 MessageByName(CreateF,@inpRec):Created,Type +1801 StartUpTools(MemID,ssDesc,ssRef/4):ssRef/4 +1901 ShutDownTools(ssDesc,ssRef/4) +1A01 GetMsgHandle(Flags,MsgRef/4):H +1B01 AcceptRequests(@NameStr,UserID,@ReqProc) +1C01 SendRequest(ReqCode,How,Target/4,@In,@Out) +0002 === memory manager === +0102 MMBootInit() +0202 MMStartUp():MemID +0302 MMShutDown(MemID) +0402 MMVersion():Vers +0502 MMReset() +0602 MMStatus():ActFlg +0902 NewHandle(Size/4,MemID,Attr,@loc):H +0A02 ReAllocHandle(Size/4,MemID,Attr,@loc,H) +0B02 RestoreHandle(H) +0C02 AddToOOMQueue(@header) +0D02 RemoveFromOOMQueue(@header) +1002 DisposeHandle(H) +1102 DisposeAll(MemID) +1202 PurgeHandle(H) +1302 PurgeAll(MemID) +1802 GetHandleSize(H):Size/4 +1902 SetHandleSize(Size/4,H) +1A02 FindHandle(@byte):H +1B02 FreeMem():FreeBytes/4 +1C02 MaxBlock():Size/4 +1D02 TotalMem():Size/4 +1E02 CheckHandle(H) +1F02 CompactMem() +2002 HLock(H) +2102 HLockAll(MemID) +2202 HUnlock(H) +2302 HUnlockAll(MemID) +2402 SetPurge(PrgLvl,H) +2502 SetPurgeAll(PrgLvl,MemID) +2802 PtrToHand(@Src,DestH,Count/4) +2902 HandToPtr(SrcH,@Dest,Count/4) +2A02 HandToHand(SrcH,DestH,Count/4) +2B02 BlockMove(@Source,@Dest,Count/4) +2F02 RealFreeMem():Size/4 +3002 SetHandleID(newMemID,theH):oldMemID +0003 === misc tools === +0103 MTBootInit() +0203 MTStartUp() +0303 MTShutDown() +0403 MTVersion():Vers +0503 MTReset() +0603 MTStatus():ActFlg +0903 WriteBRam(@Buff) +0A03 ReadBRam(@Buff) +0B03 WriteBParam(Data,Parm#) +0C03 ReadBParam(Parm#):Data +0D03 ReadTimeHex():WkDay,Mn&Dy,Yr&Hr,Mn&Sec +0E03 WriteTimeHex(Mn&Dy,Yr&Hr,Mn&Sec) +0F03 ReadAsciiTime(@Buff) +1003 SetVector(Vec#,@x) +1103 GetVector(Vec#):@x +1203 SetHeartBeat(@Task) +1303 DelHeartBeat(@Task) +1403 ClrHeartBeat() +1503 SysFailMgr(Code,@Msg) +1603 GetAddr(Ref#):@Parm +1703 ReadMouse():X,Y,Stat&Mode +1803 InitMouse(Slot) +1903 SetMouse(Mode) +1A03 HomeMouse() +1B03 ClearMouse() +1C03 ClampMouse(Xmn,Xmx,Ymn,Ymx) +1D03 GetMouseClamp():Xmn,Xmx,Ymn,Ymx +1E03 PosMouse(X,Y) +1F03 ServeMouse():IntStat +2003 GetNewID(Kind):MemID +2103 DeleteID(MemID) +2203 StatusID(MemID) +2303 IntSource(Ref#) +2403 FWEntry(A,X,Y,Address):P,A,X,Y +2503 GetTick():Ticks/4 +2603 PackBytes(@StartPtr,@Sz,@OutBf,OutSz):Size +2703 UnPackBytes(@Buff,BfSz,@StartPtr,@Sz):Size +2803 Munger(@Dst,@DstL,@t,tL,@Rpl,RplL,@Pad):N +2903 GetIRQEnable():IntStat +2A03 SetAbsClamp(Xmn,Xmx,Ymn,Ymx) +2B03 GetAbsClamp():Xmn,Xmx,Ymn,Ymx +2C03 SysBeep() +2E03 AddToQueue(@newTask,@queueHeader) +2F03 DeleteFromQueue(@task,@queueHeader) +3003 SetInterruptState(@stateRec,NumBytes) +3103 GetInterruptState(@stateRec,NumBytes) +3203 GetIntStateRecSize():Size +3303 ReadMouse2():xPos,yPos,StatMode +3403 GetCodeResConverter():@proc +3503 GetROMResource(???,???/4):???H +3603 ReleaseROMResource(???,???/4) +3703 ConvSeconds(convVerb,Secs/4,@Date):SecondsOut/4 +3803 SysBeep2(beepKind) +3903 VersionString(flags,Version/4,@Buffer) +3A03 WaitUntil(WaitFromTime,DelayTime):NewTime +3B03 StringToText(flags,@String,StrLen,@Buffer):ResFlags,PrntLen +3C03 ShowBootInfo(@String,@Icon) +3D03 ScanDevices():DevNum +3E03 AlertMessage(@Table,MsgNum,@Subs):Button +3F03 DoSysPrefs(bitsToClear,bitsToSet):SysPrefs +0004 === QuickDraw II === +0104 QDBootInit() +0204 QDStartUp(DirPg,MastSCB,MaxWid,MemID) +0304 QDShutDown() +0404 QDVersion():Vers +0504 QDReset() +0604 QDStatus():ActFlg +0904 GetAddress(what):@Table +0A04 GrafOn() +0B04 GrafOff() +0C04 GetStandardSCB():SCB +0D04 InitColorTable(@Table) +0E04 SetColorTable(Tab#,@SrcTab) +0F04 GetColorTable(Tab#,@DestTbl) +1004 SetColorEntry(Tab#,Ent#,NewCol) +1104 GetColorEntry(Tab#,Ent#):Color +1204 SetSCB(Line#,SCB) +1304 GetSCB(Line#):SCB +1404 SetAllSCBs(SCB) +1504 ClearScreen(Color) +1604 SetMasterSCB(SCB) +1704 GetMasterSCB():SCB +1804 OpenPort(@Port) +1904 InitPort(@Port) +1A04 ClosePort(@Port) +1B04 SetPort(@Port) +1C04 GetPort():@Port +1D04 SetPortLoc(@LocInfo) +1E04 GetPortLoc(@LocInfo) +1F04 SetPortRect(@Rect) +2004 GetPortRect(@Rect) +2104 SetPortSize(w,h) +2204 MovePortTo(h,v) +2304 SetOrigin(h,v) +2404 SetClip(RgnH) +2504 GetClip(RgnH) +2604 ClipRect(@Rect) +2704 HidePen() +2804 ShowPen() +2904 GetPen(@Pt) +2A04 SetPenState(@PenSt) +2B04 GetPenState(@PenSt) +2C04 SetPenSize(w,h) +2D04 GetPenSize(@Pt) +2E04 SetPenMode(Mode) +2F04 GetPenMode():Mode +3004 SetPenPat(@Patt) +3104 GetPenPat(@Patt) +3204 SetPenMask(@Mask) +3304 GetPenMask(@Mask) +3404 SetBackPat(@Patt) +3504 GetBackPat(@Patt) +3604 PenNormal() +3704 SetSolidPenPat(Color) +3804 SetSolidBackPat(Color) +3904 SolidPattern(Color,@Patt) +3A04 MoveTo(h,v) +3B04 Move(dh,dv) +3C04 LineTo(h,v) +3D04 Line(dh,dv) +3E04 SetPicSave(Val/4) +3F04 GetPicSave():Val/4 +4004 SetRgnSave(Val/4) +4104 GetRgnSave():Val/4 +4204 SetPolySave(Val/4) +4304 GetPolySave():Val/4 +4404 SetGrafProcs(@GrafProcs) +4504 GetGrafProcs():@GrafProcs +4604 SetUserField(Val/4) +4704 GetUserField():Val/4 +4804 SetSysField(Val/4) +4904 GetSysField():Val/4 +4A04 SetRect(@Rect,left,top,right,bot) +4B04 OffsetRect(@Rect,dh,dv) +4C04 InsetRect(@Rect,dh,dv) +4D04 SectRect(@R1,@R2,@DstR):nonEmptyF +4E04 UnionRect(@Rect1,@Rect2,@UnionRect) +4F04 PtInRect(@Pt,@Rect):Flag +5004 Pt2Rect(@Pt1,@Pt2,@Rect) +5104 EqualRect(@Rect1,@Rect2):Flag +5204 NotEmptyRect(@Rect):Flag +5304 FrameRect(@Rect) +5404 PaintRect(@Rect) +5504 EraseRect(@Rect) +5604 InvertRect(@Rect) +5704 FillRect(@Rect,@Patt) +5804 FrameOval(@Rect) +5904 PaintOval(@Rect) +5A04 EraseOval(@Rect) +5B04 InvertOval(@Rect) +5C04 FillOval(@Rect,@Patt) +5D04 FrameRRect(@Rect,OvalW,OvalHt) +5E04 PaintRRect(@Rect,OvalW,OvalHt) +5F04 EraseRRect(@Rect,OvalW,OvalHt) +6004 InvertRRect(@Rect,OvalW,OvalHt) +6104 FillRRect(@Rect,OvalW,OvalHt,@Patt) +6204 FrameArc(@Rect,Ang1,ArcAng) +6304 PaintArc(@Rect,Ang1,ArcAng) +6404 EraseArc(@Rect,Ang1,ArcAng) +6504 InvertArc(@Rect,Ang1,ArcAng) +6604 FillArc(@Rect,Ang1,ArcAng,@Patt) +6704 NewRgn():RgnH +6804 DisposeRgn(RgnH) +6904 CopyRgn(SrcRgnH,DestRgnH) +6A04 SetEmptyRgn(RgnH) +6B04 SetRectRgn(RgnH,left,top,right,bot) +6C04 RectRgn(RgnH,@Rect) +6D04 OpenRgn() +6E04 CloseRgn(RgnH) +6F04 OffsetRgn(RgnH,dh,dv) +7004 InsetRgn(RgnH,dh,dv) +7104 SectRgn(Rgn1H,Rgn2H,DstRgnH) +7204 UnionRgn(Rgn1H,Rgn2H,UnionRgnH) +7304 DiffRgn(Rgn1H,Rgn2H,DstRgnH) +7404 XorRgn(Rgn1H,Rgn2H,DstRgnH) +7504 PtInRgn(@Pt,RgnH):Flag +7604 RectInRgn(@Rect,RgnH):Flag +7704 EqualRgn(Rgn1H,Rgn2H):Flag +7804 EmptyRgn(RgnH):Flag +7904 FrameRgn(RgnH) +7A04 PaintRgn(RgnH) +7B04 EraseRgn(RgnH) +7C04 InvertRgn(RgnH) +7D04 FillRgn(RgnH,@Patt) +7E04 ScrollRect(@Rect,dh,dv,UpdtRgnH) +7F04 PaintPixels(@ppParms) +8004 AddPt(@SrcPt,@DestPt) +8104 SubPt(@SrcPt,@DstPt) +8204 SetPt(@Pt,h,v) +8304 EqualPt(@Pt1,@Pt2):Flag +8404 LocalToGlobal(@Pt) +8504 GlobalToLocal(@Pt) +8604 Random():N +8704 SetRandSeed(Seed/4) +8804 GetPixel(Hor,Vert):Pixel +8904 ScalePt(@Pt,@SrcRect,@DstRect) +8A04 MapPt(@Pt,@SrcRect,@DstRect) +8B04 MapRect(@Rect,@SrcRect,@DstRect) +8C04 MapRgn(MapRgnH,@SrcRect,@DstRect) +8D04 SetStdProcs(@StdProcRec) +8E04 SetCursor(@Curs) +8F04 GetCursorAdr():@Curs +9004 HideCursor() +9104 ShowCursor() +9204 ObscureCursor() +9304 SetMouseLoc ??? +9404 SetFont(FontH) +9504 GetFont():FontH +9604 GetFontInfo(@InfoRec) +9704 GetFontGlobals(@FGRec) +9804 SetFontFlags(Flags) +9904 GetFontFlags():Flags +9A04 SetTextFace(TextF) +9B04 GetTextFace():TextF +9C04 SetTextMode(TextM) +9D04 GetTextMode():TextM +9E04 SetSpaceExtra(SpEx/4f) +9F04 GetSpaceExtra():SpEx/4f +A004 SetForeColor(Color) +A104 GetForeColor():Color +A204 SetBackColor(BackCol) +A304 GetBackColor():BackCol +A404 DrawChar(Char) +A504 DrawString(@Str) +A604 DrawCString(@cStr) +A704 DrawText(@Text,Len) +A804 CharWidth(Char):Width +A904 StringWidth(@Str):Width +AA04 CStringWidth(@cStr):Width +AB04 TextWidth(@Text,Len):Width +AC04 CharBounds(Char,@Rect) +AD04 StringBounds(@Str,@Rect) +AE04 CStringBounds(@cStr,@Rect) +AF04 TextBounds(@Text,Len,@Rect) +B004 SetArcRot(ArcRot) +B104 GetArcRot():ArcRot +B204 SetSysFont(FontH) +B304 GetSysFont():FontH +B404 SetVisRgn(RgnH) +B504 GetVisRgn(RgnH) +B604 SetIntUse(Flag) +B704 OpenPicture(@FrameRect):PicH +B804 PicComment(Kind,DataSz,DataH) +B904 ClosePicture() +BA04 DrawPicture(PicH,@DstRect) +BB04 KillPicture(PicH) +BC04 FramePoly(PolyH) +BD04 PaintPoly(PolyH) +BE04 ErasePoly(PolyH) +BF04 InvertPoly(PolyH) +C004 FillPoly(PolyH,@Patt) +C104 OpenPoly():PolyH +C204 ClosePoly() +C304 KillPoly(PolyH) +C404 OffsetPoly(PolyH,dh,dv) +C504 MapPoly(PolyH,@SrcRect,@DstRect) +C604 SetClipHandle(RgnH) +C704 GetClipHandle():RgnH +C804 SetVisHandle(RgnH) +C904 GetVisHandle():RgnH +CA04 InitCursor() +CB04 SetBufDims(MaxW,MaxFontHt,MaxFBRext) +CC04 ForceBufDims(MaxW,MaxFontHt,MaxFBRext) +CD04 SaveBufDims(@SizeInfo) +CE04 RestoreBufDims(@SizeInfo) +CF04 GetFGSize():FGSize +D004 SetFontID(FontID/4) +D104 GetFontID():FontID/4 +D204 SetTextSize(TextSz) +D304 GetTextSize():TextSz +D404 SetCharExtra(ChEx/4f) +D504 GetCharExtra():ChEx/4f +D604 PPToPort(@SrcLoc,@SrcRect,X,Y,Mode) +D704 InflateTextBuffer(NewW,NewHt) +D804 GetRomFont(@Rec) +D904 GetFontLore(@Rec,RecSize):Size +DA04 Get640Colors():@PattTable +DB04 Set640Color(color) +0005 === desk manager === +0105 DeskBootInit() +0205 DeskStartUp() +0305 DeskShutDown() +0405 DeskVersion():Vers +0505 DeskReset() +0605 DeskStatus():ActFlg +0905 SaveScrn() +0A05 RestScrn() +0B05 SaveAll() +0C05 RestAll() +0E05 InstallNDA(ndaH) +0F05 InstallCDA(cdaH) +1105 ChooseCDA() +1305 SetDAStrPtr(AltDispH,@StrTbl) +1405 GetDAStrPtr():@StrTbl +1505 OpenNDA(ItemID):Ref# +1605 CloseNDA(Ref#) +1705 SystemClick(@EvRec,@Wind,fwRes) +1805 SystemEdit(eType):Flag +1905 SystemTask() +1A05 SystemEvent(Mods,Where/4,When/4,Msg/4,What):F +1B05 GetNumNDAs():N +1C05 CloseNDAbyWinPtr(@Wind) +1D05 CloseAllNDAs() +1E05 FixAppleMenu(MenuID) +1F05 AddToRunQ(@taskHeader) +2005 RemoveFromRunQ(@taskHeader) +2105 RemoveCDA(cdaH) +2205 RemoveNDA(ndaH) +2305 GetDeskAccInfo(flags,daRef/4,BufSize,@Buffer) +2405 CallDeskAcc(flags,daRef/4,Action,Data/4):Result +2505 GetDeskGlobal(selector):Value/4 +0006 === event manager === +0106 EMBootInit() +0206 EMStartUp(DirPg,qSz,Xmn,Xmx,Ymn,Ymx,MemID) +0306 EMShutDown() +0406 EMVersion():Vers +0506 EMReset() +0606 EMStatus():ActFlg +0906 DoWindows():DirPg +0A06 GetNextEvent(evMask,@EvRec):Flag +0B06 EventAvail(evMask,@EvRec):Flag +0C06 GetMouse(@Pt) +0D06 Button(Btn#):DownFlg +0E06 StillDown(Btn#):Flag +0F06 WaitMouseUp(Btn#):Flag +1006 TickCount():Ticks/4 +1106 GetDblTime():Ticks/4 +1206 GetCaretTime():Ticks/4 +1306 SetSwitch() +1406 PostEvent(code,Msg/4):Flag +1506 FlushEvents(evMask,StopMask):F +1606 GetOSEvent(evMask,@EvRec):Flag +1706 OSEventAvail(evMask,@EvRec):Flag +1806 SetEventMask(evMask) +1906 FakeMouse(ChFlg,Mods,X,Y,BtnStat) +1A06 SetAutoKeyLimit(NewLimit) +1B06 GetKeyTranslation():kTransID +1C06 SetKeyTranslation(kTransID) +0007 === scheduler === +0107 SchBootInit() +0207 SchStartUp() +0307 SchShutDown() +0407 SchVersion():Vers +0507 SchReset() +0607 SchStatus():ActFlg +0907 SchAddTask(@Task):Flag +0A07 SchFlush() +0008 === sound manager === +0108 SoundBootInit() +0208 SoundStartUp(DirPg) +0308 SoundShutDown() +0408 SoundVersion():Vers +0508 SoundReset() +0608 SoundToolStatus():ActFlg +0908 WriteRamBlock(@Src,DOCStart,Count) +0A08 ReadRamBlock(@Dest,DOCStart,Count) +0B08 GetTableAddress():@JumpTbl +0C08 GetSoundVolume(Gen#):Vol +0D08 SetSoundVolume(Vol,Gen#) +0E08 FFStartSound(GenN&mode,@Parms) +0F08 FFStopSound(GenMask) +1008 FFSoundStatus():ActFlg +1108 FFGeneratorStatus(Gen#):Stat +1208 SetSoundMIRQV(@IntHandler) +1308 SetUserSoundIRQV(@NewIRQ):@OldIRQ +1408 FFSoundDoneStatus(Gen#):Stat +1508 FFSetUpSound(ChannelGen,@Parms) +1608 FFStartPlaying(GenWord) +1708 SetDocReg(@DocRegParms) +1808 ReadDocReg(@DocRegParms) +0009 === desktop bus === +0109 ADBBootInit() +0209 ADBStartUp() +0309 ADBShutDown() +0409 ADBVersion():Vers +0509 ADBReset() +0609 ADBStatus():ActFlg +0909 SendInfo(NumB,@Data,Cmd) +0A09 ReadKeyMicroData(NumB,@Data,Cmd) +0B09 ReadKeyMicroMemory(@DataOut,@DataIn,Cmd) +0C09 [resynch--don't call] +0D09 AsyncADBReceive(@CompVec,Cmd) +0E09 SyncADBReceive(InputWrd,@CompVec,Cmd) +0F09 AbsOn() +1009 AbsOff() +1109 RdAbs():Flag +1209 SetAbsScale(@DataOut) +1309 GetAbsScale(@DataIn) +1409 SRQPoll(@CompVec,ADBreg) +1509 SRQRemove(ADBreg) +1609 ClearSRQTable() +FF09 [OBSOLETE: Use 09FF] +000A === SANE === +010A SANEBootInit() +020A SANEStartUp(DirPg) +030A SANEShutDown() +040A SANEVersion():Vers +050A SANEReset() +060A SANEStatus():ActFlg +090A FPNum (...) +0A0A DecStrNum (...) +0B0A ElemNum (...) +FF0A [OBSOLETE: USE $0AFF] +000B === integer math === +010B IMBootInit() +020B IMStartUp() +030B IMShutDown() +040B IMVersion():Vers +050B IMReset() +060B IMStatus():ActFlg +090B Multiply(A,B):Prod/4 +0A0B SDivide(Num,Den):Rem,Quot +0B0B UDivide(Num,Den):Rem,Quot +0C0B LongMul(A/4,B/4):Prod/8 +0D0B LongDivide(Num/4,Denom/4):Rem/4,Quot/4 +0E0B FixRatio(Numer,Denom):fxRatio/4 +0F0B FixMul(fx1/4,fx2/4):fxProd/4 +100B FracMul(fr1/4,fr2/4):frRes/4 +110B FixDiv(Quot/4,Divisor/4):fxRes/4 +120B FracDiv(Quot/4,Divisor/4):frRes/4 +130B FixRound(fxVal/4):Int +140B FracSqrt(frVal/4):frRes/4 +150B FracCos(fxAngle/4):frRes/4 +160B FracSin(fxAngle/4):frRes/4 +170B FixATan2(In1/4,In2/4):fxArcTan/4 +180B HiWord(Long/4):Int +190B LoWord(Long/4):Int +1A0B Long2Fix(Long/4):fxRes/4 +1B0B Fix2Long(Fix/4):Long/4 +1C0B Fix2Frac(fxVal/4):Frac/4 +1D0B Frac2Fix(frVal/4):fxRes/4 +1E0B Fix2X(Fix/4,@Extended) +1F0B Frac2X(frVal/4,@Extended) +200B X2Fix(@Extended):fxRes/4 +210B X2Frac(@Extended):frRes/4 +220B Int2Hex(Int,@Str,Len) +230B Long2Hex(Long/4,@Str,Len) +240B Hex2Int(@Str,Len):Int +250B Hex2Long(@Str,Len):Long/4 +260B Int2Dec(Int,@Str,Len,SgnFlg) +270B Long2Dec(Long/4,@Str,Len,SgnFlg) +280B Dec2Int(@Str,Len,SgnFlg):Int +290B Dec2Long(@Str,Len,SgnFlg):Long/4 +2A0B HexIt(Int):Hex/4 +000C === text tools === +010C TextBootInit() +020C TextStartUp() +030C TextShutDown() +040C TextVersion():Vers +050C TextReset() +060C TextStatus():ActFlg +090C SetInGlobals(ANDmsk,ORmsk) +0A0C SetOutGlobals(ANDmsk,ORmsk) +0B0C SetErrGlobals(ANDmsk,ORmsk) +0C0C GetInGlobals():ANDmsk,ORmsk +0D0C GetOutGlobals():ANDmsk,ORmsk +0E0C GetErrGlobals():ANDmsk,ORmsk +0F0C SetInputDevice(Type,@drvr|Slot/4) +100C SetOutputDevice(Type,@drvr|Slot/4) +110C SetErrorDevice(Type,@drvr|Slot/4) +120C GetInputDevice():Type,@drvr|Slot/4 +130C GetOutputDevice():Type,@drvr|Slot/4 +140C GetErrorDevice():Type,@drvr|Slot/4 +150C InitTextDev(dev) +160C CtlTextDev(dev,code) +170C StatusTextDev(dev,request) +180C WriteChar(Char) +190C ErrWriteChar(Char) +1A0C WriteLine(@Str) +1B0C ErrWriteLine(@Str) +1C0C WriteString(@Str) +1D0C ErrWriteString(@Str) +1E0C TextWriteBlock(@Text,Offset,Len) +1F0C ErrWriteBlock(@Text,Offset,Len) +200C WriteCString(@cStr) +210C ErrWriteCString(@cStr) +220C ReadChar(EchoFlg):Char +230C TextReadBlock(@Buff,Offset,Size,EchoFlg) +240C ReadLine(@Buff,Max,EOLch,EchoFlg):Count +000D === reserved === +000E === window manager === +010E WindBootInit() +020E WindStartUp(MemID) +030E WindShutDown() +040E WindVersion():Vers +050E WindReset() +060E WindStatus():ActFlg +090E NewWindow(@Parms):@Wind +0A0E CheckUpdate(@EvRec):Flag +0B0E CloseWindow(@Wind) +0C0E Desktop(Oper,param/4):result/4 +0D0E SetWTitle(@Title,@Wind) +0E0E GetWTitle(@Wind):@Title +0F0E SetFrameColor(@NewColTbl,@Wind) +100E GetFrameColor(@Table,@Wind) +110E SelectWindow(@Wind) +120E HideWindow(@Wind) +130E ShowWindow(@Wind) +140E SendBehind(@BehindWho,@Wind) +150E FrontWindow():@Wind +160E SetInfoDraw(@Proc,@Wind) +170E FindWindow(@WindVar,X,Y):Where +180E TrackGoAway(X,Y,@Wind):Flag +190E MoveWindow(X,Y,@Wind) +1A0E DragWindow(Grid,X,Y,Grace,@bRect,@Wind) +1B0E GrowWindow(mnW,mnH,X,Y,@Wind):nSize/4 +1C0E SizeWindow(w,h,@Wind) +1D0E TaskMaster(evMask,@TaskRec):Code +1E0E BeginUpdate(@Wind) +1F0E EndUpdate(@Wind) +200E GetWMgrPort():@Port +210E PinRect(X,Y,@Rect):Point/4 +220E HiliteWindow(Flag,@Wind) +230E ShowHide(Flag,@Wind) +240E BringToFront(@Wind) +250E WindNewRes() +260E TrackZoom(X,Y,@Wind):Flag +270E ZoomWindow(@Wind) +280E SetWRefCon(Refcon/4,@Wind) +290E GetWRefCon(@Wind):Refcon/4 +2A0E GetNextWindow(@Wind):@Wind +2B0E GetWKind(@Wind):Flag +2C0E GetWFrame(@Wind):Frame +2D0E SetWFrame(Frame,@Wind) +2E0E GetStructRgn(@Wind):StructRgnH +2F0E GetContentRgn(@Wind):ContRgnH +300E GetUpdateRgn(@Wind):UpdateRgnH +310E GetDefProc(@Wind):@Proc +320E SetDefProc(@Proc,@Wind) +330E GetWControls(@Wind):CtrlH +340E SetOriginMask(Mask,@Wind) +350E GetInfoRefCon(@Wind):Refcon/4 +360E SetInfoRefCon(Val/4,@Wind) +370E GetZoomRect(@Wind):@zRect +380E SetZoomRect(@zRect,@Wind) +390E RefreshDesktop(@Rect) +3A0E InvalRect(@Rect) +3B0E InvalRgn(RgnH) +3C0E ValidRect(@Rect) +3D0E ValidRgn(RgnH) +3E0E GetContentOrigin(@Wind):Origin/4 +3F0E SetContentOrigin(X,Y,@Wind) +400E GetDataSize(@Wind):DataSize/4 +410E SetDataSize(w,h,@Wind) +420E GetMaxGrow(@Wind):MaxGrow/4 +430E SetMaxGrow(maxWidth,maxHeight,@Wind) +440E GetScroll(@Wind):Scroll/4 +450E SetScroll(h,v,@Wind) +460E GetPage(@Wind):Page/4 +470E SetPage(h,v,@Wind) +480E GetContentDraw(@Wind):@Proc +490E SetContentDraw(@Proc,@Wind) +4A0E GetInfoDraw(@Wind):@Proc +4B0E SetSysWindow(@Wind) +4C0E GetSysWFlag(@Wind):Flag +4D0E StartDrawing(@Wind) +4E0E SetWindowIcons(NewFontH):OldFontH +4F0E GetRectInfo(@InfoRect,@Wind) +500E StartInfoDrawing(@iRect,@Wind) +510E EndInfoDrawing() +520E GetFirstWindow():@Wind +530E WindDragRect(@a,@P,X,Y,@R,@lR,@sR,F):M/4 +540E Private01():@func [GetDragRectPtr] +550E DrawInfoBar(@Wind) +560E WindowGlobal(Flags):Flags +570E SetContentOrigin2(ScrollFlag,X,Y,@Wind) +580E GetWindowMgrGlobals():@Globals +590E AlertWindow(AlertDesc,@SubArray,AlertRef/4):Btn +5A0E StartFrameDrawing(@Wind) +5B0E EndFrameDrawing() +5C0E ResizeWindow(hidden,@ContRect,@Wind) +5D0E TaskMasterContent +5E0E TaskMasterKey +5F0E TaskMasterDA(evMask,@bigTaskRec):taskCode +600E CompileText(subType,@subs,@text,size):H +610E NewWindow2(@T,RC/4,@draw,@def,pDesc,pRef/4,rType):@W +620E ErrorWindow(subType,@subs,ErrNum):Button +630E GetAuxWindInfo(@Wind):@Info +640E DoModalWindow(@Event,@Update,@EvHook,@Beep,Flags):Result/4 +650E MWGetCtlPart():Part +660E MWSetMenuProc(@NewMenuProc):@OldMenuProc +670E MWStdDrawProc() +680E MWSetUpEditMenu() +690E FindCursorCtl(@CtrlH,x,y,@Wind):PartCode +6A0E ResizeInfoBar(flags,newHeight,@Wind) +6B0E HandleDiskInsert(flags,devNum):resFlags,resDevNum +6C0E UpdateWindow(flags,@Wind) +000F === menu manager === +010F MenuBootInit() +020F MenuStartUp(MemID,DirPg) +030F MenuShutDown() +040F MenuVersion():Vers +050F MenuReset() +060F MenuStatus():ActFlg +090F MenuKey(@TaskRec,BarH) +0A0F GetMenuBar():BarH +0B0F MenuRefresh(@RedrawProc) +0C0F FlashMenuBar() +0D0F InsertMenu(MenuH,AfterWhat) +0E0F DeleteMenu(MenuID) +0F0F InsertMItem(@Item,AfterItem,MenuID) +100F DeleteMItem(ItemID) +110F GetSysBar():BarH +120F SetSysBar(BarH) +130F FixMenuBar():Height +140F CountMItems(MenuID):N +150F NewMenuBar(@Wind):BarH +160F GetMHandle(MenuID):MenuH +170F SetBarColors(BarCol,InvCol,OutCol) +180F GetBarColors():Colors/4 +190F SetMTitleStart(hStart) +1A0F GetMTitleStart():hStart +1B0F GetMenuMgrPort():@Port +1C0F CalcMenuSize(w,h,MenuID) +1D0F SetMTitleWidth(w,MenuID) +1E0F GetMTitleWidth(MenuID):TitleWidth +1F0F SetMenuFlag(Flags,MenuID) +200F GetMenuFlag(MenuID):Flags +210F SetMenuTitle(@Title,MenuID) +220F GetMenuTitle(MenuID):@Title +230F MenuGlobal(Flags):Flags +240F SetMItem(@Str,ItemID) +250F GetMItem(ItemID):@ItemName +260F SetMItemFlag(Flags,ItemID) +270F GetMItemFlag(ItemID):Flag +280F SetMItemBlink(Count) +290F MenuNewRes() +2A0F DrawMenuBar() +2B0F MenuSelect(@TaskRec,BarH) +2C0F HiliteMenu(Flag,MenuID) +2D0F NewMenu(@MenuStr):MenuH +2E0F DisposeMenu(MenuH) +2F0F InitPalette() +300F EnableMItem(ItemID) +310F DisableMItem(ItemID) +320F CheckMItem(Flag,ItemID) +330F SetMItemMark(MarkCh,ItemID) +340F GetMItemMark(ItemID):MarkChar +350F SetMItemStyle(TextStyle,ItemID) +360F GetMItemStyle(ItemID):TextStyle +370F SetMenuID(New,Old) +380F SetMItemID(New,Old) +390F SetMenuBar(BarH) +3A0F SetMItemName(@Str,ItemID) +3B0F GetPopUpDefProc():@proc +3C0F PopUpMenuSelect(SelID,left,top,flag,MenuH):id +3D0F [DrawPopUp(SelID,Flag,right,bottom,left,top,MenuH)] +3E0F NewMenu2(RefDesc,Ref/4):MenuH +3F0F InsertMItem2(RefDesc,Ref/4,After,MenuID) +400F SetMenuTitle2(RefDesc,TitleRef/4,MenuID) +410F SetMItem2(RefDesc,Ref/4,Item) +420F SetMItemName2(RefDesc,Ref/4,Item) +430F NewMenuBar2(RefDesc,Ref/4,@Wind):BarH +450F HideMenuBar() +460F ShowMenuBar() +470F SetMItemIcon(IconDesc,IconRef/4,ItemID) +480F GetMItemIcon(ItemID):IconRef/4 +490F SetMItemStruct(Desc,StructRef/4,ItemID) +4A0F GetMItemStruct(ItemID):ItemStruct/4 +4B0F RemoveMItemStruct(ItemID) +4C0F GetMItemFlag2(ItemID):ItemFlag2 +4D0F SetMItemFlag2(newValue,ItemID) +4F0F GetMItemBlink():Count +500F InsertPathMItems(flags,@Path,devnum,MenuID,AfterID,StartID,@Results) +0010 === control manager === +0110 CtlBootInit() +0210 CtlStartUp(MemID,DirPg) +0310 CtlShutDown() +0410 CtlVersion():Vers +0510 CtlReset() +0610 CtlStatus():ActFlg +0910 NewControl(@W,@R,@T,F,V,P1,P2,@p,r/4,@C):cH +0A10 DisposeControl(CtrlH) +0B10 KillControls(@Wind) +0C10 SetCtlTitle(@Title,CtrlH) +0D10 GetCtlTitle(CtrlH):@Title +0E10 HideControl(CtrlH) +0F10 ShowControl(CtrlH) +1010 DrawControls(@Wind) +1110 HiliteControl(Flag,CtrlH) +1210 CtlNewRes() +1310 FindControl(@CtrlHVar,X,Y,@Wind):Part +1410 TestControl(X,Y,CtrlH):Part +1510 TrackControl(X,Y,@ActProc,CtrlH):Part +1610 MoveControl(X,Y,CtrlH) +1710 DragControl(X,Y,@LimR,@slR,Axis,CtrlH) +1810 SetCtlIcons(FontH):OldFontH +1910 SetCtlValue(Val,CtrlH) +1A10 GetCtlValue(CtrlH):Val +1B10 SetCtlParams(P2,P1,CtrlH) +1C10 GetCtlParams(CtrlH):P1,P2 +1D10 DragRect(@acPr,@P,X,Y,@drR,@l,@slR,F):M/4 +1E10 GrowSize():Size/4 +1F10 GetCtlDpage():DirPg +2010 SetCtlAction(@ActProc,CtrlH) +2110 GetCtlAction(CtrlH):Action/4 +2210 SetCtlRefCon(Refcon/4,CtrlH) +2310 GetCtlRefCon(CtrlH):Refcon/4 +2410 EraseControl(CtrlH) +2510 DrawOneCtl(CtrlH) +2610 FindTargetCtl():CtrlH +2710 MakeNextCtlTarget():CtrlH +2810 MakeThisCtlTarget(CtrlH) +2910 SendEventToCtl(TgtOnly,@Wind,@eTask):Accepted +2A10 GetCtlID(CtrlH):CtlID/4 +2B10 SetCtlID(CtlID/4,CtrlH) +2C10 CallCtlDefProc(CtrlH,Msg,Param/4):Result/4 +2D10 NotifyCtls(Mask,Msg,Param/4,@Wind) +2E10 GetCtlMoreFlags(CtrlH):Flags +2F10 SetCtlMoreFlags(Flags,CtrlH) +3010 GetCtlHandleFromID(@Wind,CtlID/4):CtrlH +3110 NewControl2(@Wind,InKind,InRef/4):CtrlH +3210 CMLoadResource(rType,rID/4):resH +3310 CMReleaseResource(rType,rID/4) +3410 SetCtlParamPtr(@SubArray) +3510 GetCtlParamPtr():@SubArray +3710 InvalCtls(@Wind) +3810 [reserved] +3910 FindRadioButton(@Wind,FamilyNum):WhichRadio +3A10 SetLETextByID(@Wind,leID/4,@PString) +3B10 GetLETextByID(@Wind,leID/4,@PString) +3C10 SetCtlValueByID(Value,@Wind,CtlID/4) +3D10 GetCtlValueByID(@Wind,CtlID/4):Value +3E10 InvalOneCtlByID(@Wind,CtlID/4) +3F10 HiliteCtlByID(Hilite,@Wind,CtlID/4) +0011 === loader === +0111 LoaderBootInit() +0211 LoaderStartUp() +0311 LoaderShutDown() +0411 LoaderVersion():Vers +0511 LoaderReset() +0611 LoaderStatus():ActFlg +0911 InitialLoad(MemID,@path,F):dpsSz,dps,@l,MemID +0A11 Restart(MemID):dpsSz,dps,@loc,MemID +0B11 LoadSegNum(MemID,file#,seg#):@loc +0C11 UnloadSegNum(MemID,file#,seg#) +0D11 LoadSegName(MemID,@path,@segn):@loc,MemID,file#,sg# +0E11 UnloadSeg(@loc):seg#,file#,MemID +0F11 GetLoadSegInfo(MemID,file#,seg#,@buff) +1011 GetUserID(@Pathname):MemID +1111 LGetPathname(MemID,file#):@path +1211 UserShutDown(MemID,qFlag):MemID +1311 RenamePathname(@path1,@path2) +2011 InitialLoad2(MemID,@in,F,Type):dpsSz,dps,@l,MemID +2111 GetUserID2(@path):MemID +2211 LGetPathname2(MemID,file#):@path +0012 === QuickDraw Aux === +0112 QDAuxBootInit() +0212 QDAuxStartUp() +0312 QDAuxShutDown() +0412 QDAuxVersion():Vers +0512 QDAuxReset() +0612 QDAuxStatus():ActFlg +0912 CopyPixels(@sLoc,@dLoc,@sRect,@dRct,M,MskH) +0A12 WaitCursor() +0B12 DrawIcon(@Icon,Mode,X,Y) +0C12 SpecialRect(@Rect,FrameColor,FillColor) +0D12 SeedFill(@sLoc,@sR,@dLoc,@dR,X,Y,Mode,@Patt,@Leak) +0E12 CalcMask(@sLoc,@sR,@dLoc,@dR,Mode,@Patt,@Leak) +0F12 GetSysIcon(flags,value,aux/4):@Icon +1012 PixelMap2Rgn(@srcLoc,bitsPerPix,colorMask):RgnH +1312 IBeamCursor() +1412 WhooshRect(flags/4,@smallRect,@bigRect) +1512 DrawStringWidth(Flags,Ref/4,Width) +1612 UseColorTable(tableNum,@Table,Flags):ColorInfoH +1712 RestoreColorTable(ColorInfoH,Flags) +0013 === print manager === +0113 PMBootInit() +0213 PMStartUp(MemID,DirPg) +0313 PMShutDown() +0413 PMVersion():Vers +0513 PMReset() +0613 PMStatus():ActFlg +0913 PrDefault(PrRecH) +0A13 PrValidate(PrRecH):Flag +0B13 PrStlDialog(PrRecH):Flag +0C13 PrJobDialog(PrRecH):Flag +0D13 PrPixelMap(@LocInfo,@SrcRect,colorFlag) +0E13 PrOpenDoc(PrRecH,@Port):@Port +0F13 PrCloseDoc(@Port) +1013 PrOpenPage(@Port,@Frame) +1113 PrClosePage(@Port) +1213 PrPicFile(PrRecH,@Port,@StatRec) +1313 PrControl [obsolete] +1413 PrError():Error +1513 PrSetError(Error) +1613 PrChoosePrinter():DrvFlag +1813 PrGetPrinterSpecs():Type,Characteristics +1913 PrDevPrChanged(@PrinterName) +1A13 PrDevStartup(@PrinterName,@ZoneName) +1B13 PrDevShutDown() +1C13 PrDevOpen(@compProc,Reserved/4) +1D13 PrDevRead(@buffer,reqCount):xferCount +1E13 PrDevWrite(@compProc,@buff,bufLen) +1F13 PrDevClose() +2013 PrDevStatus(@statBuff) +2113 PrDevAsyncRead(@compPr,bufLen,@buff):xferCount +2213 PrDevWriteBackground(@compProc,bufLen,@buff) +2313 PrDriverVer():Vers +2413 PrPortVer():Vers +2513 PrGetZoneName():@ZoneName +2813 PrGetPrinterDvrName():@Name +2913 PrGetPortDvrName():@Name +2A13 PrGetUserName():@Name +2B13 PrGetNetworkName():@Name +3013 PrDevIsItSafe():safeFlag +3113 GetZoneList [obsolete?] +3213 GetMyZone [obsolete?] +3313 GetPrinterList [obsolete?] +3413 PMUnloadDriver(whichDriver) +3513 PMLoadDriver(whichDriver) +3613 PrGetDocName():@pStr +3713 PrSetDocName(@pStr) +3813 PrGetPgOrientation(PrRecH):Orientation +0014 === line edit === +0114 LEBootInit() +0214 LEStartUp(MemID,DirPg) +0314 LEShutDown() +0414 LEVersion():Vers +0514 LEReset() +0614 LEStatus():ActFlg +0914 LENew(@DstRect,@ViewRect,MaxL):leH +0A14 LEDispose(leH) +0B14 LESetText(@Text,Len,leH) +0C14 LEIdle(leH) +0D14 LEClick(@EvRec,leH) +0E14 LESetSelect(Start,End,leH) +0F14 LEActivate(leH) +1014 LEDeactivate(leH) +1114 LEKey(Key,Mods,leH) +1214 LECut(leH) +1314 LECopy(leH) +1414 LEPaste(leH) +1514 LEDelete(leH) +1614 LEInsert(@Text,Len,leH) +1714 LEUpdate(leH) +1814 LETextBox(@Text,Len,@Rect,Just) +1914 LEFromScrap() +1A14 LEToScrap() +1B14 LEScrapHandle():ScrapH +1C14 LEGetScrapLen():Len +1D14 LESetScrapLen(NewL) +1E14 LESetHilite(@HiliteProc,leH) +1F14 LESetCaret(@CaretProc,leH) +2014 LETextBox2(@Text,Len,@Rect,Just) +2114 LESetJust(Just,leH) +2214 LEGetTextHand(leH):TextH +2314 LEGetTextLen(leH):TxtLen +2414 GetLEDefProc():@proc +2514 LEClassifyKey(@Event):Flag +0015 === dialog manager === +0115 DialogBootInit() +0215 DialogStartUp(MemID) +0315 DialogShutDown() +0415 DialogVersion():Vers +0515 DialogReset() +0615 DialogStatus():ActFlg +0915 ErrorSound(@SoundProc) +0A15 NewModalDialog(@bR,vis,refcon/4):@Dlog +0B15 NewModelessDialog(@R,@T,@b,fr,rf/4,@zR):@D +0C15 CloseDialog(@Dlog) +0D15 NewDItem(@Dlog,dItem,@R,ty,Des/4,V,F,@Col) +0E15 RemoveDItem(@Dlog,dItem) +0F15 ModalDialog(@FilterProc):Hit +1015 IsDialogEvent(@EvRec):Flag +1115 DialogSelect(@EvRec,@Dlog,@Hit):Flag +1215 DlgCut(@Dlog) +1315 DlgCopy(@Dlog) +1415 DlgPaste(@Dlog) +1515 DlgDelete(@Dlog) +1615 DrawDialog(@Dlog) +1715 Alert(@AlertTmpl,@FiltProc):Hit +1815 StopAlert(@AlertTmpl,@FiltProc):Hit +1915 NoteAlert(@AlertTmpl,@FiltProc):Hit +1A15 CautionAlert(@AlertTmpl,@FiltProc):Hit +1B15 ParamText(@P0,@P1,@P2,@P3) +1C15 SetDAFont(FontH) +1E15 GetControlDItem(@Dlog,dItem):CtrlH +1F15 GetIText(@Dlog,dItem,@Str) +2015 SetIText(@Dlog,dItem,@Str) +2115 SelectIText(@Dlog,dItem,start,end) +2215 HideDItem(@Dlog,dItem) +2315 ShowDItem(@Dlog,dItem) +2415 FindDItem(@Dlog,Point/4):Hit +2515 UpdateDialog(@Dlog,UpdtRgnH) +2615 GetDItemType(@Dlog,dItem):type +2715 SetDItemType(type,@Dlog,dItem) +2815 GetDItemBox(@Dlog,dItem,@Rect) +2915 SetDItemBox(@Dlog,dItem,@Rect) +2A15 GetFirstDItem(@Dlog):dItem +2B15 GetNextDItem(@Dlog,dItem):dItem +2C15 ModalDialog2(@FilterProc):HitInfo/4 +2E15 GetDItemValue(@Dlog,dItem):Val +2F15 SetDItemValue(val,@Dlog,dItem) +3215 GetNewModalDialog(@DlogTmpl):@Dlog +3315 GetNewDItem(@Dlog,@ItemTmpl) +3415 GetAlertStage():Stage +3515 ResetAlertStage() +3615 DefaultFilter(@Dlog,@EvRec,@Hit):Flag +3715 GetDefButton(@Dlog):dItem +3815 SetDefButton(BtnID,@Dlog) +3915 DisableDItem(@Dlog,dItem) +3A15 EnableDItem(@Dlog,dItem) +0016 === scrap manager === +0116 ScrapBootInit() +0216 ScrapStartUp() +0316 ScrapShutDown() +0416 ScrapVersion():Vers +0516 ScrapReset() +0616 ScrapStatus():ActFlg +0916 UnloadScrap() +0A16 LoadScrap() +0B16 ZeroScrap() +0C16 PutScrap(Count/4,Type,@Src) +0D16 GetScrap(DestH,Type) +0E16 GetScrapHandle(Type):ScrapH +0F16 GetScrapSize(Type):Size/4 +1016 GetScrapPath():@Pathname +1116 SetScrapPath(@Pathname) +1216 GetScrapCount():Count +1316 GetScrapState():State +1416 GetIndScrap(Index,@buffer) +1516 ShowClipboard(flags,@rect):@Wind +0017 === standard file === +0117 SFBootInit() +0217 SFStartUp(MemID,DirPg) +0317 SFShutDown() +0417 SFVersion():Vers +0517 SFReset() +0617 SFStatus():ActFlg +0917 SFGetFile(X,Y,@Prmpt,@FPrc,@tL,@Reply) +0A17 SFPutFile(X,Y,@Prompt,@DfltName,mxL,@Reply) +0B17 SFPGetFile(X,Y,@P,@FPrc,@tL,@dTmp,@dHk,@Rp) +0C17 SFPPutFile(X,Y,@P,@Df,mxL,@dTmpl,@dHk,@Rply) +0D17 SFAllCaps(Flag) +0E17 SFGetFile2(X,Y,prDesc,prRef/4,@fProc,@tList,@rep) +0F17 SFPutFile2(X,Y,prDesc,prRef/4,nmDesc,nmRef/4,@rep) +1017 SFPGetFile2(X,Y,@draw,prD,prRf/4,@fP,@tL,@d,@hk,@rep) +1117 SFPPutFile2(X,Y,@draw,prD,prRf/4,nmD,nmRf/4,@d,@hk,@rep) +1217 SFShowInvisible(InvisState):OldState +1317 SFReScan(@filterProc,@typeList) +1417 SFMultiGet2(X,Y,prDesc,prRef/4,@fP,@tL,@rep) +1517 SFPMultiGet2(X,Y,@draw,prD,prRf/4,@fP,@tL,@d,@hk,@rep) +0019 === note synthesizer === +0119 NSBootInit() +0219 NSStartUp(Rate,@UpdProc) +0319 NSShutDown() +0419 NSVersion():Vers +0519 NSReset() +0619 NSStatus():ActFlg +0919 AllocGen(Priority):Gen# +0A19 DeallocGen(Gen#) +0B19 NoteOn(Gen#,Semitone,Vol,@Instr) +0C19 NoteOff(Gen#,Semitone) +0D19 AllNotesOff() +0E19 NSSetUpdateRate(NewRate):OldRate +0F19 NSSetUserUpdateRtn(@New):@Old +001A === note sequencer === +011A SeqBootInit() +021A SeqStartUp(DirPg,Mode,Rate,Incr) +031A SeqShutDown() +041A SeqVersion():Vers +051A SeqReset() +061A SeqStatus():ActFlg +091A SetIncr(Increment) +0A1A ClearIncr():OldIncr +0B1A GetTimer():Tick +0C1A GetLoc():Phrase,Patt,Level +0D1A SeqAllNotesOff() +0E1A SetTrkInfo(Priority,InstIndex,TrkNum) +0F1A StartSeq(@ErrRtn,@CompRtn,SeqH) +101A StepSeq() +111A StopSeq(NextFlag) +121A SetInstTable(TableH) +131A StartInts() +141A StopInts() +151A StartSeqRel(@errHndlr,@CompRtn,SeqH) +001B === font manager === +011B FMBootInit() +021B FMStartUp(MemID,DirPg) +031B FMShutDown() +041B FMVersion():Vers +051B FMReset() +061B FMStatus():ActFlg +091B CountFamilies(FamSpecs):Count +0A1B FindFamily(Specs,Pos,@Name):FamNum +0B1B GetFamInfo(FamNum,@Name):FamStats +0C1B GetFamNum(@Name):FamNum +0D1B AddFamily(FamNum,@Name) +0E1B InstallFont(ID/4,Scale) +0F1B SetPurgeStat(FontID/4,PrgStat) +101B CountFonts(ID/4,Specs):N +111B FindFontStats(ID/4,Specs,Pos,@FStatRec) +121B LoadFont(ID/4,Specs,Pos,@FStatRec) +131B LoadSysFont() +141B AddFontVar(FontH,NewSpecs) +151B FixFontMenu(MenuID,StartID,FamSpecs) +161B ChooseFont(CurrID/4,Famspecs):NewID/4 +171B ItemID2FamNum(ItemID):FamNum +181B FMSetSysFont(FontID/4) +191B FMGetSysFID():SysID/4 +1A1B FMGetCurFID():CurID/4 +1B1B FamNum2ItemID(FamNum):ItemID +1C1B InstallWithStats(ID/4,Scale,@ResultRec) +001C === List Manager === +011C ListBootInit() +021C ListStartUp() +031C ListShutDown() +041C ListVersion():Vers +051C ListReset() +061C ListStatus():ActFlg +091C CreateList(@Wind,@ListRec):CtrlH +0A1C SortList(@CompareProc,@ListRec) +0B1C NextMember(@Member,@ListRec):@NxtMemVal +0C1C DrawMember(@Member,@ListRec) +0D1C SelectMember(@Member,@ListRec) +0E1C GetListDefProc():@Proc +0F1C ResetMember(@ListRec):NxtMemVal/4 +101C NewList(@Member,@ListRec) +111C DrawMember2(itemNum,CtrlH) +121C NextMember2(itemNum,CtrlH):itemNum +131C ResetMember2(CtrlH):itemNum +141C SelectMember2(itemNum,CtrlH) +151C SortList2(@CompareProc,CtrlH) +161C NewList2(@draw,start,ref/4,refKind,size,CtrlH) +171C ListKey(flags,@EventRec,CtrlH) +181C CompareStrings(flags,@String1,@String2):Order +001D === Audio Compression/Expansion === +011D ACEBootInit() +021D ACEStartUp(DirPg) +031D ACEShutDown() +041D ACEVersion():Vers +051D ACEReset() +061D ACEStatus():ActFlg +071D ACEInfo(Code):Value/4 +091D ACECompress(SrcH,SrcOff/4,DestH,DestOff/4,Blks,Method) +0A1D ACEExpand(SrcH,SrcOff/4,DestH,DestOff/4,Blks,Method) +0B1D ACECompBegin() +0C1D ACEExpBegin() +0D1D GetACEExpState(@Buffer) +0E1D SetACEExpState(@Buffer) +001E === Resource Manager === +011E ResourceBootInit() +021E ResourceStartUp(MemID) +031E ResourceShutDown() +041E ResourceVersion():Vers +051E ResourceReset() +061E ResourceStatus():ActFlag +091E CreateResourceFile(aux/4,fType,Access,@n) +0A1E OpenResourceFile(reqAcc,@mapAddr,@n):fileID +0B1E CloseResourceFile(fileID) +0C1E AddResource(H,Attr,rType,rID/4) +0D1E UpdateResourcefile(fileID) +0E1E LoadResource(rType,rID/4):H +0F1E RemoveResource(rType,rID/4) +101E MarkResourceChange(changeFlag,rType,rID/4) +111E SetCurResourceFile(fileID) +121E GetCurResourceFile():fileID +131E SetCurResourceApp(MemID) +141E GetCurResourceApp():MemID +151E HomeResourceFile(rType,rID/4):fileID +161E WriteResource(rType,rID/4) +171E ReleaseResource(PurgeLevel,rType,rID/4) +181E DetachResource(rType,rID/4) +191E UniqueResourceID(IDrange,rType):rID/4 +1A1E SetResourceID(newID/4,rType,oldID/4) +1B1E GetResourceAttr(rType,rID/4):Attr +1C1E SetResourceAttr(rAttr,rType,rID/4) +1D1E GetResourceSize(rType,rID/4):Size/4 +1E1E MatchResourceHandle(@buffer,H) +1F1E GetOpenFileRefNum(fileID):RefNum +201E CountTypes():Num +211E GetIndType(tIndex):rType +221E CountResources(rType):Num/4 +231E GetIndResource(rType,rIndex/4):rID/4 +241E SetResourceLoad(Flag):oldFlag +251E SetResourceFileDepth(Depth):oldDepth +261E GetMapHandle(fileID):MapH +271E LoadAbsResource(@loc,MaxSize/4,rType,rID/4):Size/4 +281E ResourceConverter(@proc,rType,logFlags) +291E LoadResource2(flag,@AttrBuff,rType,rID/4):H +2A1E RMFindNamedResource(rType,@name,@fileID):rID/4 +2B1E RMGetResourceName(rType,rID/4,@nameBuffer) +2C1E RMLoadNamedResource(rType,@name):H +2D1E RMSetResourceName(rType,rID/4,@name) +2E1E OpenResourceFileByID(reqAcc,userID):oldResApp +2F1E CompactResourceFile(flags,fileID) +0020 === MIDI === +0120 MidiBootInit() +0220 MidiStartUp(MemID,DirPg) +0320 MidiShutDown() +0420 MidiVersion():Vers +0520 MidiReset() +0620 MidiStatus():ActFlg +0920 MidiControl(Function,Argument/4) +0A20 MidiDevice(Function,@DriverInfo) +0B20 MidiClock(Function,Argument/4) +0C20 MidiInfo(Function):Info/4 +0D20 MidiReadPacket(@buff,size):Count +0E20 MidiWritePacket(@buff):Count +0021 === Video Overlay === +0121 VDBootInit() +0221 VDStartUp() +0321 VDShutDown() +0421 VDVersion():Vers +0521 VDReset() +0621 VDStatus():ActFlg +0921 VDInStatus(Selector):Status +0A21 VDInSetStd(InStandard) +0B21 VDInGetStd():InStandard +0C21 VDInConvAdj(Selector,AdjFunction) +0D21 VDKeyControl(Selector,KeyerCtrlVal) +0E21 VDKeyStatus(Selector):KeyerStatus +0F21 VDKeySetKCol(Red,Green,Blue) +1021 VDKeyGetKRCol():RedValue +1121 VDKeyGetKGCol():GreenValue +1221 VDKeyGetKBCol():BlueValue +1321 VDKeySetKDiss(KDissolve) +1421 VDKeyGetKDiss():KDissolve +1521 VDKeySetNKDiss(NKDissolve) +1621 VDKeyGetNKDiss():NKDissolve +1721 VDOutSetStd(OutStandard) +1821 VDOutGetStd():OutStandard +1921 VDOutControl(Selector,Value) +1A21 VDOutStatus(Selector):OutStatus +1B21 VDGetFeatures(Feature):Info +1C21 VDInControl(Selector,Value) +1D21 VDGGControl(Selector,Value) +1E21 VDGGStatus(Selector):Value +0022 === Text Edit === +0122 TEBootInit() +0222 TEStartUp(MemID,DirPg) +0322 TEShutDown() +0422 TEVersion():Vers +0522 TEReset() +0622 TEStatus():ActFlg +0922 TENew(@parms):teH +0A22 TEKill(teH) +0B22 TESetText(tDesc,tRef/4,Len/4,stDesc,stRef/4,teH) +0C22 TEGetText(bDesc,bRef/4,bLen/4,stDesc,stRef/4,teH):L/4 +0D22 TEGetTextInfo(@infoRec,parmCount,teH) +0E22 TEIdle(teH) +0F22 TEActivate(teH) +1022 TEDeactivate(teH) +1122 TEClick(@eventRec,teH) +1222 TEUpdate(teH) +1322 TEPaintText(@Port,startLn/4,@R,Flags,teH):NextLn/4 +1422 TEKey(@eventRec,teH) +1522 [not supported] +1622 TECut(teH) +1722 TECopy(teH) +1822 TEPaste(teH) +1922 TEClear(teH) +1A22 TEInsert(tDesc,tRef/4,tLen/4,stDesc,stRef/4,teH) +1B22 TEReplace(tDesc,tRef/4,tLen/4,stDesc,stRef/4,teH) +1C22 TEGetSelection(@selStart,@selEnd,teH) +1D22 TESetSelection(selStart/4,selEnd/4,teH) +1E22 TEGetSelectionStyle(@stRec,stH,teH):comFlag +1F22 TEStyleChange(flags,@stRec,teH) +2022 TEOffsetToPoint(offset/4,@vertPos,@horPos,teH) +2122 TEPointToOffset(vertPos/4,horPos/4,teH):textOffset/4 +2222 TEGetDefProc():@defProc +2322 TEGetRuler(rulerDesc,rulerRef/4,teH) +2422 TESetRuler(rulerDesc,rulerRef/4,teH) +2522 TEScroll(scrDesc,vertAmt/4,horAmt/4,teH):Offset/4 +2622 TEGetInternalProc():@proc +2722 TEGetLastError(clearFlag,teH):lastError +2822 TECompactRecord(teH) +0023 === MIDI Synth === +0123 MSBootInit() +0223 MSStartUp() +0323 MSShutDown() +0423 MSVersion():Vers +0523 MSReset() +0623 MSStatus():ActFlg +0923 SetBasicChannel(Channel) +0A23 SetMIDIMode(Mode) +0B23 PlayNote(Channel,NoteNum,KeyVel) +0C23 StopNote(Channel,NoteNum) +0D23 KillAllNotes() +0E23 SetRecTrack(TrackNum) +0F23 SetPlayTrack(TrackNum,State) +1023 TrackToChannel(TrackNum,ChannelNum) +1123 Locate(TimeStamp/4,@SeqBuff):@SeqItem +1223 SetVelComp(VelocityOffset) +1323 SetMIDIPort(EnabInput,EnabOutput) +1423 SetInstrument(@InstRec,InstNum) +1523 SeqPlayer(@SeqPlayerRec) +1623 SetTempo(Tempo) +1723 SetCallBack(@CallBackRec) +1823 SysExOut(@Msg,Delay,@MonRoutine) +1923 SetBeat(BeatDuration) +1A23 MIDIMessage(Dest,nBytes,Message,Byte1,Byte2) +1B23 LocateEnd(@seqBuffer):@End +1C23 Merge(@Buffer1,@Buffer2) +1D23 DeleteTrack(TrackNum,@Seq) +1E23 SetMetro(Volume,Freq,@Wave) +1F23 GetMSData():Reserved/4,@DirPage +2023 ConvertToTime(TkPerBt,BtPerMsr,BeatNum,MsrNum):Ticks/4 +2123 ConvertToMeasure(TkPerBt,BtPerMsr,Ticks/4):Ticks,Beat,Msr +2223 MSSuspend() +2323 MSResume() +2423 SetTuningTable(@Table) +2523 GetTuningTable(@Buffer) +2623 SetTrackOut(TrackNum,PathVal) +2723 InitMIDIDriver(Slot,Internal,UserID,@Driver) +2823 RemoveMIDIDriver() +0026 === Media Controller === +0126 MCBootInit() +0226 MCStartUp(MemID) +0326 MCShutDown() +0426 MCVersion():Vers +0526 MCReset() +0626 MCStatus():ActFlg +0926 MCGetErrorMsg(mcErrorNo,@PStringBuff) +0A26 MCLoadDriver(mcChannelNo) +0B26 MCUnLoadDriver(mcChannelNo) +0C26 MCTimeToBin(mcTimeValue/4):result/4 +0D26 MCBinToTime(mcBinVal/4):result/4 +0E26 MCGetTrackTitle(mcDiskID/4,mcTrackNo,@PStringBuff) +0F26 MCSetTrackTitle(mcDiskID/4,TrackNum,@title) +1026 MCGetProgram(mcDiskID/4,@resultBuff) +1126 MCSetProgram(mcDiskID/4,@mcProg) +1226 MCGetDiscTitle(mcDiskID/4,@PStringBuff) +1326 MCSetDiscTitle(mcDiskID/4,@title) +1426 MCDStartUp(mcChannelNo,@portName,userID) +1526 MCDShutDown(mcChannelNo) +1626 MCGetFeatures(mcChannelNo,mcFeatSel):result/4 +1726 MCPlay(mcChannelNo) +1826 MCPause(mcChannelNo) +1926 MCSendRawData(mcChannelNo,@mcNative) +1A26 MCGetStatus(mcChannelNo,mcStatusSel):result +1B26 MCControl(mcChannelNo,ctlCommand) +1C26 MCScan(mcChannelNo,mcDirection) +1D26 MCGetSpeeds(mcChannelNo,@PStringBuff) +1E26 MCSpeed(mcChannelNo,mcFPS) +1F26 MCStopAt(mcChannelNo,mcUnitType,mcStopLoc/4) +2026 MCJog(mcChannelNo,mcUnitType,mcNJog/4,mcJogRepeat) +2126 MCSearchTo(mcChannelNo,mcUnitType,searchLoc/4) +2226 MCSearchDone(mcChannelNo):result +2326 MCSearchWait(mcChannelNo) +2426 MCGetPosition(mcChannelNo,mcUnitType):result/4 +2526 MCSetAudio(mcChannelNo,mcAudioCtl) +2626 MCGetTimes(mcChannelNo,mctimesSel):result/4 +2726 MCGetDiscTOC(mcChannelNo,mcTrackNo):result/4 +2826 MCGetDiscID(mcChannelNo):result/4 +2926 MCGetNoTracks(mcChannelNo):result +2A26 MCRecord(mcChannelNo) +2B26 MCStop(mcChannelNo) +2C26 MCWaitRawData(mcChannelNo,@result,tickWait,termMask) +2D26 MCGetName(mcChannelNo,@PStringBuff) +2E26 MCSetVolume(mcChannelNo,mcLeftVol,mcRightVol) +0036 === Marinetti === +0136 TCPIPBootInit() +0236 TCPIPStartUp() +0336 TCPIPShutDown() +0436 TCPIPVersion():Vers +0536 TCPIPReset() +0636 TCPIPStatus():ActFlg +0836 TCPIPLongVersion():rVersion/4 +0936 TCPIPGetConnectStatus():connectedFlag +0A36 TCPIPGetErrorTable():@errTablePtr +0B36 TCPIPGetReconnectStatus():reconnectFlag +0C36 TCPIPReconnect(@displayPtr) +0D36 TCPIPConvertIPToHex(@cvtRecPtr,@ddippstring) +0E36 TCPIPConvertIPToASCII(ipaddress/4,@ddpstring,flags):strlen +0F36 TCPIPGetMyIPAddress():ipaddress/4 +1036 TCPIPGetConnectMethod():method +1136 TCPIPSetConnectMethod(method) +1236 TCPIPConnect(@displayPtr) +1336 TCPIPDisconnect(forceflag,@displayPtr) +1436 TCPIPGetMTU():mtu +1536 TCPIPValidateIPCString(@cstringPtr):validFlag +1636 TCPIPGetConnectData(userid,method):H +1736 TCPIPSetConnectData(method,H) +1836 TCPIPGetDisconnectData(userid,method):H +1936 TCPIPSetDisconnectData(method,H) +1A36 TCPIPLoadPreferences() +1B36 TCPIPSavePreferences() +1C36 TCPIPGetDNS(@DNSRecPtr) +1D36 TCPIPSetDNS(@DNSRecPtr) +1E36 TCPIPGetTuningTable(@tunePtr) +1F36 TCPIPSetTuningTable(@tunePtr) +2036 TCPIPCancelDNR(@dnrBufferPtr) +2136 TCPIPDNRNameToIP(@nameptr,@dnrBufferPtr) +2236 TCPIPPoll() +2336 TCPIPLogin(userid,destip/4,destport,defaultTOS,defaultTTL):ipid +2436 TCPIPLogout(ipid) +2536 TCPIPSendICMP(ipid,@messagePtr,messageLen) +2636 TCPIPSendUDP(ipid,@udpPtr,udpLen) +2736 TCPIPGetDatagramCount(ipid,protocol):dgmCount +2836 TCPIPGetNextDatagram(ipid,protocol,flags):H +2936 TCPIPGetLoginCount():loginCount +2A36 TCPIPSendICMPEcho(ipid,seqNum) +2B36 TCPIPReceiveICMPEcho(ipid):seqNum +2C36 TCPIPOpenTCP(ipid):tcpError +2D36 TCPIPWriteTCP(ipid,@dataPtr,dataLength/4,pushFlag,urgentFlag):tcpError +2E36 TCPIPReadTCP(ipid,buffType,buffData/4,buffLen/4,@rrBuffPtr):tcpError +2F36 TCPIPCloseTCP(ipid):tcpError +3036 TCPIPAbortTCP(ipid):tcpError +3136 TCPIPStatusTCP(ipid,@srBuffPtr):tcpError +3236 TCPIPGetSourcePort(ipid):sourcePort +3336 TCPIPGetTOS(ipid):TOS +3436 TCPIPSetTOS(ipid,TOS) +3536 TCPIPGetTTL(ipid):TTL +3636 TCPIPSetTTL(ipid,TTL) +3736 TCPIPSetSourcePort(ipid,sourcePort) +3836 TCPIPSetMyIPAddress(ipaddress/4) +3936 TCPIPGetDP():dp +3A36 TCPIPGetDebugHex():debugFlag +3B36 TCPIPDebugHex(debugFlag) +3C36 TCPIPGetDebugTCP():debugFlag +3D36 TCPIPDebugTCP(debugFlag) +3E36 TCPIPGetUserRecord(ipid):userRecEntry/4 +3F36 TCPIPConvertIPCToHex(@cvtRecPtr,@ddipcstring) +4036 TCPIPSendIPDatagram(@datagramPtr) +4136 TCPIPConvertIPToClass(ipaddress/4):class +4236 TCPIPGetConnectMsgFlag():conMsgFlag +4336 TCPIPSetConnectMsgFlag(conMsgFlag) +4436 TCPIPGetUsername(@unBuffPtr) +4536 TCPIPSetUsername(@usernamePtr) +4636 TCPIPGetPassword(@pwBuffPtr) +4736 TCPIPSetPassword(@passwordPtr) +4836 TCPIPValidateIPString(@pstringPtr):validFlag +4936 TCPIPGetUserStatistic(ipid,statisticNum):statistic/4 +4A36 TCPIPGetLinkVariables():@variablesPtr +4B36 TCPIPEditLinkConfig(connectHandle/4,disconnectHandle/4) +4C36 TCPIPGetModuleNames():@moduleListPtr +4D36 TCPIPRebuildModuleList() +4E36 TCPIPListenTCP(ipid):tcpError +4F36 TCPIPAcceptTCP(ipid,reserved):newipid +5036 TCPIPSetNewDestination(ipid,destip/4,destport) +5136 TCPIPGetHostName(@hnBuffPtr) +5236 TCPIPSetHostName(@hostNamePtr) +5336 TCPIPStatusUDP(ipid,@udpVarsPtr) +5436 TCPIPGetLinkLayer(@linkInfoBlkPtr) +5536 TCPIPPtrToPtr(@from,@to,len/4) +5636 TCPIPPtrToPtrNeg(@fromend,@toend,len/4) +5736 TCPIPGetAuthMessage(userid):authMsgHandle/4 +5836 TCPIPConvertIPToCASCII(ipaddress/4,@ddcstring,flags):strlen +5936 TCPIPMangleDomainName(flags,@dnPstringPtr):port +5A36 TCPIPGetAliveFlag():aliveFlag +5B36 TCPIPSetAliveFlag(aliveFlag) +5C36 TCPIPGetAliveMinutes():aliveMinutes +5D36 TCPIPSetAliveMinutes(aliveMinutes) +5E36 TCPIPReadLineTCP(ipid,@delimitStrPtr,buffType,buffData/4,buffLen/4,@rrBuffPtr):tcpError +5F36 TCPIPGetBootConnectFlag():bootConnectFlag +6036 TCPIPSetBootConnectFlag(bootConnectFlag) +6136 TCPIPSetUDPDispatch(ipid,dispatchFlag) +6236 TCPIPGetDestination(ipid,@destRecPtr) +6336 TCPIPGetUserEventTrigger(triggerNumber,ipid):triggerProcPtr/4 +6436 TCPIPSetUserEventTrigger(triggerNumber,ipid,@triggerProcPtr) +6536 TCPIPGetSysEventTrigger(triggerNumber):triggerProcPtr/4 +6636 TCPIPSetSysEventTrigger(triggerNumber,@triggerProcPtr) +6736 TCPIPGetDNRTimeouts(@dnrTimeoutsBuffPtr) +6836 TCPIPSetDNRTimeouts(@dnrTimeoutsBuffPtr) +0032 === Male Voice === +0132 MaleBootInit() +0232 MaleStartUp() +0332 MaleShutDown() +0432 MaleVersion():Vers +0532 MaleReset() +0632 MaleStatus():ActFlg +0932 MaleSpeak(Vol,Speed,Pitch,@PhonStr) +0033 === Female Voice === +0133 FemaleBootInit() +0233 FemaleStartUp() +0333 FemaleShutDown() +0433 FemaleVersion():Vers +0533 FemaleReset() +0633 FemaleStatus():ActFlg +0933 FemaleSpeak(Vol,Speed,Pitch,@PhonStr) +0034 === TML Speech Toolkit parser === +0134 SpeechBootInit() +0234 SpeechStartUp(MemID) +0334 SpeechShutDown() +0434 SpeechVersion():Vers +0534 SpeechReset() +0634 SpeechStatus():ActFlg +0934 Parse(@EnglStr,@PhonStr,Start) +0A34 DictInsert(@EnglStr,@PhonStr) +0B34 DictDelete(@EnglStr) +0C34 DictDump(@EnglStr,@PhonStr):@Str; +0D34 SetSayGlobals(Gend,Tone,Pitch,Spd,Vol) +0E34 DictInit(Flag) +0F34 Say(@EnglishStr) +1034 Activate... +0042 === Finder (error codes only) === +00FF === GSBug === +04FF DebugVersion():Vers +06FF DebugStatus():ActFlg +09FF DebugStr(@PStr) +0AFF SetMileStone(@PStr) +0BFF DebugSetHook(@hook) +0CFF DebugGetInfo(selector):Info/4 +0DFF DebugControl(data/4,extraData/4,operation,type) +0EFF DebugQuery(data/4,operation,type):Info/4 +* User tools +0000 === User Tools === +0001 === fakeModalDialog (DTS) === +0101 fmdBootInit() +0201 fmdStartUp() +0301 fmdShutDown() +0401 fmdVersion():Vers +0501 fmdReset() +0601 fmdStatus():ActFlg +0901 fakeModalDialog(@Event,@Update,@EvHook,@Beep,Flags):Result/4 +0A01 fmdSetMenuProc(@MenuProc) +0B01 fmdGetMenuProc():@MenuProc +0C01 fmdStdDrawProc() +0D01 fmdEditMenu() +0E01 fmdFindCursorCtl(@CtrlH,x,y,@Wind):PartCode +0F01 fmdLESetText(@Wind,leID/4,@PString) +1001 fmdLEGetText(@Wind,leID/4,@PString) +1101 fmdWhichRadio(@Wind,RadioID/4):WhichRadio +1201 fmdIBeamCursor() +1301 fmdInitIBeam() +1401 fmdSetIBeam(@Cursor) +1501 fmdGetIBeamAdr():@Cursor +1601 fmdGetCtlPart():Part +1701 fmdGetError():Error +0002 === PixelMap Tools (DTS) === +0102 pmapBootInit() +0202 pmapStartUp() +0302 pmapShutDown() +0402 pmapVersion():Vers +0502 pmapReset() +0602 pmapStatus():ActFlg +0902 pixelMap2Rgn(@srcLoc,bitsPerPix,colorMask):RgnH +0A02 newPort(@pmapPortInfo):@port +0B02 killPort(@pmapPortInfo) +* E1xxxx vectors +0000 System Tool dispatcher +0004 System Tool dispatcher, glue entry +0008 User Tool dispatcher +000C User Tool dispatcher, glue entry +0010 Interrupt mgr +0014 COP mgr +0018 Abort mgr +001C System Death mgr +0020 AppleTalk interrupt +0024 Serial interrupt +0028 Scanline interrupt +002C Sound interrupt +0030 VertBlank interrupt +0034 Mouse interrupt +0038 1/4 sec interrupt +003C Keyboard interrupt +0040 ADB Response byte int +0044 ADB SRQ int +0048 Desk Acc mgr +004C FlushBuffer handler +0050 KbdMicro interrupt +0054 1 sec interrupt +0058 External VGC int +005C other interrupt +0060 Cursor update +0064 IncBusy +0068 DecBusy +006C Bell vector +0070 Break vector +0074 Trace vector +0078 Step vector +007C [install ROMdisk] +0080 ToWriteBram +0084 ToReadBram +0088 ToWriteTime +008C ToReadTime +0090 ToCtrlPanel +0094 ToBramSetup +0098 ToPrintMsg8 +009C ToPrintMsg16 +00A0 Native Ctrl-Y +00A4 ToAltDispCDA +00A8 ProDOS 16 [inline parms] +00AC OS vector +00B0 GS/OS(@parms,call) [stack parms] +00B4 OS_P8_Switch +00B8 OS_Public_Flags +00BC OS_KIND (byte: 0=P8,1=P16) +00BD OS_BOOT (byte) +00BE OS_BUSY (bit 15=busy) +00C0 MsgPtr +0180 ToBusyStrip +0184 ToStrip +01B2 MidiInputPoll +0200 Memory Mover +0204 Set System Speed +0208 Slot Arbiter +0220 HyperCard IIgs callback +0224 WordForRTL +1004 ATLK: BASIC +1008 ATLK: Pascal +100C ATLK: RamGoComp +1010 ATLK: SoftReset +1014 ATLK: RamDispatch +1018 ATLK: RamForbid +101C ATLK: RamPermit +1020 ATLK: ProEntry +1022 ATLK: ProDOS +1026 ATLK: SerStatus +102A ATLK: SerWrite +102E ATLK: SerRead +103A init file hook +103E ATLK: PFI Vector +D600 ATLK: CmdTable +DA00 ATLK: TickCount +* E0xxxx vectors +1E04 QD:StdText +1E08 QD:StdLine +1E0C QD:StdRect +1E10 QD:StdRRect +1E14 QD:StdOval +1E18 QD:StdArc +1E1C QD:StdPoly +1E20 QD:StdRgn +1E24 QD:StdPixels +1E28 QD:StdComment +1E2C QD:StdTxMeas +1E30 QD:StdTxBnds +1E34 QD:StdGetPic +1E38 QD:StdPutPic +1E98 QD:ShieldCursor +1E9C QD:UnShieldCursor +* softswitches and F8 ROM routines +B000 Dvx: xgetparm_ch +B003 Dvx: xgetparm_n +B006 Dvx: xmess +B009 Dvx: xprint_ftype +B00C Dvx: xprint_access +B00F Dvx: xprdec_2 +B012 Dvx: xprdec_3 +B015 Dvx: xprdec_pad +B018 Dvx: xprint_path +B01B Dvx: xbuild_local +B01E Dvx: xprint_sd +B021 Dvx: xprint_drvr +B024 Dvx: xredirect +B027 Dvx: xpercent +B02A Dvx: xyesno +B02D Dvx: xgetln +B030 Dvx: xbell +B033 Dvx: xdowncase +B036 Dvx: xplural +B039 Dvx: xcheck_wait +B03C Dvx: xpr_date_ay +B03F Dvx: xpr_time_ay +B042 Dvx: xProDOS_err +B045 Dvx: xProDOS_er +B048 Dvx: xerr +B04B Dvx: xprdec_pady +B04E Dvx: xdir_setup +B051 Dvx: xdir_finish +B054 Dvx: xread1dir +B057 Dvx: xpmgr +B05A Dvx: xmmgr +B05D Dvx: xpoll_io +B060 Dvx: xprint_ver +B063 Dvx: xpush_level +B066 Dvx: xfman_open +B069 Dvx: xfman_read +B06C Dvx: xrdkey (v1.1+) +B06F Dvx: xdirty (v1.1+) +B072 Dvx: xgetnump (v1.1+) +B075 Dvx: xyesno2 (v1.2+) +B078 Dvx: xdir_setup2 (v1.23+) +B07B Dvx: xshell_info (v1.25+) +C000 r:KBD w:CLR80COL +C001 w:SET80COL +C002 w:RDMAINRAM +C003 w:RDCARDRAM +C004 w:WRMAINRAM +C005 w:WRCARDRAM +C006 w:SETSLOTCXROM +C007 w:SETINTCXROM +C008 w:SETSTDZP +C009 w:SETALTZP +C00A w:SETINTC3ROM +C00B w:SETSLOTC3ROM +C00C w:CLR80VID +C00D w:SET80VID +C00E w:CLRALTCHAR +C00F w:SETALTCHAR +C010 r:KBDSTRB +C011 r:RDLCBNK2 +C012 r:RDLCRAM +C013 r:RDRAMRD +C014 r:RDRAMWRT +C015 r:RDCXROM +C016 r:RDALTZP +C017 r:RDC3ROM +C018 r:RD80COL +C019 r:RDVBLBAR +C01A r:RDTEXT +C01B r:RDMIX +C01C r:RDPAGE2 +C01D r:RDHIRES +C01E r:ALTCHARSET +C01F r:RD80VID +C020 reserved [cassette] +C021 rw:MONOCOLOR +C022 rw:TBCOLOR +C023 rw:VGCINT +C024 r:MOUSEDATA +C025 r:KEYMODREG +C026 rw:DATAREG [key micro] +C027 rw:KMSTATUS +C028 rw:ROMBANK [IIc Plus] +C029 rw:NEWVIDEO +C02B rw:LANGSEL +C02C r:CHARROM +C02D rw:SLTROMSEL +C02E r:VERTCNT +C02F r:HORIZCNT +C030 rw:SPKR +C031 rw:DISKREG +C032 w:SCANINT +C033 rw:CLOCKDATA +C034 rw:CLOCKCTL [+border color] +C035 rw:SHADOW +C036 rw:CYAREG +C037 rw:DMAREG +C038 rw:SCCBREG +C039 rw:SCCAREG +C03A rw:SCCBDATA +C03B rw:SCCADATA +C03C rw:SOUNDCTL +C03D rw:SOUNDDATA +C03E rw:SOUNDADRL +C03F rw:SOUNDADRH +C040 reserved [C040 Strobe] +C041 *rw:INTEN +C044 *r:MMDELTAX +C045 *r:MMDELTAY +C046 w:DIAGTYPE r:INTFLAG +C047 w:CLRVBLINT +C048 w:CLRXYINT +C050 rw:TXTCLR +C051 rw:TXTSET +C052 rw:MIXCLR +C053 rw:MIXSET +C054 rw:TXTPAGE1 +C055 rw:TXTPAGE2 +C056 rw:LORES +C057 rw:HIRES +C058 rw:SETAN0 +C059 rw:CLRAN0 +C05A rw:SETAN1 +C05B rw:CLRAN1 +C05C rw:SETAN2 +C05D rw:CLRAN2 +C05E rw:SETAN3 +C05F rw:CLRAN3 +C060 r:BUTN3 +C061 r:BUTN0 +C062 r:BUTN1 +C063 r:BUTN2 +C064 r:PADDL0 +C065 r:PADDL1 +C066 r:PADDL2 +C067 r:PADDL3 +C068 rw:STATEREG +C06D *TESTREG +C06E *CLTRM +C06F *ENTM +C070 rw:PTRIG +C081 rw:ROMIN +C083 rw:LCBANK2 +C08B rw:LCBANK1 +C0E0 IWM:PH0 off +C0E1 IWM:PH0 on +C0E2 IWM:PH1 off +C0E3 IWM:PH1 on +C0E4 IWM:PH2 off +C0E5 IWM:PH2 on +C0E6 IWM:PH3 off +C0E7 IWM:PH3 on +C0E8 IWM:motor off +C0E9 IWM:motor on +C0EA IWM:drive 1 +C0EB IWM:drive 2 +C0EC IWM:Q6 OFF (Read) +C0ED IWM:Q6 ON (WP-sense) +C0EE IWM:Q7 OFF (WP-sense/Read) +C0EF IWM:Q7 ON (Write) +C311 ROM:AUXMOVE +C314 ROM:XFER +CFFF rw:CLRROM +F800 F8ROM:PLOT +F80E F8ROM:PLOT1 +F819 F8ROM:HLINE +F828 F8ROM:VLINE +F832 F8ROM:CLRSCR +F836 F8ROM:CLRTOP +F847 F8ROM:GBASCALC +F85F F8ROM:NXTCOL +F864 F8ROM:SETCOL +F871 F8ROM:SCRN +F88C F8ROM:INSDS1.2 +F88E F8ROM:INSDS2 +F890 F8ROM:GET816LEN +F8D0 F8ROM:INSTDSP +F940 F8ROM:PRNTYX +F941 F8ROM:PRNTAX +F944 F8ROM:PRNTX +F948 F8ROM:PRBLNK +F94A F8ROM:PRBL2 +F953 F8ROM:PCADJ +F962 F8ROM:TEXT2COPY +FA40 F8ROM:OLDIRQ +FA4C F8ROM:BREAK +FA59 F8ROM:OLDBRK +FA62 F8ROM:RESET +FAA6 F8ROM:PWRUP +FABA F8ROM:SLOOP +FAD7 F8ROM:REGDSP +FB19 F8ROM:RTBL +FB1E F8ROM:PREAD +FB21 F8ROM:PREAD4 +FB2F F8ROM:INIT +FB39 F8ROM:SETTXT +FB40 F8ROM:SETGR +FB4B F8ROM:SETWND +FB51 F8ROM:SETWND2 +FB5B F8ROM:TABV +FB60 F8ROM:APPLEII +FB6F F8ROM:SETPWRC +FB78 F8ROM:VIDWAIT +FB88 F8ROM:KBDWAIT +FBB3 F8ROM:VERSION +FBBF F8ROM:ZIDBYTE2 +FBC0 F8ROM:ZIDBYTE +FBC1 F8ROM:BASCALC +FBDD F8ROM:BELL1 +FBE2 F8ROM:BELL1.2 +FBE4 F8ROM:BELL2 +FBF0 F8ROM:STORADV +FBF4 F8ROM:ADVANCE +FBFD F8ROM:VIDOUT +FC10 F8ROM:BS +FC1A F8ROM:UP +FC22 F8ROM:VTAB +FC24 F8ROM:VTABZ +FC42 F8ROM:CLREOP +FC58 F8ROM:HOME +FC62 F8ROM:CR +FC66 F8ROM:LF +FC70 F8ROM:SCROLL +FC9C F8ROM:CLREOL +FC9E F8ROM:CLREOLZ +FCA8 F8ROM:WAIT +FCB4 F8ROM:NXTA4 +FCBA F8ROM:NXTA1 +FCC9 F8ROM:HEADR +FD0C F8ROM:RDKEY +FD10 F8ROM:FD10 +FD18 F8ROM:RDKEY1 +FD1B F8ROM:KEYIN +FD35 F8ROM:RDCHAR +FD67 F8ROM:GETLNZ +FD6A F8ROM:GETLN +FD6C F8ROM:GETLN0 +FD6F F8ROM:GETLN1 +FD8B F8ROM:CROUT1 +FD8E F8ROM:CROUT +FD92 F8ROM:PRA1 +FDDA F8ROM:PRBYTE +FDE3 F8ROM:PRHEX +FDED F8ROM:COUT +FDF0 F8ROM:COUT1 +FDF6 F8ROM:COUTZ +FE1F F8ROM:IDROUTINE +FE2C F8ROM:MOVE +FE5E F8ROM:LIST (not on GS) +FE80 F8ROM:SETINV +FE84 F8ROM:SETNORM +FE89 F8ROM:SETKBD +FE8B F8ROM:INPORT +FE93 F8ROM:SETVID +FE95 F8ROM:OUTPORT +FEB6 F8ROM:GO +FECD F8ROM:WRITE +FEFD F8ROM:READ +FF2D F8ROM:PRERR +FF3A F8ROM:BELL +FF3F F8ROM:RESTORE +FF4A F8ROM:SAVE +FF58 F8ROM:IORTS +FF59 F8ROM:OLDRST +FF65 F8ROM:MON +FF69 F8ROM:MONZ +FF6C F8ROM:MONZ2 +FF70 F8ROM:MONZ4 +FF8A F8ROM:DIG +FFA7 F8ROM:GETNUM +FFAD F8ROM:NXTCHR +FFBE F8ROM:TOSUB +FFC7 F8ROM:ZMODE +* 01xxxx vectors +FC00 SysSrv: DEV_DISPATCHER +FC04 SysSrv: CACHE_FIND_BLK +FC08 SysSrv: CACHE_ADD_BLK +FC14 SysSrv: CACHE_DEL_BLK +FC1C SysSrv: ALLOC_SEG +FC20 SysSrv: RELEASE_SEG +FC34 SysSrv: SWAP_OUT +FC38 SysSrv: DEREF +FC50 SysSrv: SET_SYS_SPEED +FC68 SysSrv: LOCK_MEM +FC6C SysSrv: UNLOCK_MEM +FC70 SysSrv: MOVE_INFO +FC88 SysSrv: SIGNAL +FC90 SysSrv: SET_DISK_SW +FCA4 SysSrv: SUP_DRVR_DISP +FCA8 SysSrv: INSTALL_DRIVER +FCBC SysSrv: DYN_SLOT_ARBITER +FCD8 SysSrv: UNBIND_INT_VEC +* Nifty List service calls +0000 NLServ: nlRecover +0001 NLServ: nlEnter +0002 NLServ: nlRemoveNL +0003 NLServ: nlGetInfo +0004 NLServ: nlInstallHook +0005 NLServ: nlRemoveHook +0006 NLServ: nlGetDirectory():@dir +0007 NLServ: nlNewSession(@callback):sessRef +0008 NLServ: nlKillSession(sessRef) +0009 NLServ: nlSetSession(sessRef):oldRef +000A NLServ: nlWelcome +0010 NLServ: nlGetFirstHandle +0011 NLServ: nlGetHandleInfo +0012 NLServ: nlLookup +0013 NLServ: nlIndLookup +0014 NLServ: nlGetProcName(@proc):@pString +0020 NLServ: nlScanHandles +0021 NLServ: nlDisasm1 +0022 NLServ: nlExecCmdLine +0023 NLServ: nlGetRange +0024 NLServ: nlGetAGlobal(ref):value +0025 NLServ: nlSetAGlobal(@(ref,value)) +0026 NLServ: nlAbortToCmd +0030 NLServ: nlWriteChar +0031 NLServ: nlShowChar +0032 NLServ: nlWriteStr +0033 NLServ: nlShowStr +0034 NLServ: nlWriteCStr +0035 NLServ: nlShowCStr +0036 NLServ: nlWriteText +0037 NLServ: nlShowText +0038 NLServ: nlWriteByte +0039 NLServ: nlWriteWord +003A NLServ: nlWritePtr +003B NLServ: nlWriteLong +003C NLServ: nlGetLn +003D NLServ: nlGetChar +003E NLServ: nlCheckKey +003F NLServ: nlCrout +0040 NLServ: nlSpout +0041 NLServ: nlPause +0042 NLServ: nlHandleInfo +0043 NLServ: nlWriteNoVoice(@cStr) +0044 NLServ: nlShowWString(@wStr) +0050 NLServ: nlChrGet +0051 NLServ: nlChrGot +0052 NLServ: nlEatBlanks() +0054 NLServ: nlEvalExpr(@exprBuff):exprLen +0060 NLServ: nlGetByte(@addr):byte +0061 NLServ: nlGetWord(@addr):word +0062 NLServ: nlGetLong(@addr):long +* resource type names +8001 rIcon +8002 rPicture +8003 rControlList +8004 rControlTemplate +8005 rC1InputString +8006 rPString +8007 rStringList +8008 rMenuBar +8009 rMenu +800A rMenuItem +800B rTextForLETextBox2 +800C rCtlDefProc +800D rCtlColorTbl +800E rWindParam1 +800F rWindParam2 +8010 rWindColor +8011 rTextBlock +8012 rStyleBlock +8013 rToolStartup +8014 rResName +8015 rAlertString +8016 rText +8017 rCodeResource +8018 rCDEVCode +8019 rCDEVFlags +801A rTwoRects +801B rFileType +801C rListRef +801D rCString +801E rXCMD +801F rXFCN +8020 rErrorString +8021 rKTransTable +8022 rWString +8023 rC1OutputString +8024 rSoundSample +8025 rTERuler +8026 rFSequence +8027 rCursor +8028 rItemStruct +8029 rVersion +802A rComment +802B rBundle +802C rFinderPath +802D rPaletteWindow +802E rTaggedStrings +802F rPatternList +C001 rRectList +C002 rPrintRecord +C003 rFont +* Error codes +0001 OS:bad call number / dispatcher:toolset not found +0002 function not found +0004 OS:bad parameter count +0007 GS/OS is busy +0010 GS/OS:device not found +0011 GS/OS:bad device number +0020 GS/OS:invalid driver request +0021 GS/OS:invalid driver control or status code +0022 GS/OS:bad call parameter +0023 GS/OS:character device not open +0024 GS/OS:character device already open +0025 OS:interrupt table full +0026 GS/OS:resources not available +0027 OS:I/O error +0028 OS:no device connected +0029 GS/OS:driver is busy +002B OS:disk write protected +002C GS/OS:invalid byte count +002D GS/OS:invalid block address +002E OS:disk switched +002F OS:no disk +0040 OS:bad pathname +0042 OS:max number of files already open +0043 OS:bad file reference number +0044 OS:directory not found +0045 OS:volume not found +0046 OS:file not found +0047 OS:duplicate filename +0048 OS:volume full +0049 OS:volume directory full +004A OS:incompatible file format +004B OS:unsupported storage type +004C OS:end of file encountered +004D OS:position out of range +004E OS:access not allowed +004F GS/OS:buffer too small +0050 OS:file is open +0051 OS:directory damaged +0052 OS:unknown volume type +0053 OS:parameter out of range +0054 GS/OS:out of memory +0055 P8:volume control block table full +0056 P8:bad buffer address +0057 OS:duplicate volume name +0058 GS/OS:not a block device +0059 GS/OS:file level out of range +005A OS:bad bitmap address (block # too large) +005B GS/OS:invalid pathnames for ChangePath +005C GS/OS:not an executable file +005D GS/OS:Operating System not supported +005F GS/OS:too many applications on stack +0060 GS/OS:data unavailable +0061 GS/OS:end of directory +0062 GS/OS:invalid FST call class +0063 GS/OS:file doesn't have a resource fork +0064 GS/OS:invalidFSTID +0065 GS/OS:invalid FST operation +0066 GS/OS:fstCaution +0067 GS/OS:devNameErr +0068 GS/OS:devListFull +0069 GS/OS:supListFull +006A GS/OS:fstError (generic) +0070 GS/OS:resExistsErr +0071 GS/OS:resAddErr +0088 network error +0110 toolVersionErr +0111 messNotFoundErr +0112 messageOvfl +0113 srqNameTooLong +0120 reqNotAccepted +0121 duplicateName +0122 invalidSendRequest +0201 memErr (couldn't allocate memory) +0202 emptyErr +0203 notEmptyErr +0204 lockErr +0205 purgeErr +0206 handleErr +0207 idErr +0208 attrErr +0301 badInputErr +0302 noDevParamErr +0303 taskInstlErr +0304 noSigTaskErr +0305 queueDmgdErr +0306 taskNtFdErr +0307 firmTaskErr +0308 hbQueueBadErr +0309 unCnctdDevErr +030B idTagNtAvlErr +034F mtBuffTooSmall +0381 invalidTag +0382 alreadyInQueue +0390 badTimeVerb +0391 badTimeData +0401 alreadyInitialized +0402 cannotReset +0403 notInitialized +0410 screenReserved +0411 badRect +0420 notEqualChunkiness +0430 rgnAlreadyOpen +0431 rgnNotOpen +0432 rgnScanOverflow +0433 rgnFull +0440 polyAlreadyOpen +0441 polyNotOpen +0442 polyTooBig +0450 badTableNum +0451 badColorNum +0452 badScanLine +0510 daNotFound +0511 notSysWindow +0520 deskBadSelector +0601 emDupStrtUpErr +0602 emResetErr +0603 emNotActErr +0604 emBadEvtCodeErr +0605 emBadBttnNoErr +0606 emQSiz2LrgErr +0607 emNoMemQueueErr +0681 emBadEvtQErr +0682 emBadQHndlErr +0810 noDOCFndErr +0811 docAddrRngErr +0812 noSAppInitErr +0813 invalGenNumErr +0814 synthModeErr +0815 genBusyErr +0817 mstrIRQNotAssgnErr +0818 sndAlreadyStrtErr +08FF uncleamedSntIntErr +0910 cmndIncomplete +0911 cantSync +0982 adbBusy +0983 devNotAtAddr +0984 srqListFull +0B01 imBadInptParam +0B02 imIllegalChar +0B03 imOverflow +0B04 imStrOverflow +0C01 badDevType +0C02 badDevNum +0C03 badMode +0C04 unDefHW +0C05 lostDev +0C06 lostFile +0C07 badTitle +0C08 noRoom +0C09 noDevice +0C0B dupFile +0C0C notClosed +0C0D notOpen +0C0E badFormat +0C0F ringBuffOFlo +0C10 writeProtected +0C40 devErr +0E01 paramLenErr +0E02 allocateErr +0E03 taskMaskErr +0E04 compileTooLarge +0E05 cantUpdateErr +0F01 menuStarted +0F02 menuItemNotFound +0F03 menuNoStruct +0F04 dupMenuID +1001 wmNotStartedUp +1002 cmNotInitialized +1003 noCtlInList +1004 noCtlError +1005 notExtendedCtlError +1006 noCtlTargetError +1007 notExtendedCtlError +1008 canNotBeTargetError +1009 noSuchIDError +100A tooFewParmsError +100B noCtlToBeTargetError +100C noFrontWindowError +1101 idNotFound / segment not found? +1102 OMF version error +1103 idPathnameErr +1104 idNotLoadFile +1105 idBusyErr +1107 idFilVersErr +1108 idUserIDErr +1109 idSequenceErr +110A idBadRecordErr +110B idForeignSegErr +1210 picEmpty +1211 picAlreadyOpen / badRectSize? +1212 pictureError / destModeError? +121F bad picture opcode +1221 badRect +1222 badMode +1230 badGetSysIconInput +1301 missingDriver +1302 portNotOn +1303 noPrintRecord +1304 badLaserPrep +1305 badLPFile +1306 papConnNotOpen +1307 papReadWriteErr +1308 ptrConnFailed +1309 badLoadParam +130A callNotSupported +1321 startUpAlreadyMade +1401 leDupStartUpErr +1402 leResetErr +1403 leNotActiveErr +1404 leScrapErr +150A badItemType +150B newItemFailed +150C itemNotFound +150D notModalDialog +1610 badScrapType +1701 badPromptDesc +1702 badOrigNameDesc +1704 badReplyNameDesc +1705 badReplyPathDesc +1706 badCall +17FF sfNotStarted +1901 nsAlreadyInit +1902 nsSndNotInit +1921 nsNotAvail +1922 nsBadGenNum +1923 nsNotInit +1924 nsGenAlreadyOn +1925 soundWrongVer +1A00 noRoomMidiErr +1A01 noCommandErr +1A02 noRoomErr +1A03 startedErr +1A04 noNoteErr +1A05 noStartErr +1A06 instBndsErr +1A07 nsWrongVer +1B01 fmDupStartUpErr +1B02 fmResetErr +1B03 fmNotActiveErr +1B04 fmFamNotFndErr +1B05 fmFontNtFndErr +1B06 fmFontMemErr +1B07 fmSysFontErr +1B08 fmBadFamNumErr +1B09 fmBadSizeErr +1B0A fmBadNameErr +1B0B fmMenuErr +1B0C fmScaleSizeErr +1B0D fmBadParmErr +1C02 listRejectEvent +1D01 aceIsActive +1D02 aceBadDP +1D03 aceNotActive +1D04 aceNoSuchParam +1D05 aceBadMethod +1D06 aceBadSrc +1D07 aceBadDest +1D08 aceDataOverlap +1E01 resForkUsed +1E02 resBadFormat +1E03 resNoConverter +1E04 resNoCurFile +1E05 resDupID +1E06 resNotFound +1E07 resFileNotFound +1E08 resBadAppID +1E09 resNoUniqueID +1E0A resIndexRange +1E0B resSysIsOpen +1E0C resHasChanged +1E0D resDiffConverter +1E0E resDiskFull +1E0F resInvalidShutDown +1E10 resNameNotFound +1E11 resBadNameVers +1E12 resDupStartUp +1E13 resInvalidTypeOrID +2000 miStartUpErr +2001 miPacketErr +2002 miArrayErr +2003 miFullbufErr +2004 miToolsErr +2005 miOutOffErr +2007 miNoBufErr +2008 miDriverErr +2009 miBadFreqErr +200A miClockErr +200B miConflictErr +200C miNoDevErr +2080 miDevNotAvail +2081 miDevSlotBusy +2082 miDevBusy +2083 miDevOverrun +2084 miDevNoConnect +2085 miDevReadErr +2086 miDevVersion +2087 miDevIntHndlr +2110 vdNoVideoDevice +2111 vdAlreadyStarted +2112 vdInvalidSelector +2113 vdInvalidParam +21FF vdUnImplemented +2201 teAlreadyStarted +2202 teNotStarted +2203 teInvalidHandle +2204 teInvalidDescriptor +2205 teInvalidFlag +2206 teInvalidPCount +2208 teBufferOverflow +2209 teInvalidLine +220B teInvalidParameter +220C teInvalidTextBox2 +220D teNeedsTools +2301 msAlreadyStarted +2302 msNotStarted +2303 msNoDPMem +2304 msNoMemBlock +2305 msNoMiscTool +2306 msNoSoundTool +2307 msGenInUse +2308 msBadPortNum +2309 msPortBusy +230A msParamRangeErr +230B msMsgQueueFull +230C msRecBufFull +230D msOutputDisabled +230E msMessageError +230F msOutputBufFull +2310 msDriverNotStarted +2311 msDriverAlreadySet +2380 msDevNotAvail +2381 msDevSlotBusy +2382 msDevBusy +2383 msDevOverrun +2384 msDevNoConnect +2385 msDevReadErr +2386 msDevVersion +2387 msDevIntHndlr +2601 mcUnimp +2602 mcBadSpeed +2603 mcBadUnitType +2604 mcTimeOutErr +2605 mcNotLoaded +2606 mcBadAudio +2607 mcDevRtnError +2608 mcUnrecStatus +2609 mcBadSelector +260A mcFunnyData +260B mcInvalidPort +260C mcOnlyOnce +260D mcNoResMgr +260E mcItemNotThere +260F mcWasShutDown +2610 mcWasStarted +2611 mcBadChannel +2612 mcInvalidParam +2613 mcCallNotSupported +3601 terrBADIPID +3602 terrNOCONNECTION +3603 terrNORECONDATA +3604 terrLINKERROR +3605 terrSCRIPTFAILED +3606 terrCONNECTED +3607 terrSOCKETOPEN +3608 terrINITNOTFOUND +3609 terrVERSIONMISMATCH +360A terrBADTUNETABLELEN +360B terrIPIDTABLEFULL +360C terrNOICMPQUEUED +360D terrLOGINSPENDING +360E terrTCPIPNOTACTIVE +360F terrNODNSERVERS +3610 terrDNRBUSY +3611 terrNOLINKLAYER +3612 terrBADLINKLAYER +3613 terrENJOYCOKE +3614 terrNORECONSUPPORT +3615 terrUSERABORTED +3616 terrBADUSERPASS +3617 terrBADPARAMETER +3618 terrBADENVIRONMENT +3619 terrNOINCOMING +361A terrLINKBUSY +361B terrNOLINKINTERFACE +361C terrNOLINKRESPONSE +361D terrNODNRPENDING +361E terrBADALIVEMINUTES +361F terrBUFFERTOOSMALL +3620 terrNOTSERVE +3621 terrBADTRIGGERNUM +4201 fErrBadInput +4202 fErrFailed +4203 fErrCancel +4204 fErrDimmed +4205 fErrBusy +4206 fErrNotPrudent +4207 fErrBadBundle +42FF fErrNotImp +FF01 debugUnImpErr +FF02 debugBadSelErr +FF03 debugDupBreakErr +FF04 debugBreakNotSetErr +FF05 debugTableFullErr +FF06 debugTableEmptyErr +FF07 debugBreaksInErr +* HyperCardIIgs callbacks +0001 HC:SendCardMessage(@Str) +0002 HC:EvalExpr(@Str):H +0003 HC:StringLength(@Str):Length/4 +0004 HC:StringMatch(@Pattern,@Target):@Ptr +0005 HC:SendHCMessage(@Msg) +0006 HC:ZeroBytes(@Ptr,Count/4) +0007 HC:PasToZero(@Str):StringH +0008 HC:ZeroToPas(@ZeroStr,@Str) +0009 HC:StrToLong(@Str31):Long/4 +000A HC:StrToNum(@Str31):Long/4 +000B HC:StrToBool(@Str31):Boolean +000C HC:StrToExt(@Str31):@Extended +000D HC:LongToStr(posNum/4):@Str31 +000E HC:NumToStr(Num/4):@Str31 +000F HC:NumToHex(Num/4,nDigits):@Str31 +0010 HC:BoolToStr(Boolean):@Str31 +0011 HC:ExtToStr(@Extended):@Str31 +0012 HC:GetGlobal(@GlobalName):ValueH +0013 HC:SetGlobal(@GlobalName,GlobValueH) +0014 HC:GetFieldByName(cardFieldFlag,@FieldName):H +0015 HC:GetFieldByNum(cardFieldFlag,fieldNum):H +0016 HC:GetFieldByID(cardFieldFlag,fieldID):H +0017 HC:SetFieldByName(cardFieldFlag,@fieldName,ValueH) +0018 HC:SetFieldByNum(cardFieldFlag,fieldNum,ValueH) +0019 HC:SetFieldByID(cardFieldFlag,fieldID,ValueH) +001A HC:StringEqual(@Str1,@Str2):Boolean +001B HC:ReturnToPas(@ZeroStr,@Str) +001C HC:ScanToReturn(@PtrToPtr) +001D HC:ScanToZero(@PtrToPtr) +001E HC:GSToPString(GStringH):@Str +001F HC:PToGSString(@Str):GStringH +0020 HC:CopyGSString(GStringH):GString2H +0021 HC:GSConcat(GString1H,GString2H):NewGStringH +0022 HC:GSStringEqual(GString1H,GString2H):Boolean +0023 HC:GSToZero(GStringH):ZeroH +0024 HC:ZeroToGS(ZeroH):GStringH +0025 HC:LoadNamedResource(whichType,@Name):H +0026 HC:FindNamedResource(Type,@Name,@File,@ID/4):Bool +0027 HC:SetResourceName(Type,ID/4,@Name) +0028 HC:GetResourceName(Type,ID/4):@Str +0029 HC:BeginXSound() +002A HC:EndXSound() +002B HC:GetMaskAndData(@MaskLocInfo,@DataLocInfo) +002C HC:ChangedMaskAndData(whatChanged) +002D HC:PointToStr(Point/4,@String) +002E HC:RectToStr(@Rect,@String) +002F HC:StrToPoint(@String,@Point) +0030 HC:StrToRect(@String,@Rect) +0031 HC:NewXWindow(@BoundsR,@Title,visFlg,windStyle):WindowPtr +0032 HC:SetXWIdleTime(@Window,Interval/4) +0033 HC:CloseXWindow(@Window) +0034 HC:HideHCPalettes() +0035 HC:ShowHCPalettes() +0036 HC:SetXWindowValue(@Window,Value/4) +0037 HC:GetXWindowValue(@Window):Value/4 +0038 HC:XWAllowReEntrancy(@Window,SysEvts,HCEvts) +* Request Codes +0001 systemSaysBeep +0002 systemSaysUnknownDisk +0003 srqGoAway +0004 srqGetrSoundSample +0005 srqSynchronize +0006 srqPlayrSoundSample +0008 systemSaysNewDeskMsg +000C systemSaysDoClipboard +000D systemSaysForceUndim +000E systemSaysEjectingDev +0010 srqOpenOrPrint +0011 srqQuit +0100 finderSaysHello +0101 finderSaysGoodbye +0102 finderSaysSelectionChanged +0103 finderSaysMItemSelected +0104 finderSaysBeforeOpen +0105 finderSaysOpenFailed +0106 finderSaysBeforeCopy +0107 finderSaysIdle +0108 finderSaysExtrasChosen +0109 finderSaysBeforeRename +010A finderSaysKeyHit +0502 systemSaysDeskStartUp +0503 systemSaysDeskShutDown +051E systemSaysFixedAppleMenu +0F01 systemSaysMenuKey +1201 systemSaysGetSysIcon +8000 tellFinderGetDebugInfo (or srqMountServer to EasyMount) +8001 askFinderAreYouThere +8002 tellFinderOpenWindow +8003 tellFinderCloseWindow +8004 tellFinderGetSelectedIcons +8005 tellFinderSetSelectedIcons +8006 tellFinderLaunchThis +8007 tellFinderShutDown +8008 tellFinderMItemSelected +800A tellFinderMatchFileToIcon +800B tellFinderAddBundle +800C tellFinderAboutChange +800D tellFinderCheckDatabase +800E tellFinderColorSelection +800F tellFinderAddToExtras +8011 askFinderIdleHowLong +8012 tellFinderGetWindowIcons +8013 tellFinderGetWindowInfo +8014 tellFinderRemoveFromExtras +8015 tellFinderSpecialPreferences +8200 srqConvertRelPitch +9000 cpOpenCDev +9001 cpOpenControlPanels +* diff --git a/src/assets/config.txt b/src/assets/config.txt new file mode 100644 index 0000000..d62c885 --- /dev/null +++ b/src/assets/config.txt @@ -0,0 +1,46 @@ +# GSplus configuration file version 0.15 + +s5d1 = +s5d2 = + +s6d1 = +s6d2 = + +s7d1 = + +g_cfg_rom_path = ../../roms/gsrom3 + + +bram1[00] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[10] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[20] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[30] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[40] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[50] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[60] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[70] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[80] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[90] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[a0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[b0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[c0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[d0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[e0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +bram1[f0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +bram3[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00 +bram3[10] = 00 00 07 06 02 01 01 00 00 00 0f 06 06 00 05 06 +bram3[20] = 01 00 00 00 00 00 00 01 00 00 00 00 05 02 02 00 +bram3[30] = 00 00 2d 2d 00 00 00 00 00 00 02 02 02 06 08 00 +bram3[40] = 01 02 03 04 05 06 07 0a 00 01 02 03 04 05 06 07 +bram3[50] = 08 09 0a 0b 0c 0d 0e 0f 00 00 ff ff ff ff ff ff +bram3[60] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[70] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[80] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[90] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[a0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[b0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[c0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[d0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[e0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +bram3[f0] = ff ff ff ff ff ff ff ff ff ff ff ff 36 2d 9c 87 diff --git a/assets/gsp-icons.icns b/src/assets/gsp-icons.icns similarity index 100% rename from assets/gsp-icons.icns rename to src/assets/gsp-icons.icns diff --git a/src/atbridge/CMakeLists.txt b/src/atbridge/CMakeLists.txt new file mode 100644 index 0000000..7bdcac3 --- /dev/null +++ b/src/atbridge/CMakeLists.txt @@ -0,0 +1,9 @@ +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_library(atbridge aarp.c atbridge.c elap.c llap.c pcap_delay.c port.c) + +target_compile_definitions(atbridge PUBLIC HAVE_ATBRIDGE) + +if(WIN32) + target_link_libraries(atbridge ws2_32) # winsock2 +endif() diff --git a/src/atbridge/aarp.c b/src/atbridge/aarp.c index edbb925..dcb066d 100644 --- a/src/atbridge/aarp.c +++ b/src/atbridge/aarp.c @@ -17,7 +17,7 @@ #include "aarp.h" #ifdef WIN32 -#include +#include #elif __linux__ #include #endif diff --git a/src/atbridge/atbridge.c b/src/atbridge/atbridge.c index f908f2c..e2204b9 100644 --- a/src/atbridge/atbridge.c +++ b/src/atbridge/atbridge.c @@ -18,7 +18,7 @@ #include "aarp.h" #ifdef WIN32 -#include +#include #elif __linux__ #include #endif diff --git a/src/atbridge/elap.c b/src/atbridge/elap.c index 3774df4..c55c4cc 100644 --- a/src/atbridge/elap.c +++ b/src/atbridge/elap.c @@ -16,12 +16,12 @@ #include "elap_defs.h" #include "pcap_delay.h" -#ifdef __CYGWIN__ -#include -#include -#endif +// #ifdef __CYGWIN__ +// #include +// #include +// #endif #ifdef WIN32 -#include +#include #include #endif #ifdef __linux__ diff --git a/src/atbridge/pcap_delay.h b/src/atbridge/pcap_delay.h index 03e6920..329d234 100644 --- a/src/atbridge/pcap_delay.h +++ b/src/atbridge/pcap_delay.h @@ -14,13 +14,7 @@ This wrapper provides a subset of the available PCAP APIs necessary for ATBridge Feel free to extend the wrapper. */ -#ifdef WIN32 -#include "../arch/win32/pcap.h" -#elif __linux__ #include -#elif __APPLE__ -#include -#endif bool pcapdelay_load(); bool pcapdelay_is_loaded(); diff --git a/src/config.txt b/src/config.txt deleted file mode 100644 index 29464ec..0000000 --- a/src/config.txt +++ /dev/null @@ -1,45 +0,0 @@ -# GSplus configuration file version 0.10a - -s5d1 = -s5d2 = - -s6d1 = -s6d2 = - -s7d1 = - - - -bram1[00] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[10] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[20] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[30] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[40] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[50] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[60] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[70] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[80] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[90] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[a0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[b0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[c0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[d0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[e0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram1[f0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -bram3[00] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[10] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[20] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[30] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[40] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[50] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[60] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[70] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[80] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[90] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[a0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[b0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[c0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[d0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[e0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -bram3[f0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/rawnet/CMakeLists.txt b/src/rawnet/CMakeLists.txt new file mode 100644 index 0000000..a38b88b --- /dev/null +++ b/src/rawnet/CMakeLists.txt @@ -0,0 +1,28 @@ + +if(WIN32) + set(rawnetarch rawnetarch_win32.c) +elseif(APPLE) + set(rawnetarch rawnetarch_vmnet_helper.c) + #set(rawnetarch rawnetarch_unix.c) +elseif(UNIX) + set(rawnetarch rawnetarch_unix.c) +endif() + +add_library(rawnet cs8900.c rawnet.c rawnetsupp.c rawnetarch.c ${rawnetarch}) + +target_compile_definitions(rawnet PUBLIC HAVE_RAWNET) +target_compile_definitions(rawnet PRIVATE CS8900_DEBUG RAWNET_DEBUG_FRAMES) + +target_compile_options(rawnet PRIVATE -g) + +if(WIN32) + target_link_libraries(rawnet ws2_32) # winsock2 +elseif(APPLE) + #target_link_libraries(rawnet PRIVATE pcap) + #target_link_libraries(rawnet PRIVATE "-framework vmnet") + add_executable(vmnet_helper vmnet_helper.c) + target_link_libraries(vmnet_helper PRIVATE "-framework vmnet") + +elseif(UNIX) + target_link_libraries(rawnet PRIVATE pcap) +endif() \ No newline at end of file diff --git a/src/rawnet/Networking.txt b/src/rawnet/Networking.txt new file mode 100644 index 0000000..084797c --- /dev/null +++ b/src/rawnet/Networking.txt @@ -0,0 +1,35 @@ +Networking +---------- + +GS+ can emulate an Uthernet (the original) card in slot 3. Marinetti is supported with the Uthernet Link Layer. Version 1.0.2 or newer is recommended. + +Configuration: + +In the settings menu, select Ethernet Card Configuration. + +Make sure Uthernet Card in Slot 3 is set to On. + +Select the Interface menu to choose the selected interface from a menu. + +Win32: + +Ethernet support uses Winpcap or its modern successor, npcap. You need to install them. + +Winpcap/npcap require a hardwired ethernet connection in promiscuous mode -- they work by tapping into the ethernet stream. + +Interface names are not particularly meaningful. Sorry. Run `getmac /v` from cmd.exe to get a human friendly name for the interface device. + +In marinetti, hardcode the ip address, gateway, and dns servers. + +OS X: + +Ethernet support uses the vmnet framework. This provides a virtual ethernet device, dhcp server, and dns server, all bridged to the Macintosh's network. + +Unfortunately, vmnet requires root permissions or a codesigning entitlment which may only valid for applications through the Mac App Store. + +In marinetti, use DHCP. + +Linux: + +Ethernet support uses the tap ethernet device. This require setting up the device and bridging it to your local network. + diff --git a/src/rawnet/cs8900.c b/src/rawnet/cs8900.c new file mode 100644 index 0000000..616f9a4 --- /dev/null +++ b/src/rawnet/cs8900.c @@ -0,0 +1,1675 @@ +/* + * cs8900.c - CS8900 Ethernet Core + * + * Written by + * Spiro Trikaliotis + * Christian Vogelgsang + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 "vice.h" + +#ifdef HAVE_RAWNET + +#include +#include +#include +#include +//#ifdef DOS_TFE +//#include /* FIXME: remove? */ +//#endif + +//#include "archdep.h" +#include "cs8900.h" +// #include "crc32.h" +// #include "lib.h" +// #include "log.h" +// #include "monitor.h" +#include "rawnetarch.h" +#include "rawnetsupp.h" +// #include "resources.h" +// #include "snapshot.h" +// #include "types.h" +// #include "util.h" + +/* FIXME: + - add register dump +*/ + +/* warn illegal behaviour */ +/* #define CS8900_DEBUG_WARN_REG 1 */ /* warn about invalid register accesses */ +/* #define CS8900_DEBUG_WARN_RXTX 1 */ /* warn about invalid rx or tx conditions */ + +/** #define CS8900_DEBUG_INIT 1 **/ +/** #define CS8900_DEBUG_LOAD 1 **/ /* enable to see tfe port reads */ +/** #define CS8900_DEBUG_STORE 1 **/ /* enable to see tfe port writes */ +/** #define CS8900_DEBUG_REGISTERS 1 **/ /* enable to see CS8900a register I/O */ +/** #define CS8900_DEBUG_IGNORE_RXEVENT 1 **/ /* enable to ignore RXEVENT in DEBUG_REGISTERS */ +/** #define CS8900_DEBUG_RXTX_STATE 1 **/ /* enable to see tranceiver state changes */ +/** #define CS8900_DEBUG_RXTX_DATA 1 **/ /* enable to see data in/out flow */ +/** #define RAWNET_DEBUG_FRAMES 1 **/ /* enable to see arch frame send/recv - might be defined in rawnetarch.h ! */ + +/* ------------------------------------------------------------------------- */ +/* variables needed */ + +//static log_t cs8900_log = LOG_ERR; + +/* status which received packages to accept + This is used in cs8900_should_accept(). +*/ +static uint8_t cs8900_ia_mac[6] = { 0, 0, 0, 0, 0, 0 }; + +/* remember the value of the hash mask */ +static uint32_t cs8900_hash_mask[2]; + +/* reveiver setup */ +static uint16_t cs8900_recv_control = 0; /* copy of CC_RXCTL (contains all bits below) */ +static int cs8900_recv_broadcast = 0; /* broadcast */ +static int cs8900_recv_mac = 0; /* individual address (IA) */ +static int cs8900_recv_multicast = 0; /* multicast if address passes the hash filter */ +static int cs8900_recv_correct = 0; /* accept correct frames */ +static int cs8900_recv_promiscuous = 0; /* promiscuous mode */ +static int cs8900_recv_hashfilter = 0; /* accept if IA passes the hash filter */ + +/* TFE registers */ +/* these are the 8 16-bit-ports for "I/O space configuration" + (see 4.10 on page 75 of cs8900a-4.pdf, the cs8900a data sheet) + + REMARK: The TFE operates the cs8900a in IO space configuration, as + it generates I/OW and I/OR signals. +*/ +#define CS8900_COUNT_IO_REGISTER 0x10 /* we have 16 I/O register */ + +static uint8_t *cs8900 = NULL; +/* + RW: RXTXDATA = DE00/DE01 + RW: RXTXDATA2 = DE02/DE03 (for 32-bit-operation) + -W: TXCMD = DE04/DE05 (TxCMD, Transmit Command) mapped to PP + 0144 (Reg. 9, Sec. 4.4, page 46) + -W: TXLENGTH = DE06/DE07 (TxLenght, Transmit Length) mapped to PP + 0146 + R-: INTSTQUEUE = DE08/DE09 (Interrupt Status Queue) mapped to PP + 0120 (ISQ, Sec. 5.1, page 78) + RW: PP_PTR = DE0A/DE0B (PacketPage Pointer) (see. page 75p: Read -011.---- ----.----) + RW: PP_DATA0 = DE0C/DE0D (PacketPage Data (Port 0)) + RW: PP_DATA1 = DE0E/DE0F (PacketPage Data (Port 1)) (for 32 bit only) +*/ + +#define CS8900_ADDR_RXTXDATA 0x00 /* RW */ +#define CS8900_ADDR_RXTXDATA2 0x02 /* RW 32 bit only! */ +#define CS8900_ADDR_TXCMD 0x04 /* -W Maps to PP+0144 */ +#define CS8900_ADDR_TXLENGTH 0x06 /* -W Maps to PP+0146 */ +#define CS8900_ADDR_INTSTQUEUE 0x08 /* R- Interrupt status queue, maps to PP + 0120 */ +#define CS8900_ADDR_PP_PTR 0x0a /* RW PacketPage Pointer */ +#define CS8900_ADDR_PP_DATA 0x0c /* RW PacketPage Data, Port 0 */ +#define CS8900_ADDR_PP_DATA2 0x0e /* RW PacketPage Data, Port 1 - 32 bit only */ + +/* Makros for reading and writing the visible TFE register: */ +#define GET_CS8900_8(_xxx_) (assert(_xxx_ < CS8900_COUNT_IO_REGISTER), cs8900[_xxx_]) + +#define SET_CS8900_8(_xxx_, _val_) \ + do { \ + assert(_xxx_ < CS8900_COUNT_IO_REGISTER); \ + cs8900[_xxx_] = (_val_) & 0xff; \ + } while (0) + +#define GET_CS8900_16(_xxx_) (assert(_xxx_ < CS8900_COUNT_IO_REGISTER), cs8900[_xxx_] | (cs8900[_xxx_ + 1] << 8)) + +#define SET_CS8900_16(_xxx_, _val_) \ + do { \ + assert(_xxx_ < CS8900_COUNT_IO_REGISTER); \ + cs8900[_xxx_] = (_val_) & 0xff; \ + cs8900[_xxx_ + 1] = (_val_ >> 8) & 0xff; \ + } while (0) + +/* The PacketPage register */ +/* note: The locations 0 to MAX_PACKETPAGE_ARRAY-1 are handled in this array. */ + +#define MAX_PACKETPAGE_ARRAY 0x1000 /* 4 KB */ + +static uint8_t *cs8900_packetpage = NULL; + +static uint16_t cs8900_packetpage_ptr = 0; + +/* Makros for reading and writing the PacketPage register: */ + +#define GET_PP_8(_xxx_) (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), cs8900_packetpage[_xxx_]) + +#define GET_PP_16(_xxx_) (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), assert((_xxx_ & 1) == 0), ((uint16_t)cs8900_packetpage[_xxx_]) | ((uint16_t)cs8900_packetpage[_xxx_ + 1] << 8)) + +#define GET_PP_32(_xxx_) \ + (assert(_xxx_ < MAX_PACKETPAGE_ARRAY), assert((_xxx_ & 3) == 0), \ + (((long)cs8900_packetpage[_xxx_])) | (((long)cs8900_packetpage[_xxx_ + 1]) << 8) | (((long)cs8900_packetpage[_xxx_ + 2]) << 16) | (((long)cs8900_packetpage[_xxx_ + 3]) << 24)) + +#define SET_PP_8(_xxx_, _val_) \ + do { \ + assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ + cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ + } while (0) + +#define SET_PP_16(_xxx_, _val_) \ + do { \ + assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ + assert((_xxx_ & 1) == 0), \ + cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ + cs8900_packetpage[_xxx_ + 1] = (_val_ >> 8) & 0xFF; \ + } while (0) + +#define SET_PP_32(_xxx_, _val_) \ + do { \ + assert(_xxx_ < MAX_PACKETPAGE_ARRAY); \ + assert((_xxx_ & 3) == 0), \ + cs8900_packetpage[_xxx_] = (_val_) & 0xFF; \ + cs8900_packetpage[_xxx_ + 1] = (_val_ >> 8) & 0xFF; \ + cs8900_packetpage[_xxx_ + 2] = (_val_ >> 16) & 0xFF; \ + cs8900_packetpage[_xxx_ + 3] = (_val_ >> 24) & 0xFF; \ + } while (0) + +/* The packetpage register: see p. 39f */ +#define CS8900_PP_ADDR_PRODUCTID 0x0000 /* R- - 4.3., p. 41 */ +#define CS8900_PP_ADDR_IOBASE 0x0020 /* i RW - 4.3., p. 41 - 4.7., p. 72 */ +#define CS8900_PP_ADDR_INTNO 0x0022 /* i RW - 3.2., p. 17 - 4.3., p. 41 */ +#define CS8900_PP_ADDR_DMA_CHAN 0x0024 /* i RW - 3.2., p. 17 - 4.3., p. 41 */ +#define CS8900_PP_ADDR_DMA_SOF 0x0026 /* ? R- - 4.3., p. 41 - 5.4., p. 89 */ +#define CS8900_PP_ADDR_DMA_FC 0x0028 /* ? R- - 4.3., p. 41, "Receive DMA" */ +#define CS8900_PP_ADDR_RXDMA_BC 0x002a /* ? R- - 4.3., p. 41 - 5.4., p. 89 */ +#define CS8900_PP_ADDR_MEMBASE 0x002c /* i RW - 4.3., p. 41 - 4.9., p. 73 */ +#define CS8900_PP_ADDR_BPROM_BASE 0x0030 /* i RW - 3.6., p. 24 - 4.3., p. 41 */ +#define CS8900_PP_ADDR_BPROM_MASK 0x0034 /* i RW - 3.6., p. 24 - 4.3., p. 41 */ + +/* 0x0038 - 0x003F: reserved */ +#define CS8900_PP_ADDR_EEPROM_CMD 0x0040 /* i RW - 3.5., p. 23 - 4.3., p. 41 */ +#define CS8900_PP_ADDR_EEPROM_DATA 0x0042 /* i RW - 3.5., p. 23 - 4.3., p. 41 */ + +/* 0x0044 - 0x004F: reserved */ +#define CS8900_PP_ADDR_REC_FRAME_BC 0x0050 /* RW - 4.3., p. 41 - 5.2.9., p. 86 */ + +/* 0x0052 - 0x00FF: reserved */ +#define CS8900_PP_ADDR_CONF_CTRL 0x0100 /* - RW - 4.4., p. 46; see below */ +#define CS8900_PP_ADDR_STATUS_EVENT 0x0120 /* - R- - 4.4., p. 46; see below */ + +/* 0x0140 - 0x0143: reserved */ +#define CS8900_PP_ADDR_TXCMD 0x0144 /* # -W - 4.5., p. 70 - 5.7., p. 98 */ +#define CS8900_PP_ADDR_TXLENGTH 0x0146 /* # -W - 4.5., p. 70 - 5.7., p. 98 */ + +/* 0x0148 - 0x014F: reserved */ +#define CS8900_PP_ADDR_LOG_ADDR_FILTER 0x0150 /* RW - 4.6., p. 71 - 5.3., p. 86 */ +#define CS8900_PP_ADDR_MAC_ADDR 0x0158 /* # RW - 4.6., p. 71 - 5.3., p. 86 */ + +/* 0x015E - 0x03FF: reserved */ +#define CS8900_PP_ADDR_RXSTATUS 0x0400 /* R- - 4.7., p. 72 - 5.2., p. 78 */ +#define CS8900_PP_ADDR_RXLENGTH 0x0402 /* R- - 4.7., p. 72 - 5.2., p. 78 */ +#define CS8900_PP_ADDR_RX_FRAMELOC 0x0404 /* R- - 4.7., p. 72 - 5.2., p. 78 */ + +/* here, the received frame is stored */ +#define CS8900_PP_ADDR_TX_FRAMELOC 0x0A00 /* -W - 4.7., p. 72 - 5.7., p. 98 */ + +/* here, the frame to transmit is stored */ +#define CS8900_PP_ADDR_END 0x1000 /* memory to TFE_PP_ADDR_END-1 is used */ + +/* TFE_PP_ADDR_CONF_CTRL is subdivided: */ +#define CS8900_PP_ADDR_CC_RXCFG 0x0102 /* # RW - 4.4.6., p. 52 - 0003 */ +#define CS8900_PP_ADDR_CC_RXCTL 0x0104 /* # RW - 4.4.8., p. 54 - 0005 */ +#define CS8900_PP_ADDR_CC_TXCFG 0x0106 /* RW - 4.4.9., p. 55 - 0007 */ +#define CS8900_PP_ADDR_CC_TXCMD 0x0108 /* R- - 4.4.11., p. 57 - 0009 */ +#define CS8900_PP_ADDR_CC_BUFCFG 0x010A /* RW - 4.4.12., p. 58 - 000B */ +#define CS8900_PP_ADDR_CC_LINECTL 0x0112 /* # RW - 4.4.16., p. 62 - 0013 */ +#define CS8900_PP_ADDR_CC_SELFCTL 0x0114 /* RW - 4.4.18., p. 64 - 0015 */ +#define CS8900_PP_ADDR_CC_BUSCTL 0x0116 /* RW - 4.4.20., p. 66 - 0017 */ +#define CS8900_PP_ADDR_CC_TESTCTL 0x0118 /* RW - 4.4.22., p. 68 - 0019 */ + +/* CS8900_PP_ADDR_STATUS_EVENT is subdivided: */ +#define CS8900_PP_ADDR_SE_ISQ 0x0120 /* R- - 4.4.5., p. 51 - 0000 */ +#define CS8900_PP_ADDR_SE_RXEVENT 0x0124 /* # R- - 4.4.7., p. 53 - 0004 */ +#define CS8900_PP_ADDR_SE_TXEVENT 0x0128 /* R- - 4.4.10., p. 56 - 0008 */ +#define CS8900_PP_ADDR_SE_BUFEVENT 0x012C /* R- - 4.4.13., p. 59 - 000C */ +#define CS8900_PP_ADDR_SE_RXMISS 0x0130 /* R- - 4.4.14., p. 60 - 0010 */ +#define CS8900_PP_ADDR_SE_TXCOL 0x0132 /* R- - 4.4.15., p. 61 - 0012 */ +#define CS8900_PP_ADDR_SE_LINEST 0x0134 /* R- - 4.4.17., p. 63 - 0014 */ +#define CS8900_PP_ADDR_SE_SELFST 0x0136 /* R- - 4.4.19., p. 65 - 0016 */ +#define CS8900_PP_ADDR_SE_BUSST 0x0138 /* # R- - 4.4.21., p. 67 - 0018 */ +#define CS8900_PP_ADDR_SE_TDR 0x013C /* R- - 4.4.23., p. 69 - 001C */ + +/* ------------------------------------------------------------------------- */ +/* more variables needed */ + +static uint16_t tx_buffer = CS8900_PP_ADDR_TX_FRAMELOC; +static uint16_t rx_buffer = CS8900_PP_ADDR_RXSTATUS; + +static uint16_t tx_count = 0; +static uint16_t rx_count = 0; +static uint16_t tx_length = 0; +static uint16_t rx_length = 0; + +#define CS8900_TX_IDLE 0 +#define CS8900_TX_GOT_CMD 1 +#define CS8900_TX_GOT_LEN 2 +#define CS8900_TX_READ_BUSST 3 + +#define CS8900_RX_IDLE 0 +#define CS8900_RX_GOT_FRAME 1 + +/* tranceiver state */ +static int tx_state = CS8900_TX_IDLE; +static int rx_state = CS8900_RX_IDLE; +static int tx_enabled = 0; +static int rx_enabled = 0; + +static int rxevent_read_mask = 3; /* set if L and/or H byte was read in RXEVENT? */ + +/* ------------------------------------------------------------------------- */ +/* some parameter definitions */ + +#define MAX_TXLENGTH 1518 +#define MIN_TXLENGTH 4 + +#define MAX_RXLENGTH 1518 +#define MIN_RXLENGTH 64 + +/* ------------------------------------------------------------------------- */ +/* debugging functions */ + +#ifdef RAWNET_DEBUG_FRAMES + +#define MAXLEN_DEBUG 1600 + +static int cs8900DebugMaxFrameLengthToDump = 150; + +static char *debug_outbuffer(const int length, const unsigned char * const buffer) +{ + int i; + static char outbuffer[MAXLEN_DEBUG * 4 + 1]; + char *p = outbuffer; + + assert(cs8900DebugMaxFrameLengthToDump <= MAXLEN_DEBUG); + + *p = 0; + + for (i = 0; i < cs8900DebugMaxFrameLengthToDump; i++) { + if (i >= length) { + break; + } + sprintf( p, "%02X%c", buffer[i], ((i + 1) % 16 == 0) ? '*' : (((i + 1) % 8 == 0) ? '-' : ' ')); + p += 3; + } + + return outbuffer; +} +#endif + +/* ------------------------------------------------------------------------- */ +/* initialization and deinitialization functions */ + +static void cs8900_set_tx_status(int ready, int error) +{ + uint16_t old_status = GET_PP_16(CS8900_PP_ADDR_SE_BUSST); + + /* mask out TxBidErr and Rdy4TxNOW */ + uint16_t new_status = old_status & ~0x180; + if (ready) { + new_status |= 0x100; /* set Rdy4TxNOW */ + } + if (error) { + new_status |= 0x080; /* set TxBidErr */ + } + + if (new_status != old_status) { + SET_PP_16(CS8900_PP_ADDR_SE_BUSST, new_status); +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: set status Rdy4TxNOW=%d TxBidErr=%d", ready, error); +#endif + } +} + +static void cs8900_set_receiver(int enabled) +{ + rx_enabled = enabled; + rx_state = CS8900_RX_IDLE; + + rxevent_read_mask = 3; /* was L or H byte read in RXEVENT? */ +} + +static void cs8900_set_transmitter(int enabled) +{ + tx_enabled = enabled; + tx_state = CS8900_TX_IDLE; + + cs8900_set_tx_status(0, 0); +} + +void cs8900_reset(void) +{ + int i; + + assert(cs8900); + assert(cs8900_packetpage); + + rawnet_arch_pre_reset(); + + /* initialize visible IO register and PacketPage registers */ + memset(cs8900, 0, CS8900_COUNT_IO_REGISTER); + memset(cs8900_packetpage, 0, MAX_PACKETPAGE_ARRAY); + + /* according to page 19 unless stated otherwise */ + SET_PP_32(CS8900_PP_ADDR_PRODUCTID, 0x0900630E ); /* p.41: 0E630009 for Rev. D; reversed order! */ + SET_PP_16(CS8900_PP_ADDR_IOBASE, 0x0300); + SET_PP_16(CS8900_PP_ADDR_INTNO, 0x0004); /* xxxx xxxx xxxx x100b */ + SET_PP_16(CS8900_PP_ADDR_DMA_CHAN, 0x0003); /* xxxx xxxx xxxx xx11b */ + + /* according to descriptions of the registers, see definitions of + CS8900_PP_ADDR_CC_... and CS8900_PP_ADDR_SE_... above! */ + + SET_PP_16(CS8900_PP_ADDR_CC_RXCFG, 0x0003); + SET_PP_16(CS8900_PP_ADDR_CC_RXCTL, 0x0005); + SET_PP_16(CS8900_PP_ADDR_CC_TXCFG, 0x0007); + SET_PP_16(CS8900_PP_ADDR_CC_TXCMD, 0x0009); + SET_PP_16(CS8900_PP_ADDR_CC_BUFCFG, 0x000B); + SET_PP_16(CS8900_PP_ADDR_CC_LINECTL, 0x0013); + SET_PP_16(CS8900_PP_ADDR_CC_SELFCTL, 0x0015); + SET_PP_16(CS8900_PP_ADDR_CC_BUSCTL, 0x0017); + SET_PP_16(CS8900_PP_ADDR_CC_TESTCTL, 0x0019); + + SET_PP_16(CS8900_PP_ADDR_SE_ISQ, 0x0000); + SET_PP_16(CS8900_PP_ADDR_SE_RXEVENT, 0x0004); + SET_PP_16(CS8900_PP_ADDR_SE_TXEVENT, 0x0008); + SET_PP_16(CS8900_PP_ADDR_SE_BUFEVENT, 0x000C); + SET_PP_16(CS8900_PP_ADDR_SE_RXMISS, 0x0010); + SET_PP_16(CS8900_PP_ADDR_SE_TXCOL, 0x0012); + /* according to specs the reset value is 0x0014, however we also set + bit 7 - Link OK + bit 9 - 10Base-T + bit 12 - Polarity OK + which makes 0x1294 ... because some software might check these and + expects them to be "Up". + FIXME: we should perhaps maintain these bits elsewhere + */ + SET_PP_16(CS8900_PP_ADDR_SE_LINEST, 0x1294); + SET_PP_16(CS8900_PP_ADDR_SE_SELFST, 0x0016); + SET_PP_16(CS8900_PP_ADDR_SE_BUSST, 0x0018); + SET_PP_16(CS8900_PP_ADDR_SE_TDR, 0x001C); + + SET_PP_16(CS8900_PP_ADDR_TXCMD, 0x0009); + + /* 4.4.19 Self Status Register, p. 65 + Important: set INITD (Bit 7) to signal device is ready */ + SET_PP_16(CS8900_PP_ADDR_SE_SELFST, 0x0896); + + cs8900_recv_control = GET_PP_16(CS8900_PP_ADDR_CC_RXCTL); + + /* spec: mac address is undefined after reset. + real HW: keeps the last set address. */ + for (i = 0; i < 6; i++) { + SET_PP_8(CS8900_PP_ADDR_MAC_ADDR + i, cs8900_ia_mac[i]); + } + + /* reset state */ + cs8900_set_transmitter(0); + cs8900_set_receiver(0); + + rawnet_arch_post_reset(); + + log_message(cs8900_log, "CS8900a rev.D reset"); +} + +int cs8900_activate(const char *net_interface) +{ + assert(cs8900 == NULL); + assert(cs8900_packetpage == NULL); + +#ifdef CS8900_DEBUG + log_message(cs8900_log, "cs8900_activate()."); +#endif + + /* allocate memory for visible IO register */ + cs8900 = lib_malloc(CS8900_COUNT_IO_REGISTER); + if (cs8900 == NULL) { +#ifdef CS8900_DEBUG_INIT + log_message(cs8900_log, "cs8900_activate: Allocating cs8900 failed."); +#endif + return -1; + } + + /* allocate memory for PacketPage register */ + cs8900_packetpage = lib_malloc(MAX_PACKETPAGE_ARRAY); + if (cs8900_packetpage == NULL) { +#ifdef CS8900_DEBUG_INIT + log_message(cs8900_log, "cs8900_activate: Allocating cs8900_packetpage failed."); +#endif + lib_free(cs8900); + cs8900 = NULL; + return -1; + } + +#ifdef CS8900_DEBUG_INIT + log_message(cs8900_log, "cs8900_activate: Allocated memory successfully."); + log_message(cs8900_log, "\tcs8900 at $%08X, cs8900_packetpage at $%08X", cs8900, cs8900_packetpage); +#endif + + if (!rawnet_arch_activate(net_interface)) { + lib_free(cs8900_packetpage); + lib_free(cs8900); + cs8900 = NULL; + cs8900_packetpage = NULL; + return -2; + } + + /* virtually reset the LAN chip */ + cs8900_reset(); + return 0; +} + +int cs8900_deactivate(void) +{ +#ifdef CS8900_DEBUG + log_message(cs8900_log, "cs8900_deactivate()."); +#endif + + assert(cs8900 && cs8900_packetpage); + + rawnet_arch_deactivate(); + + lib_free(cs8900); + cs8900 = NULL; + lib_free(cs8900_packetpage); + cs8900_packetpage = NULL; + return 0; +} + +void cs8900_shutdown(void) +{ +#ifdef CS8900_DEBUG + log_message(cs8900_log, "cs8900_shutdown()."); +#endif + + assert((cs8900 && cs8900_packetpage) || (!cs8900 && !cs8900_packetpage)); + + if (cs8900) { +#ifdef CS8900_DEBUG + log_message(cs8900_log, "...1"); +#endif + cs8900_deactivate(); + } + +#ifdef CS8900_DEBUG + log_message(cs8900_log, "cs8900_shutdown() done."); +#endif +} + +int cs8900_init(void) +{ + //cs8900_log = log_open("CS8900"); + if (!rawnet_arch_init()) { + return -1; + } + return 0; +} + +/* ------------------------------------------------------------------------- */ +/* reading and writing CS8900 register functions */ + +/* +These registers are currently fully or partially supported: + +CS8900_PP_ADDR_CC_RXCFG 0x0102 * # RW - 4.4.6., p. 52 - 0003 * +CS8900_PP_ADDR_CC_RXCTL 0x0104 * # RW - 4.4.8., p. 54 - 0005 * +CS8900_PP_ADDR_CC_LINECTL 0x0112 * # RW - 4.4.16., p. 62 - 0013 * +CS8900_PP_ADDR_SE_RXEVENT 0x0124 * # R- - 4.4.7., p. 53 - 0004 * +CS8900_PP_ADDR_SE_BUSST 0x0138 * # R- - 4.4.21., p. 67 - 0018 * +CS8900_PP_ADDR_TXCMD 0x0144 * # -W - 4.5., p. 70 - 5.7., p. 98 * +CS8900_PP_ADDR_TXLENGTH 0x0146 * # -W - 4.5., p. 70 - 5.7., p. 98 * +CS8900_PP_ADDR_MAC_ADDR 0x0158 * # RW - 4.6., p. 71 - 5.3., p. 86 * + 0x015a + 0x015c +*/ + +#ifdef RAWNET_DEBUG_FRAMES +#define return( _x_ ) \ + { \ + int retval = _x_; \ + \ + log_message(cs8900_log, "%s correct_mac=%u, broadcast=%u, multicast=%u, hashed=%u, hash_index=%u", \ + (retval ? "+++ ACCEPTED" : "--- rejected"), *pcorrect_mac, *pbroadcast, *pmulticast, *phashed, *phash_index); \ + return retval; \ + } +#endif + +/* + This is a helper for cs8900_receive() to determine if the received frame should be accepted + according to the settings. + + This function is even allowed to be called in rawnetarch.c from rawnet_arch_receive() + (via rawnet_should_accept) if necessary, and must be registered using rawnet_set_should_accept_func, + which is the reason why its prototype is included in cs8900.h. +*/ +int cs8900_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast) +{ + int hashreg; /* Hash Register (for hash computation) */ + + assert(length >= 6); /* we need at least 6 octets since the DA has this length */ + + /* first of all, delete any status */ + *phashed = 0; + *phash_index = 0; + *pcorrect_mac = 0; + *pbroadcast = 0; + *pmulticast = 0; + +#ifdef RAWNET_DEBUG_FRAMES + log_message(cs8900_log, "cs8900_should_accept called with %02X:%02X:%02X:%02X:%02X:%02X, length=%4u and buffer %s", + cs8900_ia_mac[0], cs8900_ia_mac[1], cs8900_ia_mac[2], cs8900_ia_mac[3], cs8900_ia_mac[4], cs8900_ia_mac[5], length, debug_outbuffer(length, buffer)); +#endif + + if (buffer[0] == cs8900_ia_mac[0] && buffer[1] == cs8900_ia_mac[1] && buffer[2] == cs8900_ia_mac[2] && buffer[3] == cs8900_ia_mac[3] && buffer[4] == cs8900_ia_mac[4] && buffer[5] == cs8900_ia_mac[5]) { + /* this is our individual address (IA) */ + + *pcorrect_mac = 1; + + /* if we don't want "correct MAC", we might have the chance + * that this address fits the hash index + */ + if (cs8900_recv_mac || cs8900_recv_promiscuous) { + return(1); + } + } + + if (buffer[0] == 0xFF && buffer[1] == 0xFF && buffer[2] == 0xFF && buffer[3] == 0xFF && buffer[4] == 0xFF && buffer[5] == 0xFF) { + /* this is a broadcast address */ + *pbroadcast = 1; + + /* broadcasts cannot be accepted by the hash filter */ + return ((cs8900_recv_broadcast || cs8900_recv_promiscuous) ? 1 : 0); + } + + /* now check if DA passes the hash filter */ + hashreg = (~crc32_buf((char *)buffer, 6) >> 26) & 0x3F; + + *phashed = (cs8900_hash_mask[(hashreg >= 32) ? 1 : 0] & (1 << (hashreg & 0x1F))) ? 1 : 0; + if (*phashed) { + *phash_index = hashreg; + + if (buffer[0] & 0x80) { + /* we have a multicast address */ + *pmulticast = 1; + + /* if the multicast address fits into the hash filter, + * the hashed bit has to be clear + */ + *phashed = 0; + + return ((cs8900_recv_multicast || cs8900_recv_promiscuous) ? 1 : 0); + } + return ((cs8900_recv_hashfilter || cs8900_recv_promiscuous) ? 1 : 0); + } + + return(cs8900_recv_promiscuous ? 1 : 0); +} + +#ifdef RAWNET_DEBUG_FRAMES + #undef return +#endif + +/* buffer - where to store a frame */ +/* &len - length of received frame */ +/* &hashed - set if the dest. address is accepted by the hash filter */ +/* &hash_index - hash table index if hashed == TRUE */ +/* &rx_ok - set if good CRC and valid length */ +/* &correct_mac - set if dest. address is exactly our IA */ +/* &broadcast - set if dest. address is a broadcast address */ +/* &crc_error - set if received frame had a CRC error */ + +static uint16_t cs8900_receive(void) +{ + uint16_t ret_val = 0x0004; + + uint8_t buffer[MAX_RXLENGTH]; + + int len; + int hashed; + int hash_index; + int rx_ok; + int correct_mac; + int broadcast; + int multicast = 0; /* avoid warning */ + int crc_error; + + int newframe; + + int ready; + + do { + len = MAX_RXLENGTH; + + ready = 1; /* assume we will find a good frame */ + + newframe = rawnet_arch_receive(buffer, &len, &hashed, &hash_index, &rx_ok, &correct_mac, &broadcast, &crc_error); + + assert((len & 1) == 0); /* length has to be even! */ + + if (newframe) { + if (hashed || correct_mac || broadcast) { + /* we already know the type of frame: Trust it! */ +#ifdef RAWNET_DEBUG_FRAMES + log_message( cs8900_log, "+++ cs8900_receive(): *** hashed=%u, correct_mac=%u, broadcast=%u", hashed, correct_mac, broadcast); +#endif + } else { + /* determine ourself the type of frame */ + if (!cs8900_should_accept(buffer, len, &hashed, &hash_index, &correct_mac, &broadcast, &multicast)) { + /* if we should not accept this frame, just do nothing + * now, look for another one */ + ready = 0; /* try another frame */ + continue; + } + } + + /* we did receive a frame, return that status */ + ret_val |= rx_ok ? 0x0100 : 0; + ret_val |= multicast ? 0x0200 : 0; + + if (!multicast) { + ret_val |= hashed ? 0x0040 : 0; + } + + if (hashed && rx_ok) { + /* we have the 2nd, special format with hash index: */ + assert(hash_index < 64); + ret_val |= hash_index << 9; + } else { + /* we have the regular format */ + ret_val |= correct_mac ? 0x0400 : 0; + ret_val |= broadcast ? 0x0800 : 0; + ret_val |= crc_error ? 0x1000 : 0; + ret_val |= (len < MIN_RXLENGTH) ? 0x2000 : 0; + ret_val |= (len > MAX_RXLENGTH) ? 0x4000 : 0; + } + + /* discard any octets that are beyond the MAX_RXLEN */ + if (len > MAX_RXLENGTH) { + len = MAX_RXLENGTH; + } + + if (rx_ok) { + int i; + + /* set relevant parts of the PP area to correct values */ + SET_PP_16(CS8900_PP_ADDR_RXLENGTH, len); + + for (i = 0; i < len; i++) { + SET_PP_8(CS8900_PP_ADDR_RX_FRAMELOC + i, buffer[i]); + } + + /* set rx_buffer to where start reading * + * According to 4.10.9 (pp. 76-77), we start with RxStatus and RxLength! + */ + rx_buffer = CS8900_PP_ADDR_RXSTATUS; + rx_length = len; + rx_count = 0; +#ifdef CS8900_DEBUG_WARN_RXTX + if (rx_state != CS8900_RX_IDLE) { + log_message(cs8900_log, "WARNING! New frame overwrites pending one!"); + } +#endif + rx_state = CS8900_RX_GOT_FRAME; +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "RX: recvd frame (length=%04x,status=%04x)", rx_length, ret_val); +#endif + } + } + } while (!ready); + +#ifdef RAWNET_DEBUG_FRAMES + if (ret_val != 0x0004) { + log_message( cs8900_log, "+++ cs8900_receive(): ret_val=%04X", ret_val); + } +#endif + + return ret_val; +} + +/* ------------------------------------------------------------------------- */ +/* TX/RX buffer handling */ + +static void cs8900_write_tx_buffer(uint8_t value, int odd_address) +{ + /* write tx data only if valid buffer is ready */ + if (tx_state != CS8900_TX_READ_BUSST) { +#ifdef CS8900_DEBUG_WARN_RXTX + log_message(cs8900_log, "WARNING! Ignoring TX Write without correct Transmit Condition! (odd=%d,value=%02x)", odd_address, value); +#endif + /* ensure correct tx state (needed if transmit < 4 was started) */ + cs8900_set_tx_status(0, 0); + } else { +#ifdef CS8900_DEBUG_RXTX_STATE + if (tx_count == 0) { + log_message(cs8900_log, "TX: write frame (length=%04x)", tx_length); + } +#endif + + /* always write LH, LH... to tx buffer */ + uint16_t addr = tx_buffer; + if (odd_address) { + addr++; + tx_buffer += 2; + } + tx_count++; + SET_PP_8(addr, value); + +#ifdef CS8900_DEBUG_RXTX_DATA + log_message(cs8900_log, "TX: %04x/%04x: %02x (buffer=%04x,odd=%d)", tx_count, tx_length, value, addr, odd_address); +#endif + + /* full frame transmitted? */ + if (tx_count == tx_length) { +#ifdef RAWNET_DEBUG_FRAMES + log_message(cs8900_log, "rawnet_arch_transmit() called with: length=%4u and buffer %s", tx_length, debug_outbuffer(tx_length, &cs8900_packetpage[CS8900_PP_ADDR_TX_FRAMELOC])); +#endif + + if (!tx_enabled) { +#ifdef CS8900_DEBUG_WARN_RXTX + log_message(cs8900_log, "WARNING! Can't transmit frame (Transmitter is not enabled)!"); +#endif + } else { + /* send frame */ + uint16_t txcmd = GET_PP_16(CS8900_PP_ADDR_CC_TXCMD); + rawnet_arch_transmit( + txcmd & 0x0100 ? 1 : 0, /* FORCE: Delete waiting frames in transmit buffer */ + txcmd & 0x0200 ? 1 : 0, /* ONECOLL: Terminate after just one collision */ + txcmd & 0x1000 ? 1 : 0, /* INHIBITCRC: Do not append CRC to the transmission */ + txcmd & 0x2000 ? 1 : 0, /* TXPADDIS: Disable padding to 60/64 octets */ + tx_length, &cs8900_packetpage[CS8900_PP_ADDR_TX_FRAMELOC]); + } + + /* reset transmitter state */ + tx_state = CS8900_TX_IDLE; + +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: sent frame (length=%04x)", tx_length); +#endif + + /* reset tx status */ + cs8900_set_tx_status(0, 0); + } + } +} + +static uint8_t cs8900_read_rx_buffer(int odd_address) +{ + if (rx_state != CS8900_RX_GOT_FRAME) { +#ifdef CS8900_DEBUG_WARN_RXTX + log_message(cs8900_log, "WARNING! RX Read without frame available! (odd=%d)", odd_address); +#endif + /* always reads zero on HW */ + return 0; + } else { + /* + According to the CS8900 spec, the handling is the following: + first read H, then L (RX_STATUS), then H, then L (RX_LENGTH). + Inside the RX frame data, we always get L then H, until the end is reached. + + even odd + CS8900_PP_ADDR_RXSTATUS: - proceed + CS8900_PP_ADDR_RXLENGTH: - proceed + CS8900_PP_ADDR_RX_FRAMELOC: - - + CS8900_PP_ADDR_RX_FRAMELOC+2: proceed - + CS8900_PP_ADDR_RX_FRAMELOC+4: proceed - + + */ + uint16_t addr = odd_address ? 1 : 0; + uint8_t value; + + /* read RXSTATUS or RX_LENGTH */ + if (rx_count < 4) { + addr += rx_buffer; + value = GET_PP_8(addr); + rx_count++; + + /* incr after RXSTATUS or RX_LENGTH even (L) read */ + if (!odd_address) { + rx_buffer += 2; + } + } else { + /* read frame data */ + + /* incr before frame read (but not in first word) */ + if ((rx_count >= 6) && (!odd_address)) { + rx_buffer += 2; + } + + addr += rx_buffer; + value = GET_PP_8(addr); + rx_count++; + } + +#ifdef CS8900_DEBUG_RXTX_DATA + log_message(cs8900_log, "RX: %04x/%04x: %02x (buffer=%04x,odd=%d)", rx_count, rx_length + 4, value, addr, odd_address); +#endif + + /* check frame end */ + if (rx_count >= rx_length + 4) { + /* reset receiver state to idle */ + rx_state = CS8900_RX_IDLE; +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "RX: read frame (length=%04x)", rx_length); +#endif + } + return value; + } +} + +/* ------------------------------------------------------------------------- */ +/* handle side-effects of read and write operations */ + +#define on_off_str(x) ((x) ? on_off[0] : on_off[1]) + +/* + This is called *after* the relevant octets are written +*/ +static void cs8900_sideeffects_write_pp(uint16_t ppaddress, int odd_address) +{ + const char *on_off[2] = { "on", "off" }; + uint16_t content = GET_PP_16( ppaddress ); + + assert((ppaddress & 1) == 0); + + switch (ppaddress) { + case CS8900_PP_ADDR_CC_RXCFG: + /* Skip_1 Flag: remove current (partial) tx frame and restore state */ + if (content & 0x40) { + /* restore tx state */ + if (tx_state != CS8900_TX_IDLE) { + tx_state = CS8900_TX_IDLE; +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: skipping current frame"); +#endif + } + + /* reset transmitter */ + cs8900_set_transmitter(tx_enabled); + + /* this is an "act once" bit, thus restore it to zero. */ + content &= ~0x40; + SET_PP_16(ppaddress, content); + } + break; + case CS8900_PP_ADDR_CC_RXCTL: + if (cs8900_recv_control != content) { + cs8900_recv_broadcast = content & 0x0800; /* broadcast */ + cs8900_recv_mac = content & 0x0400; /* individual address (IA) */ + cs8900_recv_multicast = content & 0x0200; /* multicast if address passes the hash filter */ + cs8900_recv_correct = content & 0x0100; /* accept correct frames */ + cs8900_recv_promiscuous = content & 0x0080; /* promiscuous mode */ + cs8900_recv_hashfilter = content & 0x0040; /* accept if IA passes the hash filter */ + cs8900_recv_control = content; + + log_message(cs8900_log, "setup receiver: broadcast=%s mac=%s multicast=%s correct=%s promiscuous=%s hashfilter=%s", + on_off_str(cs8900_recv_broadcast), on_off_str(cs8900_recv_mac), on_off_str(cs8900_recv_multicast), on_off_str(cs8900_recv_correct), on_off_str(cs8900_recv_promiscuous), on_off_str(cs8900_recv_hashfilter)); + + rawnet_arch_recv_ctl(cs8900_recv_broadcast, cs8900_recv_mac, cs8900_recv_multicast, cs8900_recv_correct, cs8900_recv_promiscuous, cs8900_recv_hashfilter); + } + break; + case CS8900_PP_ADDR_CC_LINECTL: + { + int enable_tx = (content & 0x0080) == 0x0080; + int enable_rx = (content & 0x0040) == 0x0040; + + if ((enable_tx != tx_enabled) || (enable_rx != rx_enabled)) { + rawnet_arch_line_ctl(enable_tx, enable_rx); + cs8900_set_transmitter(enable_tx); + cs8900_set_receiver(enable_rx); + + log_message(cs8900_log, "line control: transmitter=%s receiver=%s", on_off_str(enable_tx), on_off_str(enable_rx)); + } + } + break; + case CS8900_PP_ADDR_CC_SELFCTL: + { + /* reset chip? */ + if ((content & 0x40) == 0x40) { + cs8900_reset(); + } + } + break; + case CS8900_PP_ADDR_TXCMD: + { + if (odd_address) { + uint16_t txcommand = GET_PP_16(CS8900_PP_ADDR_TXCMD); + + /* already transmitting? */ + if (tx_state == CS8900_TX_READ_BUSST) { +#ifdef CS8900_DEBUG_WARN_RXTX + log_message(cs8900_log, "WARNING! Early abort of transmitted frame"); +#endif + } + + /* The transmit status command gets the last transmit command */ + SET_PP_16(CS8900_PP_ADDR_CC_TXCMD, txcommand); + + /* set transmit state */ + tx_state = CS8900_TX_GOT_CMD; + cs8900_set_tx_status(0, 0); + +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: COMMAND accepted (%04x)", txcommand); +#endif + } + } + break; + case CS8900_PP_ADDR_TXLENGTH: + { + if (odd_address && (tx_state == CS8900_TX_GOT_CMD)) { + uint16_t txlength = GET_PP_16(CS8900_PP_ADDR_TXLENGTH); + uint16_t txcommand = GET_PP_16(CS8900_PP_ADDR_CC_TXCMD); + + if (txlength < 4) { + /* frame to short */ +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: LENGTH rejected - too short! (%04x)", txlength); +#endif + /* mask space available but do not commit */ + tx_state = CS8900_TX_IDLE; + cs8900_set_tx_status(1, 0); + } else if ((txlength > MAX_TXLENGTH) || ((txlength > MAX_TXLENGTH - 4) && (!(txcommand & 0x1000)))) { + tx_state = CS8900_TX_IDLE; +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: LENGTH rejected - too long! (%04x)", txlength); +#endif + /* txlength too big, mark an error */ + cs8900_set_tx_status(0, 1); + } else { + /* make sure we put the octets to transmit at the right place */ + tx_buffer = CS8900_PP_ADDR_TX_FRAMELOC; + tx_count = 0; + tx_length = txlength; + tx_state = CS8900_TX_GOT_LEN; + +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: LENGTH accepted (%04x)", txlength); +#endif + /* all right, signal that we're ready for the next frame */ + cs8900_set_tx_status(1, 0); + } + } + } + break; + case CS8900_PP_ADDR_LOG_ADDR_FILTER: + case CS8900_PP_ADDR_LOG_ADDR_FILTER + 2: + case CS8900_PP_ADDR_LOG_ADDR_FILTER + 4: + case CS8900_PP_ADDR_LOG_ADDR_FILTER + 6: + { + unsigned int pos = 8 * (ppaddress - CS8900_PP_ADDR_LOG_ADDR_FILTER + odd_address); + uint32_t *p = (pos < 32) ? &cs8900_hash_mask[0] : &cs8900_hash_mask[1]; + + *p &= ~(0xFF << pos); /* clear out relevant bits */ + *p |= GET_PP_8(ppaddress + odd_address) << pos; + + rawnet_arch_set_hashfilter(cs8900_hash_mask); + +#if 0 + if (odd_address && (ppaddress == CS8900_PP_ADDR_LOG_ADDR_FILTER + 6)) { + log_message(cs8900_log, "set hash filter: %02x:%02x:%02x:%02x:%02x:%02x", + cs8900_hash_mask[0], cs8900_hash_mask[1], cs8900_hash_mask[2], cs8900_hash_mask[3], cs8900_hash_mask[4], cs8900_hash_mask[5]); + } +#endif + } + break; + case CS8900_PP_ADDR_MAC_ADDR: + case CS8900_PP_ADDR_MAC_ADDR + 2: + case CS8900_PP_ADDR_MAC_ADDR + 4: + /* the MAC address has been changed */ + cs8900_ia_mac[ppaddress - CS8900_PP_ADDR_MAC_ADDR + odd_address] = GET_PP_8(ppaddress + odd_address); + rawnet_arch_set_mac(cs8900_ia_mac); + if (odd_address && (ppaddress == CS8900_PP_ADDR_MAC_ADDR + 4)) { + log_message(cs8900_log, "set MAC address: %02x:%02x:%02x:%02x:%02x:%02x", + cs8900_ia_mac[0], cs8900_ia_mac[1], cs8900_ia_mac[2], cs8900_ia_mac[3], cs8900_ia_mac[4], cs8900_ia_mac[5]); + } + break; + } +} +#undef on_off_str + +/* + This is called *before* the relevant octets are read +*/ +static void cs8900_sideeffects_read_pp(uint16_t ppaddress, int odd_address) +{ + switch (ppaddress) { + case CS8900_PP_ADDR_SE_RXEVENT: + /* reading this before all octets of the frame are read + performs an "implied skip" */ + { + int access_mask = (odd_address) ? 1 : 2; + /* update the status register only if the full word of the last + status was read! unfortunately different access patterns are + possible: either the status is read LH, LH, LH... + or HL, HL, HL, or even L, L, L or H, H, H */ + if ((access_mask & rxevent_read_mask) != 0) { + /* receiver is not enabled */ + if (!rx_enabled) { +#ifdef CS8900_DEBUG_WARN_RXTX + log_message(cs8900_log, "WARNING! Can't receive any frame (Receiver is not enabled)!"); +#endif + } else { + /* perform frame reception */ + uint16_t ret_val = cs8900_receive(); + + /* RXSTATUS and RXEVENT are the same, except that RXSTATUS buffers + the old value while RXEVENT sets a new value whenever it is called + */ + SET_PP_16(CS8900_PP_ADDR_RXSTATUS, ret_val); + SET_PP_16(CS8900_PP_ADDR_SE_RXEVENT, ret_val); + } + /* reset read mask of (possible) other access */ + rxevent_read_mask = access_mask; + } else { + /* add access bit to mask */ + rxevent_read_mask |= access_mask; + } + } + break; + case CS8900_PP_ADDR_SE_BUSST: + if (odd_address) { + /* read busst before transmit condition is fullfilled */ + if (tx_state == CS8900_TX_GOT_LEN) { + uint16_t bus_status = GET_PP_16(CS8900_PP_ADDR_SE_BUSST); + + /* check Rdy4TXNow flag */ + if ((bus_status & 0x100) == 0x100) { + tx_state = CS8900_TX_READ_BUSST; +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: Ready4TXNow set! (%04x)", bus_status); +#endif + } else { +#ifdef CS8900_DEBUG_RXTX_STATE + log_message(cs8900_log, "TX: waiting for Ready4TXNow! (%04x)", bus_status); +#endif + } + } + } + break; + } +} + +/* ------------------------------------------------------------------------- */ +/* read/write from packet page register */ + +/* read a register from packet page */ +static uint16_t cs8900_read_register(uint16_t ppaddress) +{ + uint16_t value = GET_PP_16(ppaddress); + + /* --- check the register address --- */ + if (ppaddress < 0x100) { + /* reserved range reads 0x0300 on real HW */ + if ((ppaddress >= 0x0004) && (ppaddress < 0x0020)) { + return 0x0300; + } + } else if (ppaddress < 0x120) { + /* --- read control register range --- */ + uint16_t regNum = ppaddress - 0x100; + + regNum &= ~1; + regNum++; +#ifdef CS8900_DEBUG_REGISTERS + log_message(cs8900_log, "Read Control Register %04x: %04x (reg=%02x)", ppaddress, value, regNum); +#endif + + /* reserved register? */ + if ((regNum == 0x01) || (regNum == 0x11) || (regNum > 0x19)) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read reserved Control Register %04x (reg=%02x)", ppaddress, regNum); +#endif + /* real HW returns 0x0300 in reserved register range */ + return 0x0300; + } + + /* make sure internal address is always valid */ + assert((value & 0x3f) == regNum); + } else if (ppaddress < 0x140) { + /* --- read status register range --- */ + uint16_t regNum = ppaddress - 0x120; + + regNum &= ~1; +#ifdef CS8900_DEBUG_REGISTERS +#ifdef CS8900_DEBUG_IGNORE_RXEVENT + if (regNum != 4) /* do not show RXEVENT */ +#endif + log_message(cs8900_log, "Read Status Register %04x: %04x (reg=%02x)", ppaddress, value, regNum); +#endif + + /* reserved register? */ + if ((regNum == 0x02) || (regNum == 0x06) || (regNum == 0x0a) || (regNum == 0x0e) || (regNum == 0x1a) || (regNum == 0x1e)) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read reserved Status Register %04x (reg=%02x)", ppaddress, regNum); +#endif + /* real HW returns 0x0300 in reserved register range */ + return 0x0300; + } + + /* make sure internal address is always valid */ + assert((value & 0x3f) == regNum); + } else if (ppaddress < 0x150) { + /* --- read transmit register range --- */ + if (ppaddress == 0x144) { + /* make sure internal address is always valid */ + assert((value & 0x3f) == 0x09); +#ifdef CS8900_DEBUG_REGISTERS + log_message(cs8900_log, "Read TX Cmd Register %04x: %04x", ppaddress, value); +#endif + } else if (ppaddress == 0x146) { +#ifdef CS8900_DEBUG_REGISTERS + log_message(cs8900_log, "Read TX Len Register %04x: %04x", ppaddress, value); +#endif + } else { + /* reserved range */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read reserved Initiate Transmit Register %04x", ppaddress); +#endif + /* real HW returns 0x0300 in reserved register range */ + return 0x0300; + } + } else if (ppaddress < 0x160) { + /* --- read address filter register range --- */ + /* reserved range */ + if (ppaddress >= 0x15e) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read reserved Address Filter Register %04x", ppaddress); +#endif + /* real HW returns 0x0300 in reserved register range */ + return 0x0300; + } + } else if (ppaddress < 0x400) { + /* --- reserved range below 0x400 --- + returns 0x300 on real HW + */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read reserved Register %04x", ppaddress); +#endif + return 0x0300; + } else if (ppaddress < 0xa00) { + /* --- range from 0x400 .. 0x9ff --- RX Frame */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read from RX Buffer Range %04x", ppaddress); +#endif + return 0x0000; + } else { + /* --- range from 0xa00 .. 0xfff --- TX Frame */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Read from TX Buffer Range %04x", ppaddress); +#endif + return 0x0000; + } + + /* actually read from pp memory */ + return value; +} + +static void cs8900_write_register(uint16_t ppaddress, uint16_t value) +{ + /* --- write bus interface register range --- */ + if (ppaddress < 0x100) { + int ignore = 0; + + if (ppaddress < 0x20) { + ignore = 1; + } else if ((ppaddress >= 0x26) && (ppaddress < 0x2c)) { + ignore = 1; + } else if (ppaddress == 0x38) { + ignore = 1; + } else if (ppaddress >= 0x44) { + ignore = 1; + } + if (ignore) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ignoring write to read only/reserved Bus Interface Register %04x", ppaddress); +#endif + return; + } + } else if (ppaddress < 0x120) { + /* --- write to control register range --- */ + uint16_t regNum = ppaddress - 0x100; + + regNum &= ~1; + regNum += 1; + /* validate internal address */ + if ((value & 0x3f) != regNum) { + /* fix internal address */ + value &= ~0x3f; + value |= regNum; + } +#ifdef CS8900_DEBUG_REGISTERS + log_message(cs8900_log, "Write Control Register %04x: %04x (reg=%02x)", ppaddress, value, regNum); +#endif + + /* invalid register? -> ignore! */ + if ((regNum == 0x01) || (regNum == 0x11) || (regNum > 0x19)) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ignoring write to reserved Control Register %04x (reg=%02x)", ppaddress, regNum); +#endif + return; + } + } else if (ppaddress < 0x140) { + /* --- write to status register range --- */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ignoring write to read-only Status Register %04x", ppaddress); +#endif + return; + } else if (ppaddress < 0x150) { + /* --- write to initiate transmit register range --- */ + /* check tx_cmd register */ + if (ppaddress == 0x144) { + /* validate internal address */ + if ((value & 0x3f) != 0x09) { + /* fix internal address */ + value &= ~0x3f; + value |= 0x09; + } + /* mask out reserved bits */ + value &= 0x33ff; +#ifdef CS8900_DEBUG_REGISTERS + log_message(cs8900_log, "Write TX Cmd Register %04x: %04x", ppaddress, value); +#endif + } else if (ppaddress == 0x146) { + /* check tx_length register */ + /* HW always masks 0x0fff */ + value &= 0x0fff; +#ifdef CS8900_DEBUG_REGISTERS + log_message(cs8900_log, "Write TX Len Register %04x: %04x", ppaddress, value); +#endif + } else if ((ppaddress < 0x144) || (ppaddress > 0x147)) { + /* reserved range */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ignoring write to reserved Initiate Transmit Register %04x", ppaddress); +#endif + return; + } + } else if (ppaddress < 0x160) { + /* --- write to address filter register range --- */ + /* reserved range */ + if (ppaddress >= 0x15e) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ingoring write to reserved Address Filter Register %04x", ppaddress); +#endif + return; + } + } else if (ppaddress < 0x400) { + /* --- ignore write outside --- */ +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ingoring write to reserved Register %04x", ppaddress); +#endif + return; + } else if (ppaddress < 0xa00) { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ignoring write to RX Buffer Range %04x", ppaddress); +#endif + return; + } else { +#ifdef CS8900_DEBUG_WARN_REG + log_message(cs8900_log, "WARNING! Ignoring write to TX Buffer Range %04x", ppaddress); +#endif + return; + } + + /* actually set value */ + SET_PP_16(ppaddress, value); +} + +#define PP_PTR_AUTO_INCR_FLAG 0x8000 /* auto increment flag in package pointer */ +#define PP_PTR_FLAG_MASK 0xf000 /* is always : x y 1 1 (with x=auto incr) */ +#define PP_PTR_ADDR_MASK 0x0fff /* address portion of packet page pointer */ + +static void cs8900_auto_incr_pp_ptr(void) +{ + /* perform auto increment of packet page pointer */ + if ((cs8900_packetpage_ptr & PP_PTR_AUTO_INCR_FLAG) == PP_PTR_AUTO_INCR_FLAG) { + /* pointer is always increment by one on real HW */ + uint16_t ptr = cs8900_packetpage_ptr & PP_PTR_ADDR_MASK; + uint16_t flags = cs8900_packetpage_ptr & PP_PTR_FLAG_MASK; + + ptr++; + cs8900_packetpage_ptr = ptr | flags; + } +} + +/* ------------------------------------------------------------------------- */ +/* read/write CS8900 registers from VICE */ + +#define LO_uint8_t(x) (uint8_t)((x) & 0xff) +#define HI_uint8_t(x) (uint8_t)(((x) >> 8) & 0xff) +#define LOHI_uint16_t(x, y) ((uint16_t)(x) | (((uint16_t)(y)) << 8 )) + +/* ----- read byte from I/O range in VICE ----- */ +uint8_t cs8900_read(uint16_t io_address) +{ + uint8_t retval, lo, hi; + uint16_t word_value; + uint16_t reg_base; + + assert(cs8900); + assert(cs8900_packetpage); + assert(io_address < 0x10); + + /* register base addr */ + reg_base = io_address & ~1; + + /* RX register is special as it reads from RX buffer directly */ + if ((reg_base == CS8900_ADDR_RXTXDATA) || (reg_base == CS8900_ADDR_RXTXDATA2)) { + return cs8900_read_rx_buffer(io_address & 0x01); + } + + /* read packet page pointer */ + if (reg_base == CS8900_ADDR_PP_PTR) { + word_value = cs8900_packetpage_ptr; + } else { + /* read a register from packet page */ + uint16_t ppaddress = 0; + + /* determine read addr in packet page */ + switch (reg_base) { + /* PP_DATA2 behaves like PP_DATA on real HW + both show the contents at the page pointer */ + case CS8900_ADDR_PP_DATA: + case CS8900_ADDR_PP_DATA2: + /* mask and align address of packet pointer */ + ppaddress = cs8900_packetpage_ptr & PP_PTR_ADDR_MASK; + ppaddress &= ~1; + /* if flags match then auto incr pointer */ + cs8900_auto_incr_pp_ptr(); + break; + case CS8900_ADDR_INTSTQUEUE: + ppaddress = CS8900_PP_ADDR_SE_ISQ; + break; + case CS8900_ADDR_TXCMD: + ppaddress = CS8900_PP_ADDR_TXCMD; + break; + case CS8900_ADDR_TXLENGTH: + ppaddress = CS8900_PP_ADDR_TXLENGTH; + break; + default: + /* invalid! */ + assert(0); + break; + } + + /* do side effects before access */ + cs8900_sideeffects_read_pp(ppaddress, io_address & 1); + + /* read register value */ + word_value = cs8900_read_register(ppaddress); + +#ifdef CS8900_DEBUG_LOAD + log_message(cs8900_log, "reading PP Ptr: $%04X => $%04X.", ppaddress, word_value); +#endif + } + + /* extract return value from word_value */ + lo = LO_uint8_t(word_value); + hi = HI_uint8_t(word_value); + if ((io_address & 1) == 0) { + /* low byte on even address */ + retval = lo; + } else { + /* high byte on odd address */ + retval = hi; + } + +#ifdef CS8900_DEBUG_LOAD + log_message(cs8900_log, "read [$%02X] => $%02X.", io_address, retval); +#endif + + /* update _word_ value in register bank */ + cs8900[reg_base] = lo; + cs8900[reg_base + 1] = hi; + + return retval; +} + +/* ----- peek byte without side effects from I/O range in VICE ----- */ +uint8_t cs8900_peek(uint16_t io_address) +{ + uint8_t retval, lo, hi; + uint16_t word_value; + uint16_t reg_base; + + assert(cs8900); + assert(cs8900_packetpage); + assert(io_address < 0x10); + + /* register base addr */ + reg_base = io_address & ~1; + + /* RX register is special as it reads from RX buffer directly */ + if ((reg_base == CS8900_ADDR_RXTXDATA) || (reg_base == CS8900_ADDR_RXTXDATA2)) { + return 0; /* FIXME: peek rx buffer */ + } + + /* read packet page pointer */ + if (reg_base == CS8900_ADDR_PP_PTR) { + word_value = cs8900_packetpage_ptr; + } else { + /* read a register from packet page */ + uint16_t ppaddress = 0; + + /* determine read addr in packet page */ + switch (reg_base) { + /* PP_DATA2 behaves like PP_DATA on real HW + both show the contents at the page pointer */ + case CS8900_ADDR_PP_DATA: + case CS8900_ADDR_PP_DATA2: + /* mask and align address of packet pointer */ + ppaddress = cs8900_packetpage_ptr & PP_PTR_ADDR_MASK; + ppaddress &= ~1; + /* if flags match then auto incr pointer */ + cs8900_auto_incr_pp_ptr(); + break; + case CS8900_ADDR_INTSTQUEUE: + ppaddress = CS8900_PP_ADDR_SE_ISQ; + break; + case CS8900_ADDR_TXCMD: + ppaddress = CS8900_PP_ADDR_TXCMD; + break; + case CS8900_ADDR_TXLENGTH: + ppaddress = CS8900_PP_ADDR_TXLENGTH; + break; + default: + /* invalid! */ + assert(0); + break; + } + + /* read register value */ + word_value = cs8900_read_register(ppaddress); + } + + /* extract return value from word_value */ + lo = LO_uint8_t(word_value); + hi = HI_uint8_t(word_value); + if ((io_address & 1) == 0) { + /* low byte on even address */ + retval = lo; + } else { + /* high byte on odd address */ + retval = hi; + } + return retval; +} + +/* ----- write byte to I/O range of VICE ----- */ +void cs8900_store(uint16_t io_address, uint8_t byte) +{ + uint16_t reg_base; + uint16_t word_value; + + assert(cs8900); + assert(cs8900_packetpage); + assert(io_address < 0x10); + +#ifdef CS8900_DEBUG_STORE + log_message(cs8900_log, "store [$%02X] <= $%02X.", io_address, (int)byte); +#endif + + /* register base addr */ + reg_base = io_address & ~1; + + /* TX Register is special as it writes to TX buffer directly */ + if ((reg_base == CS8900_ADDR_RXTXDATA) || (reg_base == CS8900_ADDR_RXTXDATA2)) { + cs8900_write_tx_buffer(byte, io_address & 1); + return; + } + + /* combine stored value with new written byte */ + if ((io_address & 1) == 0) { + /* overwrite low byte */ + word_value = LOHI_uint16_t(byte, cs8900[reg_base + 1]); + } else { + /* overwrite high byte */ + word_value = LOHI_uint16_t(cs8900[reg_base], byte); + } + + if (reg_base == CS8900_ADDR_PP_PTR) { + /* we store the full package pointer in cs8900_packetpage_ptr variable. + this includes the mask area (0xf000) and the addr range (0x0fff). + we ensure that the bits 0x3000 are always set (as in real HW). + odd values of the pointer are valid and supported. + only register read and write have to be mapped to word boundary. */ + word_value |= 0x3000; + cs8900_packetpage_ptr = word_value; + +#ifdef CS8900_DEBUG_STORE + log_message(cs8900_log, "set PP Ptr to $%04X.", cs8900_packetpage_ptr); +#endif + } else { + /* write a register */ + + /*! \TODO: Find a reasonable default */ + uint16_t ppaddress = CS8900_PP_ADDR_PRODUCTID; + + /* now determine address of write in packet page */ + switch (reg_base) { + case CS8900_ADDR_PP_DATA: + case CS8900_ADDR_PP_DATA2: + /* mask and align ppaddress from page pointer */ + ppaddress = cs8900_packetpage_ptr & (MAX_PACKETPAGE_ARRAY - 1); + ppaddress &= ~1; + /* auto increment pp ptr */ + cs8900_auto_incr_pp_ptr(); + break; + case CS8900_ADDR_TXCMD: + ppaddress = CS8900_PP_ADDR_TXCMD; + break; + case CS8900_ADDR_TXLENGTH: + ppaddress = CS8900_PP_ADDR_TXLENGTH; + break; + case CS8900_ADDR_INTSTQUEUE: + ppaddress = CS8900_PP_ADDR_SE_ISQ; + break; + case CS8900_ADDR_PP_PTR: + break; + default: + /* invalid */ + assert(0); + break; + } + +#ifdef CS8900_DEBUG_STORE + log_message(cs8900_log, "before writing to PP Ptr: $%04X <= $%04X.", ppaddress, word_value); +#endif + + /* perform the write */ + cs8900_write_register(ppaddress, word_value); + + /* handle sideeffects */ + cs8900_sideeffects_write_pp(ppaddress, io_address & 1); + + /* update word value if it was changed in write register or by side effect */ + word_value = GET_PP_16(ppaddress); + +#ifdef CS8900_DEBUG_STORE + log_message(cs8900_log, "after writing to PP Ptr: $%04X <= $%04X.", ppaddress, word_value); +#endif + } + + /* update cs8900 registers */ + cs8900[reg_base] = LO_uint8_t(word_value); + cs8900[reg_base + 1] = HI_uint8_t(word_value); +} + +int cs8900_dump(void) +{ + /* FIXME: this is incomplete */ + // mon_out("Link status: %s\n", (GET_PP_16(CS8900_PP_ADDR_SE_LINEST) & 0x80) ? "up" : "no link"); + // mon_out("Package Page Ptr: $%04X (autoincrement %s)\n", cs8900_packetpage_ptr & PP_PTR_ADDR_MASK, (cs8900_packetpage_ptr & PP_PTR_AUTO_INCR_FLAG) != 0 ? "enabled" : "disabled"); + return 0; +} + +/* ---------------------------------------------------------------------*/ +/* snapshot support functions */ + +#define CART_DUMP_VER_MAJOR 0 +#define CART_DUMP_VER_MINOR 0 +#define SNAP_MODULE_NAME "CS8900" + +/* FIXME: implement snapshot support */ +int cs8900_snapshot_write_module(snapshot_t *s) +{ + return -1; +#if 0 + snapshot_module_t *m; + + m = snapshot_module_create(s, SNAP_MODULE_NAME, + CART_DUMP_VER_MAJOR, CART_DUMP_VER_MINOR); + if (m == NULL) { + return -1; + } + + if (0) { + snapshot_module_close(m); + return -1; + } + + snapshot_module_close(m); + return 0; +#endif +} + +int cs8900_snapshot_read_module(snapshot_t *s) +{ + return -1; +#if 0 + uint8_t vmajor, vminor; + snapshot_module_t *m; + + m = snapshot_module_open(s, SNAP_MODULE_NAME, &vmajor, &vminor); + if (m == NULL) { + return -1; + } + + if ((vmajor != CART_DUMP_VER_MAJOR) || (vminor != CART_DUMP_VER_MINOR)) { + snapshot_module_close(m); + return -1; + } + + if (0) { + snapshot_module_close(m); + return -1; + } + + snapshot_module_close(m); + return 0; +#endif +} + +#endif /* #ifdef HAVE_RAWNET */ diff --git a/src/rawnet/cs8900.h b/src/rawnet/cs8900.h new file mode 100644 index 0000000..97b23fb --- /dev/null +++ b/src/rawnet/cs8900.h @@ -0,0 +1,64 @@ +/* + * cs8900.h - CS8900 Ethernet Core + * + * Written by + * Spiro Trikaliotis + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 + +#ifndef HAVE_RAWNET + #error CS8900.H should not be included if HAVE_RAWNET is not defined! +#endif /* #ifdef HAVE_RAWNET */ + +#ifndef VICE_CS8900_H +#define VICE_CS8900_H + +//#include <"types.h"> + +typedef struct snapshot_s snapshot_t; +extern int cs8900_snapshot_read_module(snapshot_t *s); +extern int cs8900_snapshot_write_module(snapshot_t *s); + +extern int cs8900_init(void); +extern void cs8900_reset(void); + +extern int cs8900_activate(const char *net_interface); +extern int cs8900_deactivate(void); +extern void cs8900_shutdown(void); + +extern uint8_t cs8900_read(uint16_t io_address); +extern uint8_t cs8900_peek(uint16_t io_address); +extern void cs8900_store(uint16_t io_address, uint8_t byte); +extern int cs8900_dump(void); + +/* + This is a helper for cs8900_receive() to determine if the received frame should be accepted + according to the settings. + + This function is even allowed to be called (indirectly via rawnet_should_accept) in rawnetarch.c + from rawnet_arch_receive() if necessary, and must be registered using rawnet_set_should_accept_func + at init time. +*/ +extern int cs8900_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast); + +#endif diff --git a/src/rawnet/rawnet.c b/src/rawnet/rawnet.c new file mode 100644 index 0000000..3146130 --- /dev/null +++ b/src/rawnet/rawnet.c @@ -0,0 +1,85 @@ +/* + * rawnet.c - raw ethernet interface + * + * Written by + * Spiro Trikaliotis + * Christian Vogelgsang + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 "vice.h" + +#ifdef HAVE_RAWNET + +#include +#include +#include + +#include "rawnet.h" +#include "rawnetsupp.h" +#include "rawnetarch.h" + +static int (*should_accept)(unsigned char *, int, int *, int *, int *, int *, int *) = NULL; + +int rawnet_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast) +{ + assert(should_accept); + return should_accept(buffer, length, phashed, phash_index, pcorrect_mac, pbroadcast, pmulticast); +} + +void rawnet_set_should_accept_func(int (*func)(unsigned char *, int, int *, int *, int *, int *, int *)) +{ + should_accept = func; +} + +/* ------------------------------------------------------------------------- */ +/* functions for selecting and querying available NICs */ + +int rawnet_enumadapter_open(void) +{ + if (!rawnet_arch_enumadapter_open()) { + /* tfe_cannot_use = 1; */ + return 0; + } + return 1; +} + +int rawnet_enumadapter(char **ppname, char **ppdescription) +{ + return rawnet_arch_enumadapter(ppname, ppdescription); +} + +int rawnet_enumadapter_close(void) +{ + return rawnet_arch_enumadapter_close(); +} + +char *rawnet_get_standard_interface(void) +{ + return rawnet_arch_get_standard_interface(); +} + +int rawnet_status(void) +{ + return rawnet_arch_status(); +} + +#endif /* #ifdef HAVE_RAWNET */ diff --git a/src/rawnet/rawnet.h b/src/rawnet/rawnet.h new file mode 100644 index 0000000..bc61944 --- /dev/null +++ b/src/rawnet/rawnet.h @@ -0,0 +1,77 @@ +/* + * rawnet.h - raw ethernet interface + * + * Written by + * Spiro Trikaliotis + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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_RAWNET +#else + #error RAWNET.H should not be included if HAVE_RAWNET is not defined! +#endif /* #ifdef HAVE_RAWNET */ + +#ifndef VICE_RAWNET_H +#define VICE_RAWNET_H + +/* + This is a helper for the _receive() function of the emulated ethernet chip to determine + if the received frame should be accepted according to the settings. + + This function is even allowed to be called in rawnetarch.c from rawnet_arch_receive() if + necessary. the respective helper function of the emulated ethernet chip must be registered + using rawnet_set_should_accept_func at init time. +*/ + +extern int rawnet_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index, int *pcorrect_mac, int *pbroadcast, int *pmulticast); +extern void rawnet_set_should_accept_func(int (*func)(unsigned char *, int, int *, int *, int *, int *, int *)); + +/* + + These functions let the UI enumerate the available interfaces. + + First, rawnet_enumadapter_open() is used to start enumeration. + + rawnet_enumadapter() is then used to gather information for each adapter present + on the system, where: + + ppname points to a pointer which will hold the name of the interface + ppdescription points to a pointer which will hold the description of the interface + + For each of these parameters, new memory is allocated, so it has to be + freed with lib_free(). + Note: The description can be NULL, since pcap_if_t.desc can be NULL, so + check the description before calling lib_free() on it. + + rawnet_enumadapter_close() must be used to stop processing. + + Each function returns 1 on success, and 0 on failure. + rawnet_enumadapter() only fails if there is no more adpater; in this case, + *ppname and *ppdescription are not altered. +*/ +extern int rawnet_enumadapter_open(void); +extern int rawnet_enumadapter(char **ppname, char **ppdescription); +extern int rawnet_enumadapter_close(void); +extern char *rawnet_get_standard_interface(void); + +extern int rawnet_status(void); + +#endif diff --git a/src/rawnet/rawnetarch.c b/src/rawnet/rawnetarch.c new file mode 100644 index 0000000..7149de8 --- /dev/null +++ b/src/rawnet/rawnetarch.c @@ -0,0 +1,144 @@ +/** \file rawnetarch.c + * \brief raw ethernet interface, architecture-dependant stuff + * + * \author Bas Wassink + +#ifdef HAVE_RAWNET + +/* backward compatibility junk */ + + +/** \brief Transmit a frame + * + * \param[in] force Delete waiting frames in transmit buffer + * \param[in] onecoll Terminate after just one collision + * \param[in] inhibit_crc Do not append CRC to the transmission + * \param[in] tx_pad_dis Disable padding to 60 Bytes + * \param[in] txlength Frame length + * \param[in] txframe Pointer to the frame to be transmitted + */ +void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, + int tx_pad_dis, int txlength, uint8_t *txframe) +{ + + int ok; + +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, + "rawnet_arch_transmit() called, with: force = %s, onecoll = %s, " + "inhibit_crc=%s, tx_pad_dis=%s, txlength=%u", + force ? "TRUE" : "FALSE", + onecoll ? "TRUE" : "FALSE", + inhibit_crc ? "TRUE" : "FALSE", + tx_pad_dis ? "TRUE" : "FALSE", + txlength); +#endif + + ok = rawnet_arch_write(txframe, txlength); + if (ok < 0) { + log_message(rawnet_arch_log, "WARNING! Could not send packet!"); + } +} + +/** + * \brief Check if a frame was received + * + * This function checks if there was a frame received. If so, it returns 1, + * else 0. + * + * If there was no frame, none of the parameters is changed! + * + * If there was a frame, the following actions are done: + * + * - at maximum \a plen byte are transferred into the buffer given by \a pbuffer + * - \a plen gets the length of the received frame, EVEN if this is more + * than has been copied to \a pbuffer! + * - if the dest. address was accepted by the hash filter, \a phashed is set, + * else cleared. + * - if the dest. address was accepted by the hash filter, \a phash_index is + * set to the number of the rule leading to the acceptance + * - if the receive was ok (good CRC and valid length), \a *prx_ok is set, else + * cleared. + * - if the dest. address was accepted because it's exactly our MAC address + * (set by rawnet_arch_set_mac()), \a pcorrect_mac is set, else cleared. + * - if the dest. address was accepted since it was a broadcast address, + * \a pbroadcast is set, else cleared. + * - if the received frame had a crc error, \a pcrc_error is set, else cleared + * + * \param[out] buffer where to store a frame + * \param[in,out] plen IN: maximum length of frame to copy; + * OUT: length of received frame OUT + * can be bigger than IN if received frame was + * longer than supplied buffer + * \param[out] phashed set if the dest. address is accepted by the + * hash filter + * \param[out] phash_index hash table index if hashed == TRUE + * \param[out] prx_ok set if good CRC and valid length + * \param[out] pcorrect_mac set if dest. address is exactly our IA + * \param[out[ pbroadcast set if dest. address is a broadcast address + * \param[out] pcrc_error set if received frame had a CRC error +*/ +int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, + int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, + int *pcrc_error) +{ + int ok; + +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, + "rawnet_arch_receive() called, with *plen=%u.", + *plen); +#endif + + + + assert((*plen & 1) == 0); + + ok = rawnet_arch_read(pbuffer, *plen); + if (ok <= 0) return 0; + + if (ok & 1) ++ok; + *plen = ok; + + *phashed = + *phash_index = + *pbroadcast = + *pcorrect_mac = + *pcrc_error = 0; + + /* this frame has been received correctly */ + *prx_ok = 1; + return 1; + +} + + + + +#endif /* ifdef HAVE_RAWNET */ diff --git a/src/rawnet/rawnetarch.h b/src/rawnet/rawnetarch.h new file mode 100644 index 0000000..68ddc68 --- /dev/null +++ b/src/rawnet/rawnetarch.h @@ -0,0 +1,77 @@ +/* + * rawnetarch.h - raw ethernet interface + * architecture-dependant stuff + * + * Written by + * Spiro Trikaliotis + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 + +#ifdef HAVE_RAWNET +#else + #error RAWNETARCH.H should not be included if HAVE_RAWNET is not defined! +#endif /* #ifdef HAVE_RAWNET */ + +#ifndef VICE_RAWNETARCH_H +#define VICE_RAWNETARCH_H + +/* define this only if VICE should write each and every frame received + and send into the VICE log + WARNING: The log grows very fast! +*/ +/* #define RAWNET_DEBUG_FRAMES */ + +// #include "types.h" + +extern int rawnet_arch_init(void); +extern void rawnet_arch_pre_reset(void); +extern void rawnet_arch_post_reset(void); +extern int rawnet_arch_activate(const char *interface_name); +extern void rawnet_arch_deactivate(void); +extern void rawnet_arch_set_mac(const uint8_t mac[6]); +extern void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]); + +extern void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash); + +extern void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver); + +extern void rawnet_arch_transmit(int force, int onecoll, int inhibit_crc, int tx_pad_dis, int txlength, uint8_t *txframe); + +extern int rawnet_arch_receive(uint8_t *pbuffer, int *plen, int *phashed, int *phash_index, int *prx_ok, int *pcorrect_mac, int *pbroadcast, int *pcrc_error); + +extern int rawnet_arch_enumadapter_open(void); +extern int rawnet_arch_enumadapter(char **ppname, char **ppdescription); +extern int rawnet_arch_enumadapter_close(void); + +extern char *rawnet_arch_get_standard_interface(void); + + +extern int rawnet_arch_read(void *buffer, int length); +extern int rawnet_arch_write(const void *buffer, int length); + +extern int rawnet_arch_get_mtu(void); +extern int rawnet_arch_get_mac(uint8_t mac[6]); + +extern int rawnet_arch_status(void); + +#endif diff --git a/src/rawnet/rawnetarch_tap.c b/src/rawnet/rawnetarch_tap.c new file mode 100644 index 0000000..a7c7e88 --- /dev/null +++ b/src/rawnet/rawnetarch_tap.c @@ -0,0 +1,481 @@ +/* tun/tap support */ +/* for Linux, *BSD */ + +/* + * tap is a virtual ethernet devices. + * open the device, configure, and read/write ethernet frames. + * + * Linux setup: (from Network Programmability and Automation, Appendix A) + * + * Notes: + * - this assumes eth0 is your main interface device + * - may need to install the iproute/iproute2 package (ip command) + * - do this stuff as root. + * + * 1. create a tap interface + * $ ip tuntap add tap65816 mode tap user YOUR_USER_NAME + * $ ip link set tap65816 up + * + * 2. create a network bridge + * $ ip link add name br0 type bridge + * $ ip link set br0 up + * + * 3. bridge the physical network and virtual network. + * $ ip link set eth0 master br0 + * $ ip link set tap65816 master br0 + * + * 4. remove ip address from physical device (This will kill networking) + * ip address flush dev eth0 + * + * 5. and add the ip address to the bridge + * dhclient br0 # if using dhcp + * ip address add 192.168.1.1/24 dev eth0 # if using static ip address. + * + * *BSD: + * - assumes eth0 is your main interface device. + * $ ifconfig bridge0 create + * $ ifconfig tap65816 create + * $ ifconfig bridge0 addm eth0 addm tap65816 up + * + * allow normal users to open tap devices? + * $ sysctl net.link.tap.user_open=1 + * $ sysctl net.link.tap.up_on_open=1 + * + * set permissions + * $ chown YOUR_USER_NAME /dev/tap65816 + * $ chmod 660 /dev/tap65816 + */ + + + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(__linux__) +#include +#include +#endif + +#include "rawnetarch.h" +#include "rawnetsupp.h" + +#if defined(__linux__) +#define TAP_DEVICE "/dev/net/tun" +#endif + +#if defined(__FreeBSD__) +#define TAP_DEVICE "/dev/tap" +#endif + +static int interface_fd = -1; +static char *interface_dev = NULL; + +static uint8_t interface_mac[6]; +static uint8_t interface_fake_mac[6]; + +static uint8_t *interface_buffer = NULL; +static int interface_buffer_size = 0; + +int rawnet_arch_init(void) { + interface_fd = -1; + return 1; +} +void rawnet_arch_pre_reset(void) { + /* NOP */ +} + +void rawnet_arch_post_reset(void) { + /* NOP */ +} + +/* memoized buffer for ethernet packets, etc */ +static int make_buffer(int size) { + if (size <= interface_buffer_size) return 0; + if (interface_buffer) free(interface_buffer); + if (size < 1500) size = 1500; /* good mtu size */ + interface_buffer_size = 0; + size *= 2; + interface_buffer = malloc(size); + if (!interface_buffer) return -1; + interface_buffer_size = size; + return 0; +} + +#if defined(__linux__) +/* interface name. default is tap65816. */ +int rawnet_arch_activate(const char *interface_name) { + + struct ifreq ifr; + + int ok; + int one = 1; + int fd; + + if (!interface_name || !*interface_name) { + interface_name = "tap65816"; + } + + fd = open(TAP_DEVICE, O_RDWR); + if (fd < 0) { + fprintf(stderr, "rawnet_arch_activate: open(%s): %s\n", TAP_DEVICE, strerror(errno)); + return 0; + } + + ok = ioctl(fd, FIONBIO, &one); + if (ok < 0) { + perror("ioctl(FIONBIO"); + close(fd); + return 0; + } + + memset(&ifr, 0, sizeof(ifr)); + strcpy(&if.ifr_name, interface_name); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + ok = ioctl(fd, TUNSETIFF, (void *) &ifr); + if (ok < 0) { + perror("ioctl(TUNSETIFF)"); + close(fd); + return 0; + } + + if (rawnet_arch_get_mac(interface_mac) < 0) { + perror("rawnet_arch_get_mac"); + close(fd); + return 0; + } + /* copy mac to fake mac */ + memcpy(interface_fake_mac, interface_mac, 6); + + + interface_dev = strdup(interface_name); + interface_fd = fd; + return 1; +} +#endif + +#if defined(__FreeBSD__) +/* man tap(4) */ +/* interface name. default is tap65816. */ +int rawnet_arch_activate(const char *interface_name) { + + struct ifreq ifr; + + int ok; + int one = 1; + int fd; + char *path[64]; + + if (!interface_name || !*interface_name) { + interface_name = "tap65816"; + } + + ok = snprintf(path, sizeof(path), "/dev/%s", interface_name); + if (ok >= sizeof(path)) return 0; + + fd = open(path, O_RDWR); + if (fd < 0) { + fprintf(stderr, "rawnet_arch_activate: open(%s): %s\n", path, strerror(errno)); + return 0; + } + + ok = ioctl(fd, FIONBIO, &one); + if (ok < 0) { + perror("ioctl(FIONBIO"); + close(fd); + return 0; + } + + if (rawnet_arch_get_mac(interface_mac) < 0) { + perror("rawnet_arch_get_mac"); + close(fd); + return 0; + } + /* copy mac to fake mac */ + memcpy(interface_fake_mac, interface_mac, 6); + + + + interface_dev = strdup(interface_name); + interface_fd = fd; + return 1; +} +#endif + + + + +void rawnet_arch_deactivate(void) { + if (interface_fd >= 0) + close(interface_fd); + free(interface_dev); + + free(interface_buffer); + interface_buffer = 0; + interface_buffer_size = 0; + + interface_dev = NULL; + interface_fd = -1; +} + + +void rawnet_arch_set_mac(const uint8_t mac[6]) { + +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); +#endif + + memcpy(interface_fake_mac, mac, 6); + + /* in theory, SIOCSIFHWADDR (linux) or SIOCSIFADDR (bsd) will set the mac address. */ + /* in testing, (linux) I get EBUSY or EOPNOTSUPP */ + + +#if 0 + if (interface_fd < 0) return; + + + #if defined(__linux__) + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); + if (ioctl(interface_fd, SIOCSIFHWADDR, (void *)&ifr) < 0) + perror("ioctl(SIOCSIFHWADDR)"); + #endif + + #if defined(__FreeBSD__) + if (ioctl(interface_fd, SIOCSIFADDR, mac) < 0) + perror("ioctl(SIOCSIFADDR)"); + #endif +#endif +} +void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) { + /* NOP */ +} + +void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) { + /* NOP */ +} + +void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) { + /* NOP */ +} + +int rawnet_arch_read(void *buffer, int nbyte) { + int ok; + + if (make_buffer(nbyte) < 0) return -1; + + ok = read(interface_fd, interface_buffer, nbyte); + if (ok <= 0) return -1; + + rawnet_fix_incoming_packet(interface_buffer, ok, interface_mac, interface_fake_mac); + memcpy(buffer, interface_buffer, ok); + return ok; +} + +int rawnet_arch_write(const void *buffer, int nbyte) { + int ok; + + if (make_buffer(nbyte) < 0) return -1; + + + memcpy(interface_buffer, buffer, nbyte); + rawnet_fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac); + + ok = write(interface_fd, interface_buffer, nbyte); + return ok; +} + + +static unsigned adapter_index = 0; +static unsigned adapter_count = 0; +static char **devices = NULL; + +static int cmp(const void *a, const void *b) { + return strcasecmp(*(const char **)a, *(const char **)b); +} + +int rawnet_arch_enumadapter_open(void) { + adapter_index = 0; + adapter_count = 0; + devices = NULL; + + char buffer[MAXPATHLEN]; + + unsigned capacity = 0; + unsigned count = 0; + DIR *dp = NULL; + + int i; + + + capacity = 20; + devices = (char **)malloc(sizeof(char *) * capacity); + if (!devices) return 0; + + +#if defined(__linux__) + + dp = opendir("/sys/class/net/"); + if (!dp) goto fail; + + for(;;) { + char *cp; + FILE *fp; + struct dirent *d = readdir(dp); + if (!d) break; + + if (d->d_name[0] == '.') continue; + + sprintf(buffer, "/sys/class/net/%s/tun_flags", d->d_name); + fp = fopen(buffer, "r"); + if (!fp) continue; + cp = fgets(buffer, sizeof(buffer), fp); + fclose(fp); + if (cp) { + /* expect 0x1002 */ + int flags = strtol(cp, (char **)NULL, 16); + if ((flags & TUN_TYPE_MASK) == IFF_TAP) { + + devices[count++] = strdup(d->d_name); + if (count == capacity) { + char **tmp; + capacity *= 2; + tmp = (char **)realloc(devices, sizeof(char *) * capacity); + if (tmp) devices = tmp; + else break; /* no mem? */ + } + + } + } + + } + closedir(dp); +#endif + +#if defined(__FreeBSD__) + /* dev/tapxxxx */ + dp = opendir("/dev/"); + if (!dp) goto fail; + for(;;) { + struct dirent *d = readdir(dp); + if (!d) break; + + if (d->d_name[0] == '.') continue; + if (strncmp(d->d_name, "tap", 3) == 0 && isdigit(d->d_name[3])) { + + devices[count++] = strdup(d->d_name); + if (count == capacity) { + char **tmp; + capacity *= 2; + tmp = (char **)realloc(devices, sizeof(char *) * capacity); + if (tmp) devices = tmp; + else break; /* no mem? */ + } + } + + } + closedir(dp); +#endif + + /* sort them ... */ + qsort(devices, count, sizeof(char *), cmp); + + adapter_count = count; + return 1; + +fail: + if (dp) closedir(dp); + if (devices) for(i = 0; i = adapter_count) return 0; + + if (ppdescription) *ppdescription = NULL; + if (ppname) *ppname = strdup(devices[adapter_index]); + ++adapter_index; + return 1; +} + + +char *rawnet_arch_get_standard_interface(void) { + return lib_stralloc("tap65816"); +} + +int rawnet_arch_get_mtu(void) { + if (interface_fd < 0) return -1; + + #if defined(__linux__) + /* n.b. linux tap driver doesn't actually support SIOCGIFMTU */ + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + if (ioctl(interface_fd, SIOCGIFMTU, (void *) &ifr) < 0) return -1; /* ? */ + return ifr.ifr_mtu; + #endif + + #if defined(__FreeBSD__) + struct tapinfo ti; + if (ioctl(interface_fd, TAPSIFINFO, &ti) < 0) return -1; + return ti.mtu; + #endif + + return -1; +} + +int rawnet_arch_get_mac(uint8_t mac[6]) { + + + if (interface_fd < 0) return -1; + + #if defined(__linux__) + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + if (ioctl(interface_fd, SIOCGIFHWADDR, (void *)&ifr) < 0) return -1; + memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); + return 0; + #endif + + #if defined(__FreeBSD__) + if (ioctl(interface_fd, SIOCSIFADDR, mac) < 0) return -1; + return 0; + #endif + + return -1; + +} + +int rawnet_arch_status(void) { + return interface_fd >= 0 ? 1 : 0; +} + diff --git a/src/rawnet/rawnetarch_unix.c b/src/rawnet/rawnetarch_unix.c new file mode 100644 index 0000000..0609995 --- /dev/null +++ b/src/rawnet/rawnetarch_unix.c @@ -0,0 +1,511 @@ +/** \file rawnetarch_unix.c + * \brief Raw ethernet interface, architecture-dependent stuff + * + * \author Spiro Trikaliotis + * \author Bas Wassink + * + * These functions let the UI enumerate the available interfaces. + * + * First, rawnet_arch_enumadapter_open() is used to start enumeration. + * + * rawnet_arch_enumadapter() is then used to gather information for each adapter + * present on the system, where: + * + * ppname points to a pointer which will hold the name of the interface + * ppdescription points to a pointer which will hold the description of the + * interface + * + * For each of these parameters, new memory is allocated, so it has to be + * freed with lib_free(), except ppdescription, which can be `NULL`, though + * calling lib_free() on `NULL` is safe. + * + * rawnet_arch_enumadapter_close() must be used to stop processing. + * + * Each function returns 1 on success, and 0 on failure. + * rawnet_arch_enumadapter() only fails if there is no more adpater; in this + * case, *ppname and *ppdescription are not altered. + */ + +/* + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 "vice.h" + +#ifdef HAVE_RAWNET + +#include + +#include +#include +#include +#include + +// #include "lib.h" +// #include "log.h" +#include "rawnetarch.h" +#include "rawnetsupp.h" + +#if defined(__linux__) +#include +#include +#include +#endif + +/* + * FIXME: rename all remaining tfe_ stuff to rawnet_ + */ + +#define RAWNET_DEBUG_WARN 1 /* this should not be deactivated + * If this should not be deactived, why is this + * here at all? --compyx + */ + + +/** \brief Only select devices that are PCAP_IF_UP + * + * Since on Linux pcap_findalldevs() returns all interfaces, including special + * kernal devices such as nfqueue, filtering the list returned by pcap makes + * sense. Should this filtering cause trouble on other Unices, this define can + * be guarded with #ifdef SOME_UNIX_VERSION to disable the filtering. + */ +#ifdef PCAP_IF_UP +#define RAWNET_ONLY_IF_UP +#endif + + +/** #define RAWNET_DEBUG_ARCH 1 **/ +/** #define RAWNET_DEBUG_PKTDUMP 1 **/ + +/* ------------------------------------------------------------------------- */ +/* variables needed */ + +// static log_t rawnet_arch_log = LOG_ERR; + + +/** \brief Iterator for the list returned by pcap_findalldevs() + */ +static pcap_if_t *rawnet_pcap_dev_iter = NULL; + + +/** \brief Device list returned by pcap_findalldevs() + * + * Can be `NULL` since pcap_findalldevs() considers not finding any devices a + * succesful outcome. + */ +static pcap_if_t *rawnet_pcap_dev_list = NULL; + + +static pcap_t *rawnet_pcap_fp = NULL; +static char *rawnet_device_name = NULL; + + +/** \brief Buffer for pcap error messages + */ +static char rawnet_pcap_errbuf[PCAP_ERRBUF_SIZE]; + + +#ifdef RAWNET_DEBUG_PKTDUMP + +static void debug_output( const char *text, uint8_t *what, int count ) +{ + char buffer[256]; + char *p = buffer; + char *pbuffer1 = what; + int len1 = count; + int i; + + sprintf(buffer, "\n%s: length = %u\n", text, len1); + fprintf(stderr, "%s", buffer); + do { + p = buffer; + for (i=0; (i<8) && len1>0; len1--, i++) { + sprintf(p, "%02x ", (unsigned int)(unsigned char)*pbuffer1++); + p += 3; + } + *(p-1) = '\n'; *p = 0; + fprintf(stderr, "%s", buffer); + } while (len1>0); +} +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + + +int rawnet_arch_enumadapter_open(void) +{ + if (pcap_findalldevs(&rawnet_pcap_dev_list, rawnet_pcap_errbuf) == -1) { + log_message(rawnet_arch_log, + "ERROR in rawnet_arch_enumadapter_open: pcap_findalldevs: '%s'", + rawnet_pcap_errbuf); + return 0; + } + + if (!rawnet_pcap_dev_list) { + log_message(rawnet_arch_log, + "ERROR in rawnet_arch_enumadapter_open, finding all pcap " + "devices - Do we have the necessary privilege rights?"); + return 0; + } + + rawnet_pcap_dev_iter = rawnet_pcap_dev_list; + return 1; +} + + +/** \brief Get current pcap device iterator values + * + * The \a ppname and \a ppdescription are heap-allocated via lib_stralloc() + * and should thus be freed after use with lib_free(). Please not that + * \a ppdescription can be `NULL` due to pcap_if_t->description being `NULL`, + * so check against `NULL` before using it. Calling lib_free() on it is safe + * though, free(`NULL`) is guaranteed to just do nothing. + * + * \param[out] ppname device name + * \param[out] ppdescription device description + * + * \return bool (1 on success, 0 on failure) + */ +int rawnet_arch_enumadapter(char **ppname, char **ppdescription) +{ +#ifdef RAWNET_ONLY_IF_UP + /* only select devices that are up */ + while (rawnet_pcap_dev_iter != NULL + && !(rawnet_pcap_dev_iter->flags & PCAP_IF_UP)) { + rawnet_pcap_dev_iter = rawnet_pcap_dev_iter->next; + } +#endif + + if (rawnet_pcap_dev_iter == NULL) { + return 0; + } + + *ppname = lib_stralloc(rawnet_pcap_dev_iter->name); + /* carefull: pcap_if_t->description can be NULL and lib_stralloc() fails on + * passing `NULL` */ + if (rawnet_pcap_dev_iter->description != NULL) { + *ppdescription = lib_stralloc(rawnet_pcap_dev_iter->description); + } else { + *ppdescription = NULL; + } + + rawnet_pcap_dev_iter = rawnet_pcap_dev_iter->next; + + return 1; +} + +int rawnet_arch_enumadapter_close(void) +{ + if (rawnet_pcap_dev_list) { + pcap_freealldevs(rawnet_pcap_dev_list); + rawnet_pcap_dev_list = NULL; + } + return 1; +} + +static int rawnet_pcap_open_adapter(const char *interface_name) +{ + rawnet_pcap_fp = pcap_open_live((char*)interface_name, 1700, 1, 20, rawnet_pcap_errbuf); + if ( rawnet_pcap_fp == NULL) { + log_message(rawnet_arch_log, "ERROR opening adapter: '%s'", rawnet_pcap_errbuf); + return 0; + } + + if (pcap_setnonblock(rawnet_pcap_fp, 1, rawnet_pcap_errbuf) < 0) { + log_message(rawnet_arch_log, "WARNING: Setting PCAP to non-blocking failed: '%s'", rawnet_pcap_errbuf); + } + + /* Check the link layer. We support only Ethernet for simplicity. */ + if (pcap_datalink(rawnet_pcap_fp) != DLT_EN10MB) { + log_message(rawnet_arch_log, "ERROR: TFE works only on Ethernet networks."); + pcap_close(rawnet_pcap_fp); + rawnet_pcap_fp = NULL; + return 0; + } + rawnet_device_name = strdup(interface_name); + + return 1; +} + +/* ------------------------------------------------------------------------- */ +/* the architecture-dependend functions */ + +int rawnet_arch_init(void) +{ + //rawnet_arch_log = log_open("TFEARCH"); + + return 1; +} + +void rawnet_arch_pre_reset(void) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "rawnet_arch_pre_reset()." ); +#endif +} + +void rawnet_arch_post_reset(void) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "rawnet_arch_post_reset()." ); +#endif +} + +int rawnet_arch_activate(const char *interface_name) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "rawnet_arch_activate()." ); +#endif + if (!rawnet_pcap_open_adapter(interface_name)) { + return 0; + } + return 1; +} + +void rawnet_arch_deactivate( void ) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "rawnet_arch_deactivate()." ); +#endif +} + +void rawnet_arch_set_mac( const uint8_t mac[6] ) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); +#endif +} + +void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "New hash filter set: %08X:%08X.", hash_mask[1], hash_mask[0]); +#endif +} + +/* int bBroadcast - broadcast */ +/* int bIA - individual address (IA) */ +/* int bMulticast - multicast if address passes the hash filter */ +/* int bCorrect - accept correct frames */ +/* int bPromiscuous - promiscuous mode */ +/* int bIAHash - accept if IA passes the hash filter */ + +void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, "rawnet_arch_recv_ctl() called with the following parameters:" ); + log_message(rawnet_arch_log, "\tbBroadcast = %s", bBroadcast ? "TRUE" : "FALSE"); + log_message(rawnet_arch_log, "\tbIA = %s", bIA ? "TRUE" : "FALSE"); + log_message(rawnet_arch_log, "\tbMulticast = %s", bMulticast ? "TRUE" : "FALSE"); + log_message(rawnet_arch_log, "\tbCorrect = %s", bCorrect ? "TRUE" : "FALSE"); + log_message(rawnet_arch_log, "\tbPromiscuous = %s", bPromiscuous ? "TRUE" : "FALSE"); + log_message(rawnet_arch_log, "\tbIAHash = %s", bIAHash ? "TRUE" : "FALSE"); +#endif +} + +void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver ) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, + "rawnet_arch_line_ctl() called with the following parameters:"); + log_message(rawnet_arch_log, + "\tbEnableTransmitter = %s", bEnableTransmitter ? "TRUE" : "FALSE"); + log_message(rawnet_arch_log, + "\tbEnableReceiver = %s", bEnableReceiver ? "TRUE" : "FALSE"); +#endif +} + + +/** \brief Raw pcap packet + */ +typedef struct rawnet_pcap_internal_s { + unsigned int len; /**< length of packet data */ + uint8_t *buffer; /**< packet data */ +} rawnet_pcap_internal_t; + + +/** \brief Callback function invoked by libpcap for every incoming packet + * + * \param[in,out] param reference to internal VICE packet struct + * \param[in] header pcap header + * \param[in] pkt_data packet data + */ +static void rawnet_pcap_packet_handler(u_char *param, + const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + rawnet_pcap_internal_t *pinternal = (void*)param; + + /* determine the count of bytes which has been returned, + * but make sure not to overrun the buffer + */ + if (header->caplen < pinternal->len) { + pinternal->len = header->caplen; + } + + memcpy(pinternal->buffer, pkt_data, pinternal->len); +} + + +/** \brief Receives a frame + * + * If there's none, it returns a -1 in \a pinternal->len, if there is one, + * it returns the length of the frame in bytes in \a pinternal->len. + * + * It copies the frame to \a buffer and returns the number of copied bytes as + * the return value. + * + * \param[in,out] pinternal internal VICE packet struct + * + * \note At most 'len' bytes are copied. + * + * \return number of bytes copied or -1 on failure + */ +static int rawnet_arch_receive_frame(rawnet_pcap_internal_t *pinternal) +{ + int ret = -1; + + /* check if there is something to receive */ + if (pcap_dispatch(rawnet_pcap_fp, 1, rawnet_pcap_packet_handler, + (void*)pinternal) != 0) { + /* Something has been received */ + ret = pinternal->len; + } + +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, + "rawnet_arch_receive_frame() called, returns %d.", ret); +#endif + + return ret; +} + +int rawnet_arch_read(void *buffer, int nbyte) { + + int len; + + rawnet_pcap_internal_t internal = { nbyte, (uint8_t *)buffer }; + + len = rawnet_arch_receive_frame(&internal); + + if (len <= 0) return len; + +#ifdef RAWNET_DEBUG_PKTDUMP + debug_output("Received frame: ", internal.buffer, internal.len); +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + return len; + +} + + +int rawnet_arch_write(const void *buffer, int nbyte) { + +#ifdef RAWNET_DEBUG_PKTDUMP + debug_output("Transmit frame: ", buffer, nbyte); +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + + if (pcap_sendpacket(rawnet_pcap_fp, buffer, nbyte) < 0) { + log_message(rawnet_arch_log, "WARNING! Could not send packet!"); + return -1; + } + return nbyte; +} + + + +/** \brief Find default device on which to capture + * + * \return name of standard interface + * + * \note pcap_lookupdev() has been deprecated, so the correct way to get + * the default device is to use the first entry returned by + * pcap_findalldevs(). + * See http://www.tcpdump.org/manpages/pcap_lookupdev.3pcap.html + * + * \return default interface name or `NULL` when not found + * + * \note free the returned value with lib_free() if not `NULL` + */ +char *rawnet_arch_get_standard_interface(void) +{ + char *dev = NULL; + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *list; + + if (pcap_findalldevs(&list, errbuf) == 0 && list != NULL) { + dev = lib_stralloc(list[0].name); + pcap_freealldevs(list); + } + return dev; +} + +extern int rawnet_arch_get_mtu(void) { + + #if defined(__linux__) + int fd; + int ok; + struct ifreq ifr; + + if (!rawnet_device_name) return -1; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) return -1; + + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, rawnet_device_name); + ok = ioctl(fd, SIOCGIFMTU, (void *)&ifr); + close(fd); + if (ok < 0) return -1; + return ifr.ifr_mtu; + #endif + + return -1; +} + +extern int rawnet_arch_get_mac(uint8_t mac[6]) { + + #if defined(__linux__) + + int fd; + struct ifreq ifr; + int ok; + + if (!rawnet_device_name) return -1; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) return -1; + + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, rawnet_device_name); + ok = ioctl(fd, SIOCGIFHWADDR, &ifr); + close(fd); + if (ok < 0) return -1; + memcpy(mac, &ifr.ifr_hwaddr.sa_data, 6); + return 0; + #endif + + return -1; +} + +int rawnet_arch_status(void) { + return rawnet_pcap_fp ? 1 : 0; +} + + +#endif /* #ifdef HAVE_RAWNET */ diff --git a/src/rawnet/rawnetarch_vmnet.c b/src/rawnet/rawnetarch_vmnet.c new file mode 100644 index 0000000..8a1cbb1 --- /dev/null +++ b/src/rawnet/rawnetarch_vmnet.c @@ -0,0 +1,281 @@ +/* + * OS X 10.10+ + * vmnet support (clang -framework vmnet -framework Foundation) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rawnetarch.h" +#include "rawnetsupp.h" + + +static interface_ref interface; +static uint8_t interface_mac[6]; +static uint8_t interface_fake_mac[6]; +static uint64_t interface_mtu; +static uint64_t interface_packet_size; +static uint8_t *interface_buffer = NULL; +static vmnet_return_t interface_status; + +int rawnet_arch_init(void) { + interface = NULL; + return 1; +} +void rawnet_arch_pre_reset(void) { + /* NOP */ +} + +void rawnet_arch_post_reset(void) { + /* NOP */ +} + +int rawnet_arch_activate(const char *interface_name) { + + xpc_object_t dict; + dispatch_queue_t q; + dispatch_semaphore_t sem; + + /* + * there's no way to set the MAC address directly. + * using vmnet_interface_id_key w/ the previous interface id + * *MIGHT* re-use the previous MAC address. + */ + + if (interface) return 1; + + memset(interface_mac, 0, sizeof(interface_mac)); + memset(interface_fake_mac, 0, sizeof(interface_fake_mac)); + interface_status = 0; + interface_mtu = 0; + interface_packet_size = 0; + + dict = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_uint64(dict, vmnet_operation_mode_key, VMNET_SHARED_MODE); + sem = dispatch_semaphore_create(0); + q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); + + interface = vmnet_start_interface(dict, q, ^(vmnet_return_t status, xpc_object_t params){ + interface_status = status; + if (status == VMNET_SUCCESS) { + const char *cp; + cp = xpc_dictionary_get_string(params, vmnet_mac_address_key); + fprintf(stderr, "vmnet mac: %s\n", cp); + sscanf(cp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &interface_mac[0], + &interface_mac[1], + &interface_mac[2], + &interface_mac[3], + &interface_mac[4], + &interface_mac[5] + ); + + interface_mtu = xpc_dictionary_get_uint64(params, vmnet_mtu_key); + interface_packet_size = xpc_dictionary_get_uint64(params, vmnet_max_packet_size_key); + + fprintf(stderr, "vmnet mtu: %u\n", (unsigned)interface_mtu); + + } + dispatch_semaphore_signal(sem); + }); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + + if (interface_status == VMNET_SUCCESS) { + interface_buffer = (uint8_t *)malloc(interface_packet_size); + + /* copy mac to fake mac */ + memcpy(interface_fake_mac, interface_mac, 6); + + } else { + log_message(rawnet_arch_log, "vmnet_start_interface failed"); + if (interface) { + vmnet_stop_interface(interface, q, ^(vmnet_return_t status){ + dispatch_semaphore_signal(sem); + }); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + interface = NULL; + } + } + + + dispatch_release(sem); + xpc_release(dict); + return interface_status == VMNET_SUCCESS; +} + +void rawnet_arch_deactivate(void) { + + dispatch_queue_t q; + dispatch_semaphore_t sem; + + + if (interface) { + sem = dispatch_semaphore_create(0); + q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); + + vmnet_stop_interface(interface, q, ^(vmnet_return_t status){ + dispatch_semaphore_signal(sem); + }); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + dispatch_release(sem); + + interface = NULL; + interface_status = 0; + } + free(interface_buffer); + interface_buffer = NULL; + +} + +void rawnet_arch_set_mac(const uint8_t mac[6]) { + +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); +#endif + memcpy(interface_fake_mac, mac, 6); +} +void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) { + /* NOP */ +} + +void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) { + /* NOP */ +} + +void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) { + /* NOP */ +} + + +int rawnet_arch_read(void *buffer, int nbyte) { + + int count = 1; + int xfer; + vmnet_return_t st; + struct vmpktdesc v; + struct iovec iov; + + iov.iov_base = interface_buffer; + iov.iov_len = interface_packet_size; + + v.vm_pkt_size = interface_packet_size; + v.vm_pkt_iov = &iov; + v.vm_pkt_iovcnt = 1; + v.vm_flags = 0; + + st = vmnet_read(interface, &v, &count); + if (st != VMNET_SUCCESS) { + log_message(rawnet_arch_log, "vmnet_read failed!"); + return -1; + } + + if (count < 1) { + return 0; + } + + rawnet_fix_incoming_packet(interface_buffer, v.vm_pkt_size, interface_mac, interface_fake_mac); + + // iov.iov_len is not updated with the read count, apparently. + /* don't sebug multicast packets */ + if (interface_buffer[0] == 0xff || (interface_buffer[0] & 0x01) == 0 ) { + fprintf(stderr, "\nrawnet_arch_receive: %u\n", (unsigned)v.vm_pkt_size); + rawnet_hexdump(interface_buffer, v.vm_pkt_size); + } + + xfer = v.vm_pkt_size; + memcpy(buffer, interface_buffer, xfer); + + return xfer; +} + +int rawnet_arch_write(const void *buffer, int nbyte) { + + int count = 1; + vmnet_return_t st; + struct vmpktdesc v; + struct iovec iov; + + if (nbyte <= 0) return 0; + + if (nbyte > interface_packet_size) { + log_message(rawnet_arch_log, "packet is too big: %d", nbyte); + return -1; + } + + /* copy the buffer and fix the source mac address. */ + memcpy(interface_buffer, buffer, nbyte); + rawnet_fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac); + + iov.iov_base = interface_buffer; + iov.iov_len = nbyte; + + v.vm_pkt_size = nbyte; + v.vm_pkt_iov = &iov; + v.vm_pkt_iovcnt = 1; + v.vm_flags = 0; + + + fprintf(stderr, "\nrawnet_arch_transmit: %u\n", (unsigned)iov.iov_len); + rawnet_hexdump(interface_buffer, v.vm_pkt_size); + + + st = vmnet_write(interface, &v, &count); + + if (st != VMNET_SUCCESS) { + log_message(rawnet_arch_log, "vmnet_write failed!"); + return -1; + } + return nbyte; +} + + + + +static unsigned adapter_index = 0; +int rawnet_arch_enumadapter_open(void) { + adapter_index = 0; + return 1; +} + +int rawnet_arch_enumadapter(char **ppname, char **ppdescription) { + + if (adapter_index == 0) { + ++adapter_index; + if (ppname) *ppname = lib_stralloc("vmnet"); + if (ppdescription) *ppdescription = lib_stralloc("vmnet"); + return 1; + } + return 0; +} + +int rawnet_arch_enumadapter_close(void) { + return 1; +} + +char *rawnet_arch_get_standard_interface(void) { + return lib_stralloc("vmnet"); +} + +int rawnet_arch_get_mtu(void) { + return interface ? interface_mtu : -1; +} + +int rawnet_arch_get_mac(uint8_t mac[6]) { + if (interface) { + memcpy(mac, interface_mac, 6); + return 1; + } + return -1; +} + + +int rawnet_arch_status(void) { + return interface ? 1 : 0; +} + diff --git a/src/rawnet/rawnetarch_vmnet_helper.c b/src/rawnet/rawnetarch_vmnet_helper.c new file mode 100644 index 0000000..1e8eb23 --- /dev/null +++ b/src/rawnet/rawnetarch_vmnet_helper.c @@ -0,0 +1,512 @@ +/* + * OS X 10.10+ + * vmnet support (clang -framework vmnet -framework Foundation) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rawnetarch.h" +#include "rawnetsupp.h" + + +enum { + MSG_QUIT, + MSG_STATUS, + MSG_READ, + MSG_WRITE +}; +#define MAKE_MSG(msg, extra) (msg | ((extra) << 8)) + +static uint8_t interface_mac[6]; +static uint8_t interface_fake_mac[6]; +static uint32_t interface_mtu; +static uint32_t interface_packet_size; +static uint8_t *interface_buffer = NULL; + +static pid_t interface_pid = 0; +static int interface_pipe[2]; + + +static pid_t safe_waitpid(pid_t pid, int *stat_loc, int options) { + for(;;) { + pid_t rv = waitpid(pid, stat_loc,options); + if (rv < 0 && errno == EINTR) continue; + return rv; + } +} + +static ssize_t safe_read(void *data, size_t nbytes) { + for (;;) { + ssize_t rv = read(interface_pipe[0], data, nbytes); + if (rv < 0 && errno == EINTR) continue; + return rv; + } +} + +static ssize_t safe_readv(const struct iovec *iov, int iovcnt) { + + for(;;) { + ssize_t rv = readv(interface_pipe[0], iov, iovcnt); + if (rv < 0 && errno == EINTR) continue; + return rv; + } +} + + +static ssize_t safe_write(const void *data, size_t nbytes) { + for (;;) { + ssize_t rv = write(interface_pipe[1], data, nbytes); + if (rv < 0 && errno == EINTR) continue; + return rv; + } +} + +static ssize_t safe_writev(const struct iovec *iov, int iovcnt) { + + for(;;) { + ssize_t rv = writev(interface_pipe[1], iov, iovcnt); + if (rv < 0 && errno == EINTR) continue; + return rv; + } +} + +/* block the sigpipe signal */ +static int block_pipe(struct sigaction *oact) { + struct sigaction act; + memset(&act, 0, sizeof(act)); + act.sa_handler = SIG_IGN; + act.sa_flags = SA_RESTART; + + return sigaction(SIGPIPE, &act, oact); +} +static int restore_pipe(const struct sigaction *oact) { + return sigaction(SIGPIPE, oact, NULL); +} + +#if 0 +static int block_pipe(sigset_t *oldset) { + sigset_t set; + + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + sigaddset(&set, SIGCHLD); + + return sigprocmask(SIG_BLOCK, &set, oldset); +} +#endif + +static int check_child_status(void) { + pid_t pid; + int stat; + pid = safe_waitpid(interface_pid, &stat, WNOHANG); + + if (pid < 0 && errno == ECHILD) { + fprintf(stderr, "child process does not exist.\n"); + close(interface_pipe[0]); + close(interface_pipe[1]); + interface_pid = 0; + return 0; + } + if (pid == interface_pid) { + if (WIFEXITED(stat)) fprintf(stderr, "child process exited.\n"); + if (WIFSIGNALED(stat)) fprintf(stderr, "child process signalled.\n"); + + close(interface_pipe[0]); + close(interface_pipe[1]); + interface_pid = 0; + return 0; + } + return 1; +} + +static char *get_relative_path(const char *leaf) { + + uint32_t size = 0; + char *buffer = 0; + int ok; + char *cp; + int l; + + l = strlen(leaf); + ok = _NSGetExecutablePath(NULL, &size); + size += l + 1; + buffer = malloc(size); + if (buffer) { + ok = _NSGetExecutablePath(buffer, &size); + if (ok < 0) { + free(buffer); + return NULL; + } + cp = strrchr(buffer, '/'); + if (cp) + strcpy(cp + 1 , leaf); + else { + free(buffer); + buffer = NULL; + } + } + return buffer; +} + + +int rawnet_arch_init(void) { + //interface = NULL; + return 1; +} +void rawnet_arch_pre_reset(void) { + /* NOP */ +} + +void rawnet_arch_post_reset(void) { + /* NOP */ +} + + + + +int rawnet_arch_activate(const char *interface_name) { + + + int ok; + + char *argv[] = { "vmnet_helper", NULL }; + char *path = NULL; + + int pipe_stdin[2]; + int pipe_stdout[2]; + + struct sigaction oldaction; + + + if (interface_pid > 0) return 1; + + /* fd[0] = read, fd[1] = write */ + ok = pipe(pipe_stdin); + if (ok < 0) { warn("pipe"); return 0; } + + ok = pipe(pipe_stdout); + if (ok < 0) { warn("pipe"); return 0; } + + block_pipe(&oldaction); + +#ifdef USE_POSIX_SPAWN + posix_spawn_file_actions_t actions; + posix_spawnattr_t attr; + + posix_spawn_file_actions_init(&actions); + posix_spawnattr_init(&attr); + + + posix_spawn_file_actions_adddup2(&actions, pipe_stdin[0], STDIN_FILENO); + posix_spawn_file_actions_adddup2(&actions, pipe_stdout[1], STDOUT_FILENO); + + posix_spawn_file_actions_addclose(&actions, pipe_stdin[0]); + posix_spawn_file_actions_addclose(&actions, pipe_stdin[1]); + + posix_spawn_file_actions_addclose(&actions, pipe_stdout[0]); + posix_spawn_file_actions_addclose(&actions, pipe_stdout[1]); + + + path = get_relative_path("vmnet_helper"); + ok = posix_spawn(&interface_pid, path, &actions, &attr, argv, NULL); + free(path); + posix_spawn_file_actions_destroy(&actions); + posix_spawnattr_destroy(&attr); +#else + extern char **environ; + /* need to setsid() on the child */ + path = get_relative_path("vmnet_helper"); + + interface_pid = fork(); + if (interface_pid < 0) ok = 0; + if (interface_pid == 0) { + + dup2(pipe_stdin[0], STDIN_FILENO); + dup2(pipe_stdout[1], STDOUT_FILENO); + + close(pipe_stdin[0]); + close(pipe_stdin[1]); + close(pipe_stdout[0]); + close(pipe_stdout[1]); + + setsid(); + execve(path, argv, environ); + write(STDERR_FILENO, "execve failed\n", 14); + _exit(1); + } + free(path); +#endif + close(pipe_stdin[0]); + close(pipe_stdout[1]); + /* posix spawn returns 0 on success, error code on failure. */ + + if (ok != 0) { + fprintf(stderr, "posix_spawn vmnet_helper failed: %d\n", ok); + close(pipe_stdin[1]); + close(pipe_stdout[0]); + interface_pid = -1; + return 0; + } + + interface_pipe[0] = pipe_stdout[0]; + interface_pipe[1] = pipe_stdin[1]; + + /* now get the mac/mtu/etc */ + + uint32_t msg = MAKE_MSG(MSG_STATUS, 0); + ok = safe_write(&msg, 4); + if (ok != 4) goto fail; + + ok = safe_read(&msg, 4); + if (ok != 4) goto fail; + + if (msg != MAKE_MSG(MSG_STATUS, 6 + 4 + 4)) goto fail; + + struct iovec iov[3]; + iov[0].iov_len = 6; + iov[0].iov_base = interface_mac; + iov[1].iov_len = 4; + iov[1].iov_base = &interface_mtu; + iov[2].iov_len = 4; + iov[2].iov_base = &interface_packet_size; + + ok = safe_readv(iov, 3); + if (ok != 6 + 4 + 4) goto fail; + + /* copy mac to fake mac */ + memcpy(interface_fake_mac, interface_mac, 6); + + /* sanity check */ + /* expect MTU = 1500, packet_size = 1518 */ + if (interface_packet_size < 256) { + interface_packet_size = 1518; + } + interface_buffer = malloc(interface_packet_size); + if (!interface_buffer) goto fail; + + restore_pipe(&oldaction); + return 1; + +fail: + close(interface_pipe[0]); + close(interface_pipe[1]); + safe_waitpid(interface_pid, NULL, 0); + interface_pid = 0; + + restore_pipe(&oldaction); + return 0; +} + +void rawnet_arch_deactivate(void) { + + if (interface_pid) { + close(interface_pipe[0]); + close(interface_pipe[1]); + for(;;) { + int ok = waitpid(interface_pid, NULL, 0); + if (ok < 0 && errno == EINTR) continue; + break; + } + interface_pid = 0; + } + free(interface_buffer); + interface_buffer = NULL; +} + +void rawnet_arch_set_mac(const uint8_t mac[6]) { + +#ifdef RAWNET_DEBUG_ARCH + log_message( rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); +#endif + memcpy(interface_fake_mac, mac, 6); +} +void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) { + /* NOP */ +} + +void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) { + /* NOP */ +} + +void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) { + /* NOP */ +} + + + +int rawnet_arch_read(void *buffer, int nbyte) { + + + uint32_t msg; + int ok; + int xfer; + struct sigaction oldaction; + + if (interface_pid <= 0) return -1; + + block_pipe(&oldaction); + + msg = MAKE_MSG(MSG_READ, 0); + + ok = safe_write(&msg, 4); + if (ok != 4) goto fail; + + ok = safe_read(&msg, 4); + if (ok != 4) goto fail; + + if ((msg & 0xff) != MSG_READ) goto fail; + + xfer = msg >> 8; + if (xfer > interface_packet_size) { + + fprintf(stderr, "packet size too big: %d\n", xfer); + + /* drain the message ... */ + while (xfer) { + int count = interface_packet_size; + if (count > xfer) count = xfer; + ok = safe_read(interface_buffer, count); + if (ok < 0) goto fail; + xfer -= ok; + } + return -1; + } + + if (xfer == 0) return -1; + + ok = safe_read(interface_buffer, xfer); + if (ok != xfer) goto fail; + + + rawnet_fix_incoming_packet(interface_buffer, xfer, interface_mac, interface_fake_mac); + + /* don't sebug multicast packets */ + if (interface_buffer[0] == 0xff || (interface_buffer[0] & 0x01) == 0 ) { + fprintf(stderr, "\nrawnet_arch_receive: %u\n", (unsigned)xfer); + rawnet_hexdump(interface_buffer, xfer); + } + + if (xfer > nbyte) xfer = nbyte; + memcpy(buffer, interface_buffer, xfer); + + restore_pipe(&oldaction); + return xfer; + +fail: + /* check if process still ok? */ + check_child_status(); + restore_pipe(&oldaction); + return -1; +} + +int rawnet_arch_write(const void *buffer, int nbyte) { + + int ok; + uint32_t msg; + struct iovec iov[2]; + struct sigaction oldaction; + + if (interface_pid <= 0) return -1; + + + + if (nbyte <= 0) return 0; + + if (nbyte > interface_packet_size) { + log_message(rawnet_arch_log, "packet is too big: %d", nbyte); + return -1; + } + + + /* copy the buffer and fix the source mac address. */ + memcpy(interface_buffer, buffer, nbyte); + rawnet_fix_outgoing_packet(interface_buffer, nbyte, interface_mac, interface_fake_mac); + + + fprintf(stderr, "\nrawnet_arch_transmit: %u\n", (unsigned)nbyte); + rawnet_hexdump(interface_buffer, nbyte); + + + block_pipe(&oldaction); + + msg = MAKE_MSG(MSG_WRITE, nbyte); + + iov[0].iov_base = &msg; + iov[0].iov_len = 4; + iov[1].iov_base = interface_buffer; + iov[1].iov_len = nbyte; + + + ok = safe_writev(iov, 2); + if (ok != 4 + nbyte) goto fail; + + ok = safe_read(&msg, 4); + if (ok != 4) goto fail; + + if (msg != MAKE_MSG(MSG_WRITE, nbyte)) goto fail; + + restore_pipe(&oldaction); + return nbyte; + +fail: + check_child_status(); + restore_pipe(&oldaction); + return -1; +} + + + + +static unsigned adapter_index = 0; +int rawnet_arch_enumadapter_open(void) { + adapter_index = 0; + return 1; +} + +int rawnet_arch_enumadapter(char **ppname, char **ppdescription) { + + if (adapter_index == 0) { + ++adapter_index; + if (ppname) *ppname = lib_stralloc("vmnet"); + if (ppdescription) *ppdescription = lib_stralloc("vmnet"); + return 1; + } + return 0; +} + +int rawnet_arch_enumadapter_close(void) { + return 1; +} + +char *rawnet_arch_get_standard_interface(void) { + return lib_stralloc("vmnet"); +} + +int rawnet_arch_get_mtu(void) { + return interface_pid > 0 ? interface_mtu : -1; +} + +int rawnet_arch_get_mac(uint8_t mac[6]) { + if (interface_pid > 0) { + memcpy(mac, interface_mac, 6); + return 1; + } + return -1; +} + + +int rawnet_arch_status(void) { + return interface_pid > 0 ? 1 : 0; +} + diff --git a/src/rawnet/rawnetarch_win32.c b/src/rawnet/rawnetarch_win32.c new file mode 100644 index 0000000..5da1a46 --- /dev/null +++ b/src/rawnet/rawnetarch_win32.c @@ -0,0 +1,579 @@ +/** \file rawnetarch_win32.c + * \brief Raw ethernet interface, Win32 stuff + * + * \author Spiro Trikaliotis + */ + +/* + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 "vice.h" + +#ifdef HAVE_RAWNET + +/* #define WPCAP */ + + + +#include +/* prevent bpf redeclaration in packet32 */ +#ifndef BPF_MAJOR_VERSION +#define BPF_MAJOR_VERSION +#endif +#include +#include +#include + + +#include +#include +#include +#include + +// #include "lib.h" +// #include "log.h" +#include "rawnet.h" +#include "rawnetarch.h" +#include "rawnetsupp.h" + +typedef pcap_t *(*pcap_open_live_t)(const char *, int, int, int, char *); +typedef void *(*pcap_close_t)(pcap_t *); +typedef int (*pcap_dispatch_t)(pcap_t *, int, pcap_handler, u_char *); +typedef int (*pcap_setnonblock_t)(pcap_t *, int, char *); +typedef int (*pcap_datalink_t)(pcap_t *); +typedef int (*pcap_findalldevs_t)(pcap_if_t **, char *); +typedef void (*pcap_freealldevs_t)(pcap_if_t *); +typedef int (*pcap_sendpacket_t)(pcap_t *p, u_char *buf, int size); +typedef char *(*pcap_lookupdev_t)(char *); + + +typedef VOID (*PacketCloseAdapter_t)(LPADAPTER lpAdapter); +typedef LPADAPTER (*PacketOpenAdapter_t)(PCHAR AdapterName); +typedef BOOLEAN (*PacketSendPacket_t)(LPADAPTER AdapterObject, LPPACKET pPacket, BOOLEAN Sync); +typedef BOOLEAN (*PacketRequest_t)(LPADAPTER AdapterObject, BOOLEAN Set, PPACKET_OID_DATA OidData); + + +/** #define RAWNET_DEBUG_ARCH 1 **/ +/** #define RAWNET_DEBUG_PKTDUMP 1 **/ + +/* #define RAWNET_DEBUG_FRAMES - might be defined in rawnetarch.h ! */ + +#define RAWNET_DEBUG_WARN 1 /* this should not be deactivated */ + +static pcap_open_live_t p_pcap_open_live; +static pcap_close_t p_pcap_close; +static pcap_dispatch_t p_pcap_dispatch; +static pcap_setnonblock_t p_pcap_setnonblock; +static pcap_findalldevs_t p_pcap_findalldevs; +static pcap_freealldevs_t p_pcap_freealldevs; +static pcap_sendpacket_t p_pcap_sendpacket; +static pcap_datalink_t p_pcap_datalink; +static pcap_lookupdev_t p_pcap_lookupdev; + +static PacketCloseAdapter_t p_PacketCloseAdapter; +static PacketOpenAdapter_t p_PacketOpenAdapter; +static PacketSendPacket_t p_PacketSendPacket; +static PacketRequest_t p_PacketRequest; + +static HINSTANCE pcap_library = NULL; +static HINSTANCE packet_library = NULL; + +/* ------------------------------------------------------------------------- */ +/* variables needed */ + +//static log_t rawnet_arch_log = LOG_ERR; + +static pcap_if_t *EthernetPcapNextDev = NULL; +static pcap_if_t *EthernetPcapAlldevs = NULL; +static pcap_t *EthernetPcapFP = NULL; +static char *rawnet_device_name = NULL; + +static char EthernetPcapErrbuf[PCAP_ERRBUF_SIZE]; + +#ifdef RAWNET_DEBUG_PKTDUMP + +static void debug_output(const char *text, uint8_t *what, int count) +{ + char buffer[256]; + char *p = buffer; + char *pbuffer1 = what; + int len1 = count; + int i; + + sprintf(buffer, "\n%s: length = %u\n", text, len1); + OutputDebugString(buffer); + do { + p = buffer; + for (i = 0; (i < 8) && len1 > 0; len1--, i++) { + sprintf( p, "%02x ", (unsigned int)(unsigned char)*pbuffer1++); + p += 3; + } + *(p - 1) = '\n'; + *p = 0; + OutputDebugString(buffer); + } while (len1 > 0); +} +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + + +static void EthernetPcapFreeLibrary(void) +{ + if (pcap_library) { + if (!FreeLibrary(pcap_library)) { + log_message(rawnet_arch_log, "FreeLibrary WPCAP.DLL failed!"); + } + pcap_library = NULL; + + if (packet_library) FreeLibrary(packet_library); + packet_library = NULL; + + p_pcap_open_live = NULL; + p_pcap_close = NULL; + p_pcap_dispatch = NULL; + p_pcap_setnonblock = NULL; + p_pcap_findalldevs = NULL; + p_pcap_freealldevs = NULL; + p_pcap_sendpacket = NULL; + p_pcap_datalink = NULL; + p_pcap_lookupdev = NULL; + + p_PacketOpenAdapter = NULL; + p_PacketCloseAdapter = NULL; + p_PacketSendPacket = NULL; + p_PacketRequest = NULL; + } +} + +/* since I don't like typing too much... */ +#define GET_PROC_ADDRESS_AND_TEST( _name_ ) \ + p_##_name_ = (_name_##_t) GetProcAddress(x, #_name_); \ + if (!p_##_name_ ) { \ + log_message(rawnet_arch_log, "GetProcAddress " #_name_ " failed!"); \ + EthernetPcapFreeLibrary(); \ + return FALSE; \ + } + +static BOOL EthernetPcapLoadLibrary(void) +{ + /* + * npcap is c:\System32\Npcap\wpcap.dll + * winpcap is c:\System32\wpcap.dll + * + */ + HINSTANCE x = NULL; + if (!pcap_library) { + /* This inserts c:\System32\Npcap\ into the search path. */ + char buffer[512]; + unsigned length; + length = GetSystemDirectory(buffer, sizeof(buffer) - sizeof("\\Npcap")); + if (length) { + strcat(buffer + length, "\\Npcap"); + SetDllDirectory(buffer); + } + + pcap_library = LoadLibrary(TEXT("wpcap.dll")); + + if (!pcap_library) { + log_message(rawnet_arch_log, "LoadLibrary WPCAP.DLL failed!"); + return FALSE; + } + + x = pcap_library; + GET_PROC_ADDRESS_AND_TEST(pcap_open_live); + GET_PROC_ADDRESS_AND_TEST(pcap_close); + GET_PROC_ADDRESS_AND_TEST(pcap_dispatch); + GET_PROC_ADDRESS_AND_TEST(pcap_setnonblock); + GET_PROC_ADDRESS_AND_TEST(pcap_findalldevs); + GET_PROC_ADDRESS_AND_TEST(pcap_freealldevs); + GET_PROC_ADDRESS_AND_TEST(pcap_sendpacket); + GET_PROC_ADDRESS_AND_TEST(pcap_datalink); + GET_PROC_ADDRESS_AND_TEST(pcap_lookupdev); + } + + if (!packet_library) { + packet_library = LoadLibrary(TEXT("Packet.dll")); + + if (!packet_library) { + log_message(rawnet_arch_log, "LoadLibrary Packet.dll failed!"); + return FALSE; + } + + x = packet_library; + GET_PROC_ADDRESS_AND_TEST(PacketOpenAdapter); + GET_PROC_ADDRESS_AND_TEST(PacketCloseAdapter); + GET_PROC_ADDRESS_AND_TEST(PacketSendPacket); + GET_PROC_ADDRESS_AND_TEST(PacketRequest); + } + + return TRUE; +} + +#undef GET_PROC_ADDRESS_AND_TEST + + +/* + These functions let the UI enumerate the available interfaces. + + First, rawnet_arch_enumadapter_open() is used to start enumeration. + + rawnet_arch_enumadapter is then used to gather information for each adapter present + on the system, where: + + ppname points to a pointer which will hold the name of the interface + ppdescription points to a pointer which will hold the description of the interface + + For each of these parameters, new memory is allocated, so it has to be + freed with lib_free(). + + rawnet_arch_enumadapter_close() must be used to stop processing. + + Each function returns 1 on success, and 0 on failure. + rawnet_arch_enumadapter() only fails if there is no more adpater; in this case, + *ppname and *ppdescription are not altered. +*/ +int rawnet_arch_enumadapter_open(void) +{ + if (!EthernetPcapLoadLibrary()) { + return 0; + } + + if ((*p_pcap_findalldevs)(&EthernetPcapAlldevs, EthernetPcapErrbuf) == -1) { + log_message(rawnet_arch_log, "ERROR in rawnet_arch_enumadapter_open: pcap_findalldevs: '%s'", EthernetPcapErrbuf); + return 0; + } + + if (!EthernetPcapAlldevs) { + log_message(rawnet_arch_log, "ERROR in rawnet_arch_enumadapter_open, finding all pcap devices - Do we have the necessary privilege rights?"); + return 0; + } + + EthernetPcapNextDev = EthernetPcapAlldevs; + + return 1; +} + +int rawnet_arch_enumadapter(char **ppname, char **ppdescription) +{ + if (!EthernetPcapNextDev) { + return 0; + } + + *ppname = lib_stralloc(EthernetPcapNextDev->name); + *ppdescription = lib_stralloc(EthernetPcapNextDev->description); + + printf("%s: %s\n", + EthernetPcapNextDev->name ? EthernetPcapNextDev->name : "", + EthernetPcapNextDev->description ? EthernetPcapNextDev->description : "" + ); + EthernetPcapNextDev = EthernetPcapNextDev->next; + + return 1; +} + +int rawnet_arch_enumadapter_close(void) +{ + if (EthernetPcapAlldevs) { + (*p_pcap_freealldevs)(EthernetPcapAlldevs); + EthernetPcapAlldevs = NULL; + } + return 1; +} + +static BOOL EthernetPcapOpenAdapter(const char *interface_name) +{ + pcap_if_t *EthernetPcapDevice = NULL; + + if (!rawnet_enumadapter_open()) { + return FALSE; + } else { + /* look if we can find the specified adapter */ + char *pname; + char *pdescription; + BOOL found = FALSE; + + if (interface_name) { + /* we have an interface name, try it */ + EthernetPcapDevice = EthernetPcapAlldevs; + + while (rawnet_enumadapter(&pname, &pdescription)) { + if (strcmp(pname, interface_name) == 0) { + found = TRUE; + } + lib_free(pname); + lib_free(pdescription); + if (found) break; + EthernetPcapDevice = EthernetPcapNextDev; + } + } + + if (!found) { + /* just take the first adapter */ + EthernetPcapDevice = EthernetPcapAlldevs; + } + } + + EthernetPcapFP = (*p_pcap_open_live)(EthernetPcapDevice->name, 1700, 1, 20, EthernetPcapErrbuf); + if (EthernetPcapFP == NULL) { + log_message(rawnet_arch_log, "ERROR opening adapter: '%s'", EthernetPcapErrbuf); + rawnet_enumadapter_close(); + return FALSE; + } + + /* Check the link layer. We support only Ethernet for simplicity. */ + if ((*p_pcap_datalink)(EthernetPcapFP) != DLT_EN10MB) { + log_message(rawnet_arch_log, "ERROR: Ethernet works only on Ethernet networks."); + rawnet_enumadapter_close(); + (*p_pcap_close)(EthernetPcapFP); + EthernetPcapFP = NULL; + return FALSE; + } + + if ((*p_pcap_setnonblock)(EthernetPcapFP, 1, EthernetPcapErrbuf) < 0) { + log_message(rawnet_arch_log, "WARNING: Setting PCAP to non-blocking failed: '%s'", EthernetPcapErrbuf); + } + + rawnet_device_name = strdup(EthernetPcapDevice->name); + rawnet_enumadapter_close(); + return TRUE; +} + +/* ------------------------------------------------------------------------- */ +/* the architecture-dependend functions */ + +int rawnet_arch_init(void) +{ + //rawnet_arch_log = log_open("EthernetARCH"); + + if (!EthernetPcapLoadLibrary()) { + return 0; + } + + return 1; +} + +void rawnet_arch_pre_reset( void ) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, "rawnet_arch_pre_reset()."); +#endif +} + +void rawnet_arch_post_reset( void ) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, "rawnet_arch_post_reset()."); +#endif +} + +int rawnet_arch_activate(const char *interface_name) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, "rawnet_arch_activate()."); +#endif + if (!EthernetPcapOpenAdapter(interface_name)) { + return 0; + } + return 1; +} + +void rawnet_arch_deactivate( void ) +{ +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, "rawnet_arch_deactivate()."); +#endif +} + +void rawnet_arch_set_mac( const uint8_t mac[6] ) +{ +#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES) + log_message(rawnet_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); +#endif +} + +void rawnet_arch_set_hashfilter(const uint32_t hash_mask[2]) +{ +#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES) + log_message(rawnet_arch_log, "New hash filter set: %08X:%08X.", hash_mask[1], hash_mask[0]); +#endif +} + +/* int bBroadcast - broadcast */ +/* int bIA - individual address (IA) */ +/* int bMulticast - multicast if address passes the hash filter */ +/* int bCorrect - accept correct frames */ +/* int bPromiscuous - promiscuous mode */ +/* int bIAHash - accept if IA passes the hash filter */ + + +void rawnet_arch_recv_ctl(int bBroadcast, int bIA, int bMulticast, int bCorrect, int bPromiscuous, int bIAHash) +{ +#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES) + log_message(rawnet_arch_log, "rawnet_arch_recv_ctl() called with the following parameters:" ); + log_message(rawnet_arch_log, "\tbBroadcast = %s", bBroadcast ? "TRUE" : "FALSE" ); + log_message(rawnet_arch_log, "\tbIA = %s", bIA ? "TRUE" : "FALSE" ); + log_message(rawnet_arch_log, "\tbMulticast = %s", bMulticast ? "TRUE" : "FALSE" ); + log_message(rawnet_arch_log, "\tbCorrect = %s", bCorrect ? "TRUE" : "FALSE" ); + log_message(rawnet_arch_log, "\tbPromiscuous = %s", bPromiscuous ? "TRUE" : "FALSE" ); + log_message(rawnet_arch_log, "\tbIAHash = %s", bIAHash ? "TRUE" : "FALSE" ); +#endif +} + +void rawnet_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver) +{ +#if defined(RAWNET_DEBUG_ARCH) || defined(RAWNET_DEBUG_FRAMES) + log_message(rawnet_arch_log, "rawnet_arch_line_ctl() called with the following parameters:" ); + log_message(rawnet_arch_log, "\tbEnableTransmitter = %s", bEnableTransmitter ? "TRUE" : "FALSE" ); + log_message(rawnet_arch_log, "\tbEnableReceiver = %s", bEnableReceiver ? "TRUE" : "FALSE" ); +#endif +} + +typedef struct Ethernet_PCAP_internal_s { + unsigned int len; + uint8_t *buffer; +} Ethernet_PCAP_internal_t; + +/* Callback function invoked by libpcap for every incoming packet */ +static void EthernetPcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) +{ + Ethernet_PCAP_internal_t *pinternal = (void*)param; + + /* determine the count of bytes which has been returned, + * but make sure not to overrun the buffer + */ + if (header->caplen < pinternal->len) { + pinternal->len = header->caplen; + } + + memcpy(pinternal->buffer, pkt_data, pinternal->len); +} + +/* the following function receives a frame. + + If there's none, it returns a -1. + If there is one, it returns the length of the frame in bytes. + + It copies the frame to *buffer and returns the number of copied + bytes as return value. + + At most 'len' bytes are copied. +*/ +static int rawnet_arch_receive_frame(Ethernet_PCAP_internal_t *pinternal) +{ + int ret = -1; + + /* check if there is something to receive */ + if ((*p_pcap_dispatch)(EthernetPcapFP, 1, EthernetPcapPacketHandler, (void*)pinternal) != 0) { + /* Something has been received */ + ret = pinternal->len; + } + +#ifdef RAWNET_DEBUG_ARCH + log_message(rawnet_arch_log, "rawnet_arch_receive_frame() called, returns %d.", ret); +#endif + + return ret; +} + + +int rawnet_arch_read(void *buffer, int nbyte) { + + int len; + + Ethernet_PCAP_internal_t internal; + + internal.len = nbyte; + internal.buffer = (uint8_t *)buffer; + + len = rawnet_arch_receive_frame(&internal); + + if (len <= 0) return len; + +#ifdef RAWNET_DEBUG_PKTDUMP + debug_output("Received frame: ", internal.buffer, internal.len); +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + return len; + +} + + +int rawnet_arch_write(const void *buffer, int nbyte) { + +#ifdef RAWNET_DEBUG_PKTDUMP + debug_output("Transmit frame: ", buffer, nbyte); +#endif /* #ifdef RAWNET_DEBUG_PKTDUMP */ + + if ((*p_pcap_sendpacket)(EthernetPcapFP, (u_char *)buffer, nbyte) == -1) { + log_message(rawnet_arch_log, "WARNING! Could not send packet!"); + return -1; + } + return nbyte; +} + + +char *rawnet_arch_get_standard_interface(void) +{ + char *dev, errbuf[PCAP_ERRBUF_SIZE]; + + if (!EthernetPcapLoadLibrary()) { + return NULL; + } + + dev = lib_stralloc((*p_pcap_lookupdev)(errbuf)); + + return dev; +} + +extern int rawnet_arch_get_mtu(void) { + return -1; +} + +extern int rawnet_arch_get_mac(uint8_t mac[6]) { + + int rv = -1; + LPADAPTER outp = NULL; + char buffer[sizeof(PACKET_OID_DATA) + 6]; + PPACKET_OID_DATA data = (PPACKET_OID_DATA)buffer; + + + if (!packet_library) return -1; + + /* 802.5 = token ring, 802.3 = wired ethernet */ + data->Oid = OID_802_3_CURRENT_ADDRESS; // OID_802_3_CURRENT_ADDRESS ? OID_802_3_PERMANENT_ADDRESS ? + data->Length = 6; + + + outp = p_PacketOpenAdapter(rawnet_device_name); + if (!outp || outp->hFile == INVALID_HANDLE_VALUE) return -1; + + if (p_PacketRequest(outp, FALSE, data)) { + memcpy(mac, data->Data, 6); + rv = 0; + } + p_PacketCloseAdapter(outp); + return rv; +} + +int rawnet_arch_status(void) { + return EthernetPcapFP ? 1 : 0; +} + + +#endif /* #ifdef HAVE_RAWNET */ diff --git a/src/rawnet/rawnetsupp.c b/src/rawnet/rawnetsupp.c new file mode 100644 index 0000000..5fb6db8 --- /dev/null +++ b/src/rawnet/rawnetsupp.c @@ -0,0 +1,372 @@ +/* + * This file is a consolidation of functions required for tfe + * emulation taken from the following files + * + * lib.c - Library functions. + * util.c - Miscellaneous utility functions. + * crc32.c + * + * Written by + * Andreas Boose + * Ettore Perazzoli + * Andreas Matthies + * Tibor Biczo + * Spiro Trikaliotis * + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 "rawnetsupp.h" + + + +#define CRC32_POLY 0xedb88320 +static unsigned long crc32_table[256]; +static int crc32_is_initialized = 0; + +void lib_free(void *ptr) { + free(ptr); +} + +void *lib_malloc(size_t size) { + + void *ptr = malloc(size); + + if (ptr == NULL && size > 0) { + perror("lib_malloc"); + exit(-1); + } + + return ptr; +} + +/*-----------------------------------------------------------------------*/ + +/* Malloc enough space for `str', copy `str' into it and return its + address. */ +char *lib_stralloc(const char *str) { + char *ptr; + + if (str == NULL) { + fprintf(stderr, "lib_stralloc\n"); + exit(-1); + } + + ptr = strdup(str); + if (!ptr) { + perror("lib_stralloc"); + exit(-1); + } + + return ptr; +} + + + +/* Like realloc, but abort if not enough memory is available. */ +void *lib_realloc(void *ptr, size_t size) { + + + void *new_ptr = realloc(ptr, size); + + if (new_ptr == NULL) { + perror("lib_realloc"); + exit(-1); + } + + return new_ptr; +} + +// Util Stuff + +/* Set a new value to the dynamically allocated string *str. + Returns `-1' if nothing has to be done. */ +int util_string_set(char **str, const char *new_value) { + if (*str == NULL) { + if (new_value != NULL) + *str = lib_stralloc(new_value); + } else { + if (new_value == NULL) { + lib_free(*str); + *str = NULL; + } else { + /* Skip copy if src and dest are already the same. */ + if (strcmp(*str, new_value) == 0) + return -1; + + *str = (char *)lib_realloc(*str, strlen(new_value) + 1); + strcpy(*str, new_value); + } + } + return 0; +} + + +// crc32 Stuff + +unsigned long crc32_buf(const char *buffer, unsigned int len) { + int i, j; + unsigned long crc, c; + const char *p; + + if (!crc32_is_initialized) { + for (i = 0; i < 256; i++) { + c = (unsigned long) i; + for (j = 0; j < 8; j++) + c = c & 1 ? CRC32_POLY ^ (c >> 1) : c >> 1; + crc32_table[i] = c; + } + crc32_is_initialized = 1; + } + + crc = 0xffffffff; + for (p = buffer; len > 0; ++p, --len) + crc = (crc >> 8) ^ crc32_table[(crc ^ *p) & 0xff]; + + return ~crc; +} + +void rawnet_hexdump(const void *what, int count) { + static const char hex[] = "0123456789abcdef"; + char buffer1[16 * 3 + 1]; + char buffer2[16 + 1]; + unsigned offset; + unsigned char *cp = (unsigned char *)what; + + + offset = 0; + while (count > 0) { + unsigned char x = *cp++; + + buffer1[offset * 3] = hex[x >> 4]; + buffer1[offset * 3 + 1] = hex[x & 0x0f]; + buffer1[offset * 3 + 2] = ' '; + + buffer2[offset] = (x < 0x80) && isprint(x) ? x : '.'; + + + --count; + ++offset; + if (offset == 16 || count == 0) { + buffer1[offset * 3] = 0; + buffer2[offset] = 0; + fprintf(stderr, "%-50s %s\n", buffer1, buffer2); + offset = 0; + } + } +} + + + + + +enum { + eth_dest = 0, // destination address + eth_src = 6, // source address + eth_type = 12, // packet type + eth_data = 14, // packet data +}; + +enum { + ip_ver_ihl = 0, + ip_tos = 1, + ip_len = 2, + ip_id = 4, + ip_frag = 6, + ip_ttl = 8, + ip_proto = 9, + ip_header_cksum = 10, + ip_src = 12, + ip_dest = 16, + ip_data = 20, +}; + +enum { + udp_source = 0, // source port + udp_dest = 2, // destination port + udp_len = 4, // length + udp_cksum = 6, // checksum + udp_data = 8, // total length udp header +}; + +enum { + bootp_op = 0, // operation + bootp_hw = 1, // hardware type + bootp_hlen = 2, // hardware len + bootp_hp = 3, // hops + bootp_transid = 4, // transaction id + bootp_secs = 8, // seconds since start + bootp_flags = 10, // flags + bootp_ipaddr = 12, // ip address knwon by client + bootp_ipclient = 16, // client ip from server + bootp_ipserver = 20, // server ip + bootp_ipgateway = 24, // gateway ip + bootp_client_hrd = 28, // client mac address + bootp_spare = 34, + bootp_host = 44, + bootp_fname = 108, + bootp_data = 236, // total length bootp packet +}; + +enum { + arp_hw = 14, // hw type (eth = 0001) + arp_proto = 16, // protocol (ip = 0800) + arp_hwlen = 18, // hw addr len (eth = 06) + arp_protolen = 19, // proto addr len (ip = 04) + arp_op = 20, // request = 0001, reply = 0002 + arp_shw = 22, // sender hw addr + arp_sp = 28, // sender proto addr + arp_thw = 32, // target hw addr + arp_tp = 38, // target protoaddr + arp_data = 42, // total length of packet +}; + +enum { + dhcp_discover = 1, + dhcp_offer = 2, + dhcp_request = 3, + dhcp_decline = 4, + dhcp_pack = 5, + dhcp_nack = 6, + dhcp_release = 7, + dhcp_inform = 8, +}; + +static uint8_t oo[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t ff[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +static int is_arp(const uint8_t *packet, unsigned size) { + return size == arp_data + && packet[12] == 0x08 && packet[13] == 0x06 /* ARP */ + && packet[14] == 0x00 && packet[15] == 0x01 /* ethernet */ + && packet[16] == 0x08 && packet[17] == 0x00 /* ipv4 */ + && packet[18] == 0x06 /* hardware size */ + && packet[19] == 0x04 /* protocol size */ + ; +} + +static int is_broadcast(const uint8_t *packet, unsigned size) { + return !memcmp(packet + 0, ff, 6); +} + +static int is_unicast(const uint8_t *packet, unsigned size) { + return (*packet & 0x01) == 0; +} + +static int is_multicast(const uint8_t *packet, unsigned size) { + return (*packet & 0x01) == 0x01 && !is_broadcast(packet, size); +} + +static int is_dhcp_out(const uint8_t *packet, unsigned size) { + static uint8_t cookie[] = { 0x63, 0x82, 0x53, 0x63 }; + return size >= 282 + //&& !memcmp(&packet[0], ff, 6) /* broadcast */ + && packet[12] == 0x08 && packet[13] == 0x00 + && packet[14] == 0x45 /* version 4 */ + && packet[23] == 0x11 /* UDP */ + //&& !memcmp(&packet[26], oo, 4) /* source ip */ + //&& !memcmp(&packet[30], ff, 4) /* dest ip */ + && packet[34] == 0x00 && packet[35] == 0x44 /* source port */ + && packet[36] == 0x00 && packet[37] == 0x43 /* dest port */ + //&& packet[44] == 0x01 /* dhcp boot req */ + && packet[43] == 0x01 /* ethernet */ + && packet[44] == 0x06 /* 6 byte mac */ + && !memcmp(&packet[278], cookie, 4) + ; +} + + +static int is_dhcp_in(const uint8_t *packet, unsigned size) { + static uint8_t cookie[] = { 0x63, 0x82, 0x53, 0x63 }; + return size >= 282 + //&& !memcmp(&packet[0], ff, 6) /* broadcast */ + && packet[12] == 0x08 && packet[13] == 0x00 + && packet[14] == 0x45 /* version 4 */ + && packet[23] == 0x11 /* UDP */ + //&& !memcmp(&packet[26], oo, 4) /* source ip */ + //&& !memcmp(&packet[30], ff, 4) /* dest ip */ + && packet[34] == 0x00 && packet[35] == 0x43 /* source port */ + && packet[36] == 0x00 && packet[37] == 0x44 /* dest port */ + //&& packet[44] == 0x01 /* dhcp boot req */ + && packet[43] == 0x01 /* ethernet */ + && packet[44] == 0x06 /* 6 byte mac */ + && !memcmp(&packet[278], cookie, 4) + ; +} + +static unsigned ip_checksum(const uint8_t *packet) { + unsigned x = 0; + unsigned i; + for (i = 0; i < ip_data; i += 2) { + if (i == ip_header_cksum) continue; + x += packet[eth_data + i + 0 ] << 8; + x += packet[eth_data + i + 1]; + } + + /* add the carry */ + x += x >> 16; + x &= 0xffff; + return ~x & 0xffff; +} + +void rawnet_fix_incoming_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]) { + + if (memcmp(packet + 0, real_mac, 6) == 0) + memcpy(packet + 0, fake_mac, 6); + + /* dhcp request - fix the hardware address */ + if (is_unicast(packet, size) && is_dhcp_in(packet, size)) { + if (!memcmp(packet + 70, real_mac, 6)) + memcpy(packet + 70, fake_mac, 6); + return; + } + +} + +void rawnet_fix_outgoing_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]) { + + + + if (memcmp(packet + 6, fake_mac, 6) == 0) + memcpy(packet + 6, real_mac, 6); + + if (is_arp(packet, size)) { + /* sender mac address */ + if (!memcmp(packet + 22, fake_mac, 6)) + memcpy(packet + 22, real_mac, 6); + return; + } + + /* dhcp request - fix the hardware address */ + if (is_broadcast(packet, size) && is_dhcp_out(packet, size)) { + + if (!memcmp(packet + 70, fake_mac, 6)) + memcpy(packet + 70, real_mac, 6); + return; + } + +} diff --git a/src/rawnet/rawnetsupp.h b/src/rawnet/rawnetsupp.h new file mode 100644 index 0000000..012efad --- /dev/null +++ b/src/rawnet/rawnetsupp.h @@ -0,0 +1,62 @@ +/* + * This file is a consolidation of functions required for tfe + * emulation taken from the following files + * + * lib.h - Library functions. + * util.h - Miscellaneous utility functions. + * crc32.h + * + * Written by + * Andreas Boose + * Ettore Perazzoli + * Manfred Spraul + * Andreas Matthies + * Tibor Biczo + * Spiro Trikaliotis * + * + * This file is part of VICE, the Versatile Commodore Emulator. + * See README for copyright notice. + * + * 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 _TFESUPP_H +#define _TFESUPP_H + +#include +#include + +extern FILE* g_fh; // Filehandle for log file + +extern void *lib_malloc(size_t size); +extern void *lib_realloc(void *p, size_t size); +extern void lib_free(void *ptr); +extern char *lib_stralloc(const char *str); + +extern int util_string_set(char **str, const char *new_value); + +extern unsigned long crc32_buf(const char *buffer, unsigned int len); + +extern void rawnet_hexdump(const void *what, int count); +extern void rawnet_fix_incoming_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]); +extern void rawnet_fix_outgoing_packet(uint8_t *packet, unsigned size, const uint8_t real_mac[6], const uint8_t fake_mac[6]); + + +#define log_message(level,...) do { fprintf(stderr,__VA_ARGS__); fputs("\n", stderr); } while (0) +#endif diff --git a/src/rawnet/vmnet_helper.c b/src/rawnet/vmnet_helper.c new file mode 100644 index 0000000..6d108d0 --- /dev/null +++ b/src/rawnet/vmnet_helper.c @@ -0,0 +1,331 @@ +/* vmnet helper */ +/* because it needs root permissions ... sigh */ + +/* + * basicly... run as root, read messages from stdin, write to stdout. + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static interface_ref interface; +static uint8_t interface_mac[6]; +static long interface_mtu; +static long interface_packet_size; +static vmnet_return_t interface_status; + +static size_t buffer_size = 0; +static uint8_t *buffer = NULL; + +enum { + MSG_QUIT, + MSG_STATUS, + MSG_READ, + MSG_WRITE +}; +#define MAKE_MSG(msg, extra) (msg | ((extra) << 8)) + +ssize_t safe_read(void *buffer, size_t nbyte) { + + ssize_t rv; + for(;;) { + rv = read(STDIN_FILENO, buffer, nbyte); + if (rv < 0) { + if (errno == EINTR) continue; + err(1, "read"); + } + break; + } + return rv; +} + + +ssize_t safe_readv(const struct iovec *iov, int iovcnt) { + + ssize_t rv; + for(;;) { + rv = readv(STDIN_FILENO, iov, iovcnt); + if (rv < 0) { + if (errno == EINTR) continue; + err(1, "readv"); + } + break; + } + return rv; +} + +ssize_t safe_write(const void *buffer, size_t nbyte) { + + ssize_t rv; + for(;;) { + rv = write(STDOUT_FILENO, buffer, nbyte); + if (rv < 0) { + if (errno == EINTR) continue; + err(1, "write"); + } + break; + } + return rv; +} + +ssize_t safe_writev(const struct iovec *iov, int iovcnt) { + + ssize_t rv; + for(;;) { + rv = writev(STDOUT_FILENO, iov, iovcnt); + if (rv < 0) { + if (errno == EINTR) continue; + err(1, "writev"); + } + break; + } + return rv; +} + + +void msg_status(uint32_t size) { + struct iovec iov[4]; + + uint32_t msg = MAKE_MSG(MSG_STATUS, 6 + 4 + 4); + + iov[0].iov_len = 4; + iov[0].iov_base = &msg; + + iov[1].iov_len = 6; + iov[1].iov_base = interface_mac; + + iov[2].iov_len = 4; + iov[2].iov_base = &interface_mtu; + + iov[3].iov_len = 4; + iov[3].iov_base = &interface_packet_size; + + + safe_writev(iov, 4); +} + +int classify_mac(uint8_t *mac) { + if ((mac[0] & 0x01) == 0) return 1; /* unicast */ + if (memcmp(mac, "\xff\xff\xff\xff\xff\xff", 6) == 0) return 0xff; /* broadcast */ + return 2; /* multicast */ +} + +void msg_read(uint32_t flags) { + /* flag to block broadcast, multicast, etc? */ + + int count = 1; + int xfer; + vmnet_return_t st; + struct vmpktdesc v; + struct iovec iov[2]; + + uint32_t msg; + + + for(;;) { + int type; + + iov[0].iov_base = buffer; + iov[0].iov_len = interface_packet_size; + + v.vm_pkt_size = interface_packet_size; + v.vm_pkt_iov = iov; + v.vm_pkt_iovcnt = 1; + v.vm_flags = 0; + + count = 1; + st = vmnet_read(interface, &v, &count); + if (st != VMNET_SUCCESS) errx(1, "vmnet_read"); + + if (count < 1) break; + /* todo -- skip multicast messages based on flag? */ + type = classify_mac(buffer); + if (type == 2) continue; /* multicast */ + break; + } + + xfer = count == 1 ? v.vm_pkt_size : 0; + msg = MAKE_MSG(MSG_READ, xfer); + iov[0].iov_len = 4; + iov[0].iov_base = &msg; + iov[1].iov_len = xfer; + iov[1].iov_base = buffer; + + safe_writev(iov, count == 1 ? 2 : 1); +} + + +void msg_write(uint32_t size) { + + ssize_t ok; + + int count = 1; + vmnet_return_t st; + struct vmpktdesc v; + struct iovec iov; + uint32_t msg; + + if (size > interface_packet_size) errx(1, "packet too big"); + for(;;) { + ok = safe_read(buffer, size); + if (ok < 0) err(1,"read"); + if (ok != size) errx(1,"message truncated"); + break; + } + + iov.iov_base = buffer; + iov.iov_len = size; + + v.vm_pkt_size = size; + v.vm_pkt_iov = &iov; + v.vm_pkt_iovcnt = 1; + v.vm_flags = 0; + + st = vmnet_write(interface, &v, &count); + + if (st != VMNET_SUCCESS) errx(1, "vmnet_write"); + + + msg = MAKE_MSG(MSG_WRITE, size); + iov.iov_len = 4; + iov.iov_base = &msg; + + safe_writev(&iov, 1); +} + +void startup(void) { + + xpc_object_t dict; + dispatch_queue_t q; + dispatch_semaphore_t sem; + + + memset(interface_mac, 0, sizeof(interface_mac)); + interface_status = 0; + interface_mtu = 0; + interface_packet_size = 0; + + dict = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_uint64(dict, vmnet_operation_mode_key, VMNET_SHARED_MODE); + sem = dispatch_semaphore_create(0); + q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); + + interface = vmnet_start_interface(dict, q, ^(vmnet_return_t status, xpc_object_t params){ + interface_status = status; + if (status == VMNET_SUCCESS) { + const char *cp; + cp = xpc_dictionary_get_string(params, vmnet_mac_address_key); + fprintf(stderr, "vmnet mac: %s\n", cp); + sscanf(cp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &interface_mac[0], + &interface_mac[1], + &interface_mac[2], + &interface_mac[3], + &interface_mac[4], + &interface_mac[5] + ); + + interface_mtu = xpc_dictionary_get_uint64(params, vmnet_mtu_key); + interface_packet_size = xpc_dictionary_get_uint64(params, vmnet_max_packet_size_key); + + fprintf(stderr, "vmnet mtu: %u\n", (unsigned)interface_mtu); + fprintf(stderr, "vmnet packet size: %u\n", (unsigned)interface_packet_size); + + } + dispatch_semaphore_signal(sem); + }); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + + if (interface_status == VMNET_SUCCESS) { + buffer_size = (interface_packet_size * 2 + 1023) & ~1023; + buffer = (uint8_t *)malloc(buffer_size); + } else { + if (interface) { + vmnet_stop_interface(interface, q, ^(vmnet_return_t status){ + dispatch_semaphore_signal(sem); + }); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + interface = NULL; + } + errx(1,"vmnet_start_interface failed"); + } + + + dispatch_release(sem); + xpc_release(dict); + +} + +void shutdown(void) { + + dispatch_queue_t q; + dispatch_semaphore_t sem; + + + if (interface) { + sem = dispatch_semaphore_create(0); + q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); + + vmnet_stop_interface(interface, q, ^(vmnet_return_t status){ + dispatch_semaphore_signal(sem); + }); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + dispatch_release(sem); + + interface = NULL; + interface_status = 0; + } + free(buffer); + buffer = NULL; + buffer_size = 0; + +} + +int main(int argc, char **argv) { + + + uint32_t msg; + uint32_t extra; + ssize_t ok; + + + startup(); + + for(;;) { + ok = safe_read(&msg, 4); + if (ok == 0) break; + if (ok != 4) errx(1,"read msg"); + + extra = msg >> 8; + msg = msg & 0xff; + + switch(msg) { + case MSG_STATUS: + msg_status(extra); + break; + case MSG_QUIT: + shutdown(); + exit(0); + case MSG_READ: + msg_read(extra); + break; + case MSG_WRITE: + msg_write(extra); + break; + } + } + + shutdown(); + exit(0); +} diff --git a/src/sim65816.c b/src/sim65816.c index 99f846e..05e0191 100644 --- a/src/sim65816.c +++ b/src/sim65816.c @@ -14,6 +14,7 @@ #include "debug.h" #include "glog.h" #include "options.h" +#include "version.h" extern const char *g_config_gsplus_name_list[]; extern char g_config_gsplus_screenshot_dir[]; @@ -168,7 +169,7 @@ int g_imagewriter_paper = 0; int g_imagewriter_banner = 0; int g_config_iwm_vbl_count = 0; -const char g_gsplus_version_str[] = "0.14"; +const char g_gsplus_version_str[] = GSPLUS_VERSION_STRING; int g_pause=0; // OG Added pause #define START_DCYCS (0.0) diff --git a/src/string_extra.c b/src/string_extra.c new file mode 100644 index 0000000..62adc93 --- /dev/null +++ b/src/string_extra.c @@ -0,0 +1,33 @@ +#include +#include + +#include "string_extra.h" + +/* from MUSL/MIT */ + +#ifndef HAVE_STRCASESTR +char *strcasestr(const char *h, const char *n) +{ + size_t l = strlen(n); + for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h; + return 0; +} +#endif + +#ifndef HAVE_STRCASECMP +int strcasecmp(const char *l, const char *r) +{ + for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++); + return tolower(*l) - tolower(*r); +} +#endif + +#ifndef HAVE_STRNCASECMP + +int strncasecmp(const char *l, const char *r, size_t n) +{ + if (!n--) return 0; + for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--); + return tolower(*l) - tolower(*r); +} +#endif \ No newline at end of file diff --git a/src/string_extra.h.in b/src/string_extra.h.in new file mode 100644 index 0000000..7fb7e0f --- /dev/null +++ b/src/string_extra.h.in @@ -0,0 +1,20 @@ +#ifndef STRING_EXTRA_H +#define STRING_EXTRA_H + +#cmakedefine HAVE_STRCASECMP +#cmakedefine HAVE_STRNCASECMP +#cmakedefine HAVE_STRCASESTR + +#ifndef HAVE_STRCASECMP +extern int strcasecmp(const char *, const char *); +#endif + +#ifdef HAVE_STRNCASESTR +extern int strncasecmp(const char *, const char *, size_t); +#endif + +#ifndef HAVE_STRCASESTR +extern char *strcasestr(const char *, const char *); +#endif + +#endif diff --git a/src/version.h.in b/src/version.h.in new file mode 100644 index 0000000..244cccb --- /dev/null +++ b/src/version.h.in @@ -0,0 +1 @@ +#define GSPLUS_VERSION_STRING "@gsplus_VERSION_MAJOR@.@gsplus_VERSION_MINOR@" From 488af42cba0ca4a7974e206d980bc776ff761ef5 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Thu, 13 Feb 2020 12:19:17 -0600 Subject: [PATCH 2/7] adding version to ci --- .github/workflows/release.yml | 80 ++++++++++++++++++++++++----------- src/CMakeLists.txt | 1 + src/version.txt.in | 1 + 3 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 src/version.txt.in diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98e2c68..d8cb2a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,17 +44,21 @@ jobs: uses: actions/download-artifact@v1 with: name: data - - name: Get Tag Name - id: get_data + - name: Set Release Data in Outputs + id: release_data shell: bash run: | URL=`cat data/release_url.txt | tr -d '"'` + VERSION=`cat src/version.txt` echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/} - echo ::set-output name=RELEASE_URL::$URL - echo "URL = $URL" - echo name=SOURCE_TAG::${GITHUB_REF#refs/tags/} + echo ::set-output name=URL::$URL + echo ::set-output name=VERSION::$VERSION + echo "SOURCE_TAG::${GITHUB_REF#refs/tags/}" + echo "URL::$URL" + echo "VERSION::$VERSION" - uses: actions/checkout@v1 - uses: ilammy/msvc-dev-cmd@v1 + - name: Prep MacOSX if: matrix.os == 'macos-latest' shell: bash @@ -81,6 +85,7 @@ jobs: brew install -f sdl2_image-2.0.5.mojave.bottle.tar.gz curl -L https://bintray.com/homebrew/bottles/download_file?file_path=freetype-2.10.1.mojave.bottle.tar.gz -o freetype-2.10.1.mojave.bottle.tar.gz brew install -f freetype-2.10.1.mojave.bottle.tar.gz + - name: Prep Ubuntu if: matrix.os == 'ubuntu-latest' shell: bash @@ -91,34 +96,50 @@ jobs: - name: Build MacOS/Ubuntu if: matrix.os != 'windows-latest' - #working-directory: ./ + shell: bash run: | echo "${{ matrix.os }} BUILD" mkdir build ; cd build cmake .. make pwd ; ls -al - shell: bash + # - name: Package NonWindows # if: matrix.os != 'windows-latest' # run: | # zip --junk-paths merlin32.zip Source/merlin32 README.md + - name: Package MacOS if: matrix.os == 'macos-latest' - run: cd build ; chmod +x ../scripts/package-osx.sh ; ../scripts/package-osx.sh + run: cd build ; sh ../scripts/package-osx.sh + - name: Package Ubuntu if: matrix.os == 'ubuntu-latest' + env: + PACKAGE_NAME: gsplus-ubuntu run: | - PACKAGE_DIR=gsplus-ubuntu-sdl - mkdir $PACKAGE_DIR - mkdir $PACKAGE_DIR/doc - cp build/src/GSplus $PACKAGE_DIR/gsplus - cp build/src/to_pro $PACKAGE_DIR/to_pro - cp src/assets/config.txt $PACKAGE_DIR - cp LICENSE.txt $PACKAGE_DIR/doc/ - cp doc/gsplusmanual.pdf $PACKAGE_DIR/doc/ - cp doc/README.txt $PACKAGE_DIR/doc/ - tar -cvjf gsplus-ubuntu-sdl.tar.bz2 $PACKAGE_DIR + mkdir -p $PACKAGE_NAME + mkdir -p $PACKAGE_NAME/doc + cp build/src/GSplus $PACKAGE_NAME/gsplus + cp build/src/to_pro $PACKAGE_NAME/to_pro + cp src/assets/config.txt $PACKAGE_NAME + cp LICENSE.txt $PACKAGE_NAME/doc/ + cp doc/gsplusmanual.pdf $PACKAGE_NAME/doc/ + cp doc/README.txt $PACKAGE_NAME/doc/ + tar -cvjf $PACKAGE_NAME.tar.bz2 $PACKAGE_NAME + + - name: Package .deb + if: matrix.os == 'ubuntu-latest' + env: + PACKAGE_NAME: gsplus_${{ steps.release_data.outputs.VERSION }}-0 + run: | + #PACKAGE_NAME: gsplus_$VERSION-0 + mkdir -p $PACKAGE_NAME/usr/local/bin + mkdir -p $PACKAGE_NAME/DEBIAN + cp gsplus.bin $PACKAGE_NAME/usr/local/bin/gsplus + cp assets/control $PACKAGE_NAME/DEBIAN + dpkg-deb --build $PACKAGE_NAME + - name: Upload Release Asset MacOSX if: matrix.os == 'macos-latest' #id: upload-release-asset @@ -126,18 +147,29 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - upload_url: ${{ steps.get_data.outputs.RELEASE_URL }} + upload_url: ${{ steps.release_data.outputs.URL }} asset_path: ./build/GSplus-Install.dmg - asset_name: ${{ format('GSplus-Install-{0}-{1}.dmg', matrix.os, steps.get_data.outputs.SOURCE_TAG ) }} + asset_name: ${{ format('GSplus-Install-{0}-{1}.dmg', matrix.os, steps.release_data.outputs.SOURCE_TAG ) }} asset_content_type: application/x-apple-diskimage + - name: Upload Release Asset Ubuntu if: matrix.os == 'ubuntu-latest' - #id: upload-release-asset uses: actions/upload-release-asset@v1.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - upload_url: ${{ steps.get_data.outputs.RELEASE_URL }} - asset_path: ./gsplus-ubuntu-sdl.tar.bz2 - asset_name: ${{ format('gsplus-ubuntu-sdl2-{0}.tar.bz2', steps.get_data.outputs.SOURCE_TAG ) }} + upload_url: ${{ steps.release_data.outputs.URL }} + asset_path: ./gsplus-ubuntu.tar.bz2 + asset_name: ${{ format('gsplus-ubuntu-{0}.tar.bz2', steps.release_data.outputs.VERSION ) }} asset_content_type: application/x-bzip2 + + - name: Upload Release Asset .deb + if: matrix.os == 'ubuntu-latest' + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.release_data.outputs.URL }} + asset_path: ${{ format('./gsplus_{0}-0.deb', steps.release_data.outputs.VERSION ) }} + asset_name: ${{ format('gsplus_{0}-0.deb', steps.release_data.outputs.VERSION ) }} + asset_content_type: application/vnd.debian.binary-package diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30e18f1..2de2471 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,7 @@ check_function_exists(strcasestr HAVE_STRCASESTR) configure_file(string_extra.h.in string_extra.h) configure_file(version.h.in version.h) +configure_file(version.txt.in version.txt) set(generated_headers 8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h size_c.h size_s.h 8size_s.h 16size_s.h) add_custom_command( diff --git a/src/version.txt.in b/src/version.txt.in new file mode 100644 index 0000000..1c4297e --- /dev/null +++ b/src/version.txt.in @@ -0,0 +1 @@ +@gsplus_VERSION_MAJOR@.@gsplus_VERSION_MINOR@ From 3cb764d813c8a84eb4f2b17c70e005c5906c8357 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Sat, 15 Feb 2020 15:19:48 -0600 Subject: [PATCH 3/7] win --- .github/workflows/release.yml | 46 ++++++++++++++++++------- src/CMakeLists.txt | 1 + assets/control => src/assets/control.in | 5 ++- 3 files changed, 37 insertions(+), 15 deletions(-) rename assets/control => src/assets/control.in (67%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d8cb2a9..38de821 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,6 +39,8 @@ jobs: strategy: matrix: os: [ macos-latest, ubuntu-latest ] + # not working + #os: [ windows-latest ] steps: - name: Download Release Data uses: actions/download-artifact@v1 @@ -49,13 +51,10 @@ jobs: shell: bash run: | URL=`cat data/release_url.txt | tr -d '"'` - VERSION=`cat src/version.txt` echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/} echo ::set-output name=URL::$URL - echo ::set-output name=VERSION::$VERSION echo "SOURCE_TAG::${GITHUB_REF#refs/tags/}" echo "URL::$URL" - echo "VERSION::$VERSION" - uses: actions/checkout@v1 - uses: ilammy/msvc-dev-cmd@v1 @@ -83,8 +82,14 @@ jobs: brew install -f sdl2-2.0.10.mojave.bottle.tar.gz curl -L https://bintray.com/homebrew/bottles/download_file?file_path=sdl2_image-2.0.5.mojave.bottle.tar.gz -o sdl2_image-2.0.5.mojave.bottle.tar.gz brew install -f sdl2_image-2.0.5.mojave.bottle.tar.gz - curl -L https://bintray.com/homebrew/bottles/download_file?file_path=freetype-2.10.1.mojave.bottle.tar.gz -o freetype-2.10.1.mojave.bottle.tar.gz - brew install -f freetype-2.10.1.mojave.bottle.tar.gz + #curl -L https://bintray.com/homebrew/bottles/download_file?file_path=freetype-2.10.1.mojave.bottle.tar.gz -o freetype-2.10.1.mojave.bottle.tar.gz + #brew install -f freetype-2.10.1.mojave.bottle.tar.gz + + # - name: Prep windows + # if: matrix.os == 'windows-latest' + # shell: bash + # run: | + # pacman -S re2c mingw-w64-i686-cmake mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_image mingw-w64-i686-freetype - name: Prep Ubuntu if: matrix.os == 'ubuntu-latest' @@ -94,6 +99,15 @@ jobs: #sudo apt-get -y upgrade sudo apt-get -y install libpcap0.8-dev libfreetype6-dev libsdl2-dev libsdl2-image-dev + - name: Build windows + if: matrix.os == 'windows-latest' + run: | + mkdir build + cd build + cmake .. + dir + msbuild ALL_BUILD.vcxproj + - name: Build MacOS/Ubuntu if: matrix.os != 'windows-latest' shell: bash @@ -108,6 +122,12 @@ jobs: # if: matrix.os != 'windows-latest' # run: | # zip --junk-paths merlin32.zip Source/merlin32 README.md + - name: Set VERSION + id: version + run: | + VERSION=`cat build/src/version.txt` + echo ::set-output name=VERSION::$VERSION + echo "VERSION::$VERSION" - name: Package MacOS if: matrix.os == 'macos-latest' @@ -131,14 +151,16 @@ jobs: - name: Package .deb if: matrix.os == 'ubuntu-latest' env: - PACKAGE_NAME: gsplus_${{ steps.release_data.outputs.VERSION }}-0 + PACKAGE_NAME: gsplus_${{ steps.version.outputs.VERSION }}-0 run: | #PACKAGE_NAME: gsplus_$VERSION-0 mkdir -p $PACKAGE_NAME/usr/local/bin mkdir -p $PACKAGE_NAME/DEBIAN - cp gsplus.bin $PACKAGE_NAME/usr/local/bin/gsplus - cp assets/control $PACKAGE_NAME/DEBIAN + cp build/src/GSplus $PACKAGE_NAME/usr/local/bin/gsplus + cp build/src/assets/control $PACKAGE_NAME/DEBIAN dpkg-deb --build $PACKAGE_NAME + ls -al + pwd - name: Upload Release Asset MacOSX if: matrix.os == 'macos-latest' @@ -149,7 +171,7 @@ jobs: with: upload_url: ${{ steps.release_data.outputs.URL }} asset_path: ./build/GSplus-Install.dmg - asset_name: ${{ format('GSplus-Install-{0}-{1}.dmg', matrix.os, steps.release_data.outputs.SOURCE_TAG ) }} + asset_name: ${{ format('gsplus-macos-{0}.dmg', steps.version.outputs.VERSION ) }} asset_content_type: application/x-apple-diskimage - name: Upload Release Asset Ubuntu @@ -160,7 +182,7 @@ jobs: with: upload_url: ${{ steps.release_data.outputs.URL }} asset_path: ./gsplus-ubuntu.tar.bz2 - asset_name: ${{ format('gsplus-ubuntu-{0}.tar.bz2', steps.release_data.outputs.VERSION ) }} + asset_name: ${{ format('gsplus-ubuntu-{0}.tar.bz2', steps.version.outputs.VERSION ) }} asset_content_type: application/x-bzip2 - name: Upload Release Asset .deb @@ -170,6 +192,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.release_data.outputs.URL }} - asset_path: ${{ format('./gsplus_{0}-0.deb', steps.release_data.outputs.VERSION ) }} - asset_name: ${{ format('gsplus_{0}-0.deb', steps.release_data.outputs.VERSION ) }} + asset_path: ${{ format('./gsplus_{0}-0.deb', steps.version.outputs.VERSION ) }} + asset_name: ${{ format('gsplus_{0}-0.deb', steps.version.outputs.VERSION ) }} asset_content_type: application/vnd.debian.binary-package diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2de2471..3bf9d96 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,6 +82,7 @@ check_function_exists(strcasestr HAVE_STRCASESTR) configure_file(string_extra.h.in string_extra.h) configure_file(version.h.in version.h) configure_file(version.txt.in version.txt) +configure_file(assets/control.in assets/control) set(generated_headers 8inst_c.h 16inst_c.h 8inst_s.h 16inst_s.h size_c.h size_s.h 8size_s.h 16size_s.h) add_custom_command( diff --git a/assets/control b/src/assets/control.in similarity index 67% rename from assets/control rename to src/assets/control.in index 37f50b0..bc8a0fb 100644 --- a/assets/control +++ b/src/assets/control.in @@ -1,10 +1,9 @@ Package: gsplus -Version: 0.15-0 +Version: @gsplus_VERSION_MAJOR@.@gsplus_VERSION_MINOR@-0 Section: base Priority: optional Architecture: amd64 Depends: libsdl2-2.0-0, libfreetype6, libsdl2-image-2.0-0 Maintainer: Dagen Brock Description: GSplus - An Apple IIgs emulator for multiple platforms, - based on KEGS + An Apple IIgs emulator based on KEGS From e8ed62129fa9ea89f98ab18689ebfac9d6bdfac0 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Wed, 19 Aug 2020 14:32:43 -0500 Subject: [PATCH 4/7] fix for WAI instruction stalling on SCB interrupt firing - Fantavision --- src/instable.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/instable.h b/src/instable.h index 5ff6a5e..af1b7e7 100644 --- a/src/instable.h +++ b/src/instable.h @@ -2217,8 +2217,12 @@ instcb_SYM /* WAI */ b dispatch stw scratch2,r%g_wait_pending(scratch1) #else - g_wait_pending = 1; - CYCLES_FINISH + if(g_irq_pending) { + g_wait_pending = 0; + INC_KPC_1; + } else { + g_wait_pending = 1; + } #endif instcc_SYM /* CPY abs */ From c35ec63d73480c8f81b751e40334da70c0825a25 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Wed, 19 Aug 2020 14:42:11 -0500 Subject: [PATCH 5/7] inline asm for pa-risc removed --- src/instable.h | 1403 +----------------------------------------------- 1 file changed, 21 insertions(+), 1382 deletions(-) diff --git a/src/instable.h b/src/instable.h index af1b7e7..9f3972b 100644 --- a/src/instable.h +++ b/src/instable.h @@ -6,74 +6,6 @@ */ inst00_SYM /* brk */ -#ifdef ASM - ldb 1(scratch1),ret0 - ldil l%g_testing,arg3 - ldil l%g_num_brk,arg1 - ldw r%g_testing(arg3),arg3 - INC_KPC_2; - ldw r%g_num_brk(arg1),arg2 - comib,<> 0,arg3,brk_testing_SYM - extru kpc,31,16,arg0 - addi 1,arg2,arg2 - bb,>= psr,23,brk_native_SYM - stw arg2,r%g_num_brk(arg1) - - bl push_16,link - nop - - bl push_8,link - extru psr,31,8,arg0 ;B bit already on in PSR - - ldil l%0xfffe,arg0 - bl get_mem_long_16,link - ldo r%0xfffe(arg0),arg0 - - zdep ret0,31,16,kpc ;set kbank to 0 - -#if 0 - bl set_halt_act,link - ldi 3,arg0 -#endif - - - ldi 0,dbank ;clear dbank in emul mode - b dispatch - depi 1,29,2,psr ;ints masked, decimal off - - -brk_native_SYM - stw arg0,STACK_SAVE_COP_ARG0(sp) - bl push_8,link - extru kpc,15,8,arg0 - - bl push_16,link - ldw STACK_SAVE_COP_ARG0(sp),arg0 - - bl push_8,link - extru psr,31,8,arg0 - - ldil l%0xffe6,arg0 - bl get_mem_long_16,link - ldo r%0xffe6(arg0),arg0 - - zdep ret0,31,16,kpc ;zero kbank in kpc - -#if 0 -#endif - bl set_halt_act,link - ldi 3,arg0 - - b dispatch - depi 1,29,2,psr ;ints masked, decimal off - -brk_testing_SYM - DEC_KPC2; - CYCLES_PLUS_2 - b dispatch_done - depi RET_BREAK,3,4,ret0 - -#else GET_1BYTE_ARG; if(g_testing) { CYCLES_PLUS_2; @@ -96,7 +28,6 @@ brk_testing_SYM kpc = kpc & 0xffff; psr |= 0x4; psr &= ~(0x8); -#endif inst01_SYM /* ORA (Dloc,X) */ /* called with arg = val to ORA in */ @@ -104,55 +35,6 @@ inst01_SYM /* ORA (Dloc,X) */ ORA_INST(); inst02_SYM /* COP */ -#ifdef ASM - ldil l%g_num_cop,arg1 - INC_KPC_2; - ldw r%g_num_cop(arg1),arg2 - extru kpc,31,16,arg0 - addi 1,arg2,arg2 - bb,>= psr,23,cop_native_SYM - stw arg2,r%g_num_cop(arg1) - - bl push_16,link - nop - - bl push_8,link - extru psr,31,8,arg0 - - ldil l%0xfff4,arg0 - bl get_mem_long_16,link - ldo r%0xfff4(arg0),arg0 - - ldi 0,dbank ;clear dbank in emul mode - zdep ret0,31,16,kpc ;clear kbank - - bl set_halt_act,link - ldi 3,arg0 - - b dispatch - depi 1,29,2,psr ;ints masked, decimal off - -cop_native_SYM - stw arg0,STACK_SAVE_COP_ARG0(sp) - bl push_8,link - extru kpc,15,8,arg0 - - bl push_16,link - ldw STACK_SAVE_COP_ARG0(sp),arg0 - - bl push_8,link - extru psr,31,8,arg0 - - ldil l%0xffe4,arg0 - bl get_mem_long_16,link - ldo r%0xffe4(arg0),arg0 - - zdep ret0,31,16,kpc ;clear kbank - b dispatch - depi 1,29,2,psr ;ints masked, decimal off - - -#else g_num_cop++; INC_KPC_2; if(psr & 0x100) { @@ -170,7 +52,6 @@ cop_native_SYM kpc = kpc & 0xffff; psr |= 4; psr &= ~(0x8); -#endif inst03_SYM /* ORA Disp8,S */ GET_DISP8_S_RD(); @@ -193,74 +74,31 @@ inst07_SYM /* ORA [Dloc] */ ORA_INST(); inst08_SYM /* PHP */ -#ifdef ASM - dep neg,24,1,psr - ldil l%dispatch,link - INC_KPC_1 - depi 0,30,1,psr - comiclr,<> 0,zero,0 - depi 1,30,1,psr - ldo r%dispatch(link),link - b push_8 - extru psr,31,8,arg0 -#else INC_KPC_1; psr = (psr & ~0x82) | ((neg & 1) << 7) | ((!zero) << 1); PUSH8(psr); -#endif + inst09_SYM /* ORA #imm */ GET_IMM_MEM(); ORA_INST(); inst0a_SYM /* ASL a */ -#ifdef ASM -# ifdef ACC8 - ldi 0xff,scratch1 - sh1add acc,0,scratch3 - INC_KPC_1 - extru scratch3,24,1,neg - and scratch3,scratch1,zero - extru scratch3,23,1,scratch2 - dep zero,31,8,acc - b dispatch - dep scratch2,31,1,psr /* set carry */ -# else - zdepi -1,31,16,scratch1 - sh1add acc,0,scratch3 - INC_KPC_1 - extru scratch3,16,1,neg - and scratch3,scratch1,zero - extru scratch3,15,1,scratch2 - dep scratch2,31,1,psr /* set carry */ - b dispatch - dep zero,31,16,acc -# endif -#else INC_KPC_1; tmp1 = acc + acc; -# ifdef ACC8 +#ifdef ACC8 SET_CARRY8(tmp1); acc = (acc & 0xff00) + (tmp1 & 0xff); SET_NEG_ZERO8(acc & 0xff); -# else +#else SET_CARRY16(tmp1); acc = tmp1 & 0xffff; SET_NEG_ZERO16(acc); -# endif #endif inst0b_SYM /* PHD */ -#ifdef ASM - ldil l%dispatch,link - extru direct,31,16,arg0 - INC_KPC_1 - b push_16_unsafe - ldo r%dispatch(link),link -#else INC_KPC_1; PUSH16_UNSAFE(direct); -#endif inst0c_SYM /* TSB abs */ GET_ABS_RD(); @@ -280,16 +118,7 @@ inst0f_SYM /* ORA long */ inst10_SYM /* BPL disp8 */ -#ifdef ASM - COND_BR1 - comib,<> 0,neg,inst10_2_SYM - COND_BR2 - -inst10_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8(neg == 0); -#endif inst11_SYM /* ORA (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -320,14 +149,8 @@ inst17_SYM /* ORA [Dloc],Y */ ORA_INST(); inst18_SYM /* CLC */ -#ifdef ASM - INC_KPC_1 - b dispatch - depi 0,31,1,psr /* clear carry */ -#else psr = psr & (~1); INC_KPC_1; -#endif inst19_SYM /* ORA abs,y */ GET_ABS_Y_RD(); @@ -335,50 +158,21 @@ inst19_SYM /* ORA abs,y */ inst1a_SYM /* INC a */ -#ifdef ASM -# ifdef ACC8 - ldi 0xff,scratch2 - addi 1,acc,scratch1 - extru scratch1,24,1,neg - INC_KPC_1 - extru scratch1,31,8,zero - b dispatch - dep zero,31,8,acc -# else - zdepi -1,31,16,scratch2 - addi 1,acc,scratch1 - extru scratch1,16,1,neg - INC_KPC_1 - extru scratch1,31,16,zero - b dispatch - dep zero,31,16,acc -# endif -#else INC_KPC_1; -# ifdef ACC8 +#ifdef ACC8 acc = (acc & 0xff00) | ((acc + 1) & 0xff); SET_NEG_ZERO8(acc & 0xff); -# else +#else acc = (acc + 1) & 0xffff; SET_NEG_ZERO16(acc); -# endif #endif inst1b_SYM /* TCS */ -#ifdef ASM - copy acc,stack - extru,= psr,23,1,0 /* in emulation mode, stack page 1 */ - depi 1,23,24,stack - INC_KPC_1 - b dispatch - nop -#else stack = acc; INC_KPC_1; if(psr & 0x100) { stack = (stack & 0xff) + 0x100; } -#endif inst1c_SYM /* TRB Abs */ GET_ABS_RD(); @@ -398,24 +192,12 @@ inst1f_SYM /* ORA Long,X */ inst20_SYM /* JSR abs */ -#ifdef ASM - addi 2,kpc,arg0 - ldb 1(scratch1),scratch2 - CYCLES_PLUS_2 - ldb 2(scratch1),scratch1 - ldil l%dispatch,link - extru arg0,31,16,arg0 - ldo r%dispatch(link),link - dep scratch2,31,8,kpc - b push_16 - dep scratch1,23,8,kpc -#else GET_2BYTE_ARG; INC_KPC_2; PUSH16(kpc); kpc = (kpc & 0xff0000) + arg; CYCLES_PLUS_2; -#endif + inst21_SYM /* AND (Dloc,X) */ /* called with arg = val to AND in */ @@ -423,28 +205,12 @@ inst21_SYM /* AND (Dloc,X) */ AND_INST(); inst22_SYM /* JSL Long */ -#ifdef ASM - INC_KPC_3 - ldb 3(scratch1),scratch2 - copy kpc,arg0 - ldb 1(scratch1),kpc - ldb 2(scratch1),scratch1 - CYCLES_PLUS_3 - dep scratch2,15,8,kpc - stw scratch2,STACK_SAVE_INSTR_TMP1(sp) - bl push_24_unsafe,link - dep scratch1,23,8,kpc - - b dispatch - nop -#else GET_3BYTE_ARG; tmp1 = arg; CYCLES_PLUS_3; INC_KPC_3; PUSH24_UNSAFE(kpc); kpc = tmp1 & 0xffffff; -#endif inst23_SYM /* AND Disp8,S */ /* called with arg = val to AND in */ @@ -471,20 +237,6 @@ inst27_SYM /* AND [Dloc] */ AND_INST(); inst28_SYM /* PLP */ -#ifdef ASM - bl pull_8,link - ldi 0,zero - - extru psr,27,2,scratch2 /* save old x & m */ - dep ret0,31,8,psr - CYCLES_PLUS_1 - INC_KPC_1 - extru,<> ret0,30,1,0 - ldi 1,zero - copy scratch2,arg0 - b update_system_state - extru ret0,24,1,neg -#else PULL8(tmp1); tmp2 = psr; CYCLES_PLUS_1; @@ -493,7 +245,6 @@ inst28_SYM /* PLP */ zero = !(psr & 2); neg = (psr >> 7) & 1; UPDATE_PSR(psr, tmp2); -#endif inst29_SYM /* AND #imm */ @@ -501,60 +252,25 @@ inst29_SYM /* AND #imm */ AND_INST(); inst2a_SYM /* ROL a */ -#ifdef ASM -# ifdef ACC8 - extru psr,31,1,scratch2 - ldi 0xff,scratch1 - sh1add acc,scratch2,scratch3 - INC_KPC_1 - extru scratch3,24,1,neg - and scratch3,scratch1,zero - extru scratch3,23,1,scratch2 - dep zero,31,8,acc - b dispatch - dep scratch2,31,1,psr /* set carry */ -# else - extru psr,31,1,scratch2 - INC_KPC_1 - sh1add acc,scratch2,scratch3 - zdepi -1,31,16,scratch1 - extru scratch3,16,1,neg - and scratch3,scratch1,zero - extru scratch3,15,1,scratch2 - dep scratch2,31,1,psr /* set carry */ - b dispatch - dep zero,31,16,acc -# endif -#else INC_KPC_1; -# ifdef ACC8 +#ifdef ACC8 tmp1 = ((acc & 0xff) << 1) + (psr & 1); SET_CARRY8(tmp1); acc = (acc & 0xff00) + (tmp1 & 0xff); SET_NEG_ZERO8(tmp1 & 0xff); -# else +#else tmp1 = (acc << 1) + (psr & 1); SET_CARRY16(tmp1); acc = (tmp1 & 0xffff); SET_NEG_ZERO16(acc); -# endif #endif + inst2b_SYM /* PLD */ -#ifdef ASM - INC_KPC_1 - bl pull_16_unsafe,link - CYCLES_PLUS_1 - extru ret0,31,16,direct - extru ret0,16,1,neg - b dispatch - copy direct,zero -#else INC_KPC_1; PULL16_UNSAFE(direct); CYCLES_PLUS_1; SET_NEG_ZERO16(direct); -#endif inst2c_SYM /* BIT abs */ GET_ABS_RD(); @@ -574,16 +290,7 @@ inst2f_SYM /* AND long */ inst30_SYM /* BMI disp8 */ -#ifdef ASM - COND_BR1 - comib,= 0,neg,inst30_2_SYM - COND_BR2 - -inst30_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8(neg); -#endif inst31_SYM /* AND (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -614,60 +321,28 @@ inst37_SYM /* AND [Dloc],Y */ AND_INST(); inst38_SYM /* SEC */ -#ifdef ASM - INC_KPC_1 - b dispatch - depi 1,31,1,psr /* set carry */ -#else psr = psr | 1; INC_KPC_1; -#endif inst39_SYM /* AND abs,y */ GET_ABS_Y_RD(); AND_INST(); inst3a_SYM /* DEC a */ -#ifdef ASM -# ifdef ACC8 - addi -1,acc,scratch1 - extru scratch1,24,1,neg - INC_KPC_1 - extru scratch1,31,8,zero - b dispatch - dep zero,31,8,acc -# else - addi -1,acc,scratch1 - extru scratch1,16,1,neg - INC_KPC_1 - extru scratch1,31,16,zero - b dispatch - dep zero,31,16,acc -# endif -#else INC_KPC_1; -# ifdef ACC8 +#ifdef ACC8 acc = (acc & 0xff00) | ((acc - 1) & 0xff); SET_NEG_ZERO8(acc & 0xff); -# else +#else acc = (acc - 1) & 0xffff; SET_NEG_ZERO16(acc); -# endif #endif inst3b_SYM /* TSC */ /* set N,Z according to 16 bit acc */ -#ifdef ASM - copy stack,acc - extru stack,16,1,neg - INC_KPC_1 - b dispatch - extru acc,31,16,zero -#else INC_KPC_1; acc = stack; SET_NEG_ZERO16(acc); -#endif inst3c_SYM /* BIT Abs,x */ GET_ABS_X_RD(); @@ -687,43 +362,6 @@ inst3f_SYM /* AND Long,X */ inst40_SYM /* RTI */ -#ifdef ASM - bb,>= psr,23,rti_native_SYM - CYCLES_PLUS_1 -/* emulation */ - bl pull_24,link - ldi 0,zero - - extru psr,27,2,scratch2 - extru ret0,23,16,scratch3 - copy scratch2,arg0 - extru,<> ret0,30,1,0 - ldi 1,zero - dep ret0,31,8,psr - - extru ret0,24,1,neg - b update_system_state - dep scratch3,31,16,kpc - -rti_native_SYM - bl pull_8,link - ldi 0,zero - - copy ret0,scratch1 - extru ret0,24,1,neg - dep ret0,31,8,scratch1 - bl pull_24,link - stw scratch1,STACK_SAVE_INSTR_TMP1(sp) - - extru psr,27,2,scratch2 - ldw STACK_SAVE_INSTR_TMP1(sp),psr - extru ret0,31,24,kpc - extru,<> psr,30,1,0 - ldi 1,zero - - b update_system_state_and_change_kbank - copy scratch2,arg0 -#else CYCLES_PLUS_1 if(psr & 0x100) { PULL24(tmp1); @@ -742,8 +380,6 @@ rti_native_SYM PULL24(kpc); UPDATE_PSR(psr, tmp2); } -#endif - inst41_SYM /* EOR (Dloc,X) */ /* called with arg = val to EOR in */ @@ -751,20 +387,11 @@ inst41_SYM /* EOR (Dloc,X) */ EOR_INST(); inst42_SYM /* WDM */ -#ifdef ASM - ldb 1(scratch1),ret0 - CYCLES_PLUS_5 - CYCLES_PLUS_2 - INC_KPC_2 - b dispatch_done - depi RET_WDM,3,4,ret0 -#else GET_1BYTE_ARG; INC_KPC_2; CYCLES_PLUS_5; CYCLES_PLUS_2; FINISH(RET_WDM, arg & 0xff); -#endif inst43_SYM /* EOR Disp8,S */ /* called with arg = val to EOR in */ @@ -772,65 +399,6 @@ inst43_SYM /* EOR Disp8,S */ EOR_INST(); inst44_SYM /* MVP */ -#ifdef ASM - ldb 2(scratch1),scratch2 /* src bank */ - bb,< psr,23,inst44_notnat_SYM - ldb 1(scratch1),dbank /* dest bank */ - bb,< psr,27,inst44_notnat_SYM - stw scratch2,STACK_SRC_BANK(sp) - -inst44_loop_SYM - CYCLES_PLUS_1 - ldw STACK_SRC_BANK(sp),scratch2 - copy xreg,arg0 - - bl get_mem_long_8,link - dep scratch2,15,8,arg0 -/* got byte */ - copy ret0,arg1 - copy yreg,arg0 - bl set_mem_long_8,link - dep dbank,15,8,arg0 -/* wrote byte, dec acc */ - CYCLES_PLUS_2 - fldds 0(fcycles_stop_ptr),fcycles_stop - addi -1,xreg,xreg - zdepi -1,31,16,scratch2 - addi -1,yreg,yreg - addi -1,acc,acc - fcmp,<,dbl fcycles,fcycles_stop - and xreg,scratch2,xreg - extrs acc,31,16,scratch1 - and yreg,scratch2,yreg - - comib,= -1,scratch1,inst44_done_SYM - and acc,scratch2,acc - - ftest - b inst44_out_of_time_SYM - - CYCLES_PLUS_2 - b inst44_loop_SYM - nop - -/* get here if done */ -inst44_done_SYM - INC_KPC_3 - b dispatch - nop - -inst44_notnat_SYM - copy dbank,ret0 - dep scratch2,23,8,ret0 - CYCLES_PLUS_3 - depi RET_MVP,3,4,ret0 - b dispatch_done - CYCLES_PLUS_2 - -inst44_out_of_time_SYM -/* cycle have gone positive, just get out, do not update kpc */ - b,n dispatch -#else GET_2BYTE_ARG; /* arg & 0xff = dest bank, arg & 0xff00 = src bank */ if(psr & 0x110) { @@ -856,7 +424,6 @@ inst44_out_of_time_SYM break; } } -#endif inst45_SYM /* EOR Dloc */ @@ -875,27 +442,11 @@ inst47_SYM /* EOR [Dloc] */ EOR_INST(); inst48_SYM /* PHA */ -#ifdef ASM -# ifdef ACC8 - INC_KPC_1 - ldil l%dispatch,link - extru acc,31,8,arg0 - b push_8 - ldo r%dispatch(link),link -# else - INC_KPC_1 - ldil l%dispatch,link - extru acc,31,16,arg0 - b push_16 - ldo r%dispatch(link),link -# endif -#else INC_KPC_1; -# ifdef ACC8 +#ifdef ACC8 PUSH8(acc); -# else +#else PUSH16(acc); -# endif #endif inst49_SYM /* EOR #imm */ @@ -903,64 +454,27 @@ inst49_SYM /* EOR #imm */ EOR_INST(); inst4a_SYM /* LSR a */ -#ifdef ASM -# ifdef ACC8 - extru acc,31,1,scratch2 - INC_KPC_1 - extru acc,30,7,zero - ldi 0,neg - dep scratch2,31,1,psr /* set carry */ - b dispatch - dep zero,31,8,acc -# else - extru acc,31,1,scratch2 - INC_KPC_1 - extru acc,30,15,zero - ldi 0,neg - dep scratch2,31,1,psr /* set carry */ - b dispatch - dep zero,31,16,acc -# endif -#else INC_KPC_1; -# ifdef ACC8 +#ifdef ACC8 tmp1 = ((acc & 0xff) >> 1); SET_CARRY8(acc << 8); acc = (acc & 0xff00) + (tmp1 & 0xff); SET_NEG_ZERO8(tmp1 & 0xff); -# else +#else tmp1 = (acc >> 1); SET_CARRY8((acc << 8)); acc = (tmp1 & 0xffff); SET_NEG_ZERO16(acc); -# endif #endif inst4b_SYM /* PHK */ -#ifdef ASM - ldil l%dispatch,link - extru kpc,15,8,arg0 - INC_KPC_1 - b push_8 - ldo r%dispatch(link),link -#else PUSH8(kpc >> 16); INC_KPC_1; -#endif inst4c_SYM /* JMP abs */ -#ifdef ASM - ldb 1(scratch1),scratch2 - CYCLES_PLUS_1 - ldb 2(scratch1),scratch1 - dep scratch2,31,8,kpc - b dispatch - dep scratch1,23,8,kpc -#else GET_2BYTE_ARG; CYCLES_PLUS_1; kpc = (kpc & 0xff0000) + arg; -#endif inst4d_SYM /* EOR abs */ @@ -977,17 +491,7 @@ inst4f_SYM /* EOR long */ inst50_SYM /* BVC disp8 */ -#ifdef ASM - COND_BR1 - bb,< psr,25,inst50_2_SYM - COND_BR2 - -inst50_2_SYM - COND_BR_UNTAKEN - -#else BRANCH_DISP8((psr & 0x40) == 0); -#endif inst51_SYM /* EOR (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -1002,66 +506,6 @@ inst53_SYM /* EOR (Disp8,s),y */ EOR_INST(); inst54_SYM /* MVN */ -#ifdef ASM - ldb 2(scratch1),scratch2 /* src bank */ - bb,< psr,23,inst54_notnat_SYM - ldb 1(scratch1),dbank /* dest bank */ - bb,< psr,27,inst54_notnat_SYM - stw scratch2,STACK_SRC_BANK(sp) - -/* even in 8bit acc mode, use 16-bit accumulator! */ - -inst54_loop_SYM - CYCLES_PLUS_1 - ldw STACK_SRC_BANK(sp),scratch2 - copy xreg,arg0 - - bl get_mem_long_8,link - dep scratch2,15,8,arg0 -/* got byte */ - copy ret0,arg1 - copy yreg,arg0 - bl set_mem_long_8,link - dep dbank,15,8,arg0 -/* wrote byte, dec acc */ - CYCLES_PLUS_2 - fldds 0(fcycles_stop_ptr),fcycles_stop - addi 1,xreg,xreg - zdepi -1,31,16,scratch2 - addi 1,yreg,yreg - addi -1,acc,acc - fcmp,<,dbl fcycles,fcycles_stop - and xreg,scratch2,xreg - extrs acc,31,16,scratch1 - and yreg,scratch2,yreg - - comib,= -1,scratch1,inst54_done_SYM - and acc,scratch2,acc - ftest - b,n inst54_out_of_time_SYM - - CYCLES_PLUS_2 - b inst54_loop_SYM - nop - -/* get here if done */ -inst54_done_SYM - INC_KPC_3 - b dispatch - nop - -inst54_out_of_time_SYM -/* cycle have gone positive, just get out, don't update kpc */ - b,n dispatch - -inst54_notnat_SYM - copy dbank,ret0 - dep scratch2,23,8,ret0 - CYCLES_PLUS_3 - depi RET_MVN,3,4,ret0 - b dispatch_done - CYCLES_PLUS_3 -#else GET_2BYTE_ARG; /* arg & 0xff = dest bank, arg & 0xff00 = src bank */ if(psr & 0x110) { @@ -1087,7 +531,6 @@ inst54_notnat_SYM break; } } -#endif inst55_SYM /* EOR Dloc,x */ GET_DLOC_X_RD(); @@ -1102,71 +545,33 @@ inst57_SYM /* EOR [Dloc],Y */ EOR_INST(); inst58_SYM /* CLI */ -#ifdef ASM - INC_KPC_1 - b check_irqs_pending /* check for ints pending! */ - depi 0,29,1,psr /* clear int disable */ -#else psr = psr & (~4); INC_KPC_1; if(((psr & 0x4) == 0) && g_irq_pending) { FINISH(RET_IRQ, 0); } -#endif inst59_SYM /* EOR abs,y */ GET_ABS_Y_RD(); EOR_INST(); inst5a_SYM /* PHY */ -#ifdef ASM - INC_KPC_1 - ldil l%dispatch,link - bb,>= psr,27,phy_16_SYM - ldo r%dispatch(link),link - - b push_8 - copy yreg,arg0 - -phy_16_SYM - b push_16 - copy yreg,arg0 -#else INC_KPC_1; if(psr & 0x10) { PUSH8(yreg); } else { PUSH16(yreg); } -#endif inst5b_SYM /* TCD */ -#ifdef ASM - extru acc,31,16,direct - INC_KPC_1 - copy acc,zero - b dispatch - extru acc,16,1,neg -#else INC_KPC_1; direct = acc; SET_NEG_ZERO16(acc); -#endif inst5c_SYM /* JMP Long */ -#ifdef ASM - ldb 1(scratch1),kpc - ldb 2(scratch1),scratch2 - CYCLES_PLUS_1 - ldb 3(scratch1),arg0 /* new bank */ - dep scratch2,23,8,kpc - b dispatch - dep arg0,15,8,kpc -#else GET_3BYTE_ARG; CYCLES_PLUS_1; kpc = arg; -#endif inst5d_SYM /* EOR Abs,X */ GET_ABS_X_RD(); @@ -1182,19 +587,9 @@ inst5f_SYM /* EOR Long,X */ inst60_SYM /* RTS */ -#ifdef ASM - bl pull_16,link - CYCLES_PLUS_2 -/* ret0 is new kpc-1 */ - addi 1,ret0,ret0 - b dispatch - dep ret0,31,16,kpc -#else CYCLES_PLUS_2 PULL16(tmp1); kpc = (kpc & 0xff0000) + ((tmp1 + 1) & 0xffff); -#endif - inst61_SYM /* ADC (Dloc,X) */ /* called with arg = val to ADC in */ @@ -1202,23 +597,10 @@ inst61_SYM /* ADC (Dloc,X) */ ADC_INST(); inst62_SYM /* PER */ -#ifdef ASM - ldb 1(scratch1),ret0 - INC_KPC_3 - ldb 2(scratch1),scratch1 - CYCLES_PLUS_2 - ldil l%dispatch,link - dep scratch1,23,8,ret0 - ldo r%dispatch(link),link - add kpc,ret0,arg0 - b push_16_unsafe - extru arg0,31,16,arg0 -#else GET_2BYTE_ARG; CYCLES_PLUS_2; INC_KPC_3; PUSH16_UNSAFE(kpc + arg); -#endif inst63_SYM /* ADC Disp8,S */ /* called with arg = val to ADC in */ @@ -1245,110 +627,46 @@ inst67_SYM /* ADC [Dloc] */ ADC_INST(); inst68_SYM /* PLA */ -#ifdef ASM -# ifdef ACC8 - INC_KPC_1 - bl pull_8,link - CYCLES_PLUS_1 - extru ret0,31,8,zero - extru ret0,24,1,neg - b dispatch - dep ret0,31,8,acc -# else - INC_KPC_1 - bl pull_16,link - CYCLES_PLUS_1 - - extru ret0,31,16,zero - extru ret0,16,1,neg - b dispatch - extru ret0,31,16,acc -# endif -#else INC_KPC_1; CYCLES_PLUS_1; -# ifdef ACC8 +#ifdef ACC8 PULL8(tmp1); acc = (acc & 0xff00) + tmp1; SET_NEG_ZERO8(tmp1); -# else +#else PULL16(tmp1); acc = tmp1; SET_NEG_ZERO16(tmp1); -# endif #endif - inst69_SYM /* ADC #imm */ GET_IMM_MEM(); ADC_INST(); inst6a_SYM /* ROR a */ -#ifdef ASM -# ifdef ACC8 - extru psr,31,1,neg - INC_KPC_1 - extru acc,30,7,zero - dep neg,24,1,zero - dep acc,31,1,psr /* set carry */ - b dispatch - dep zero,31,8,acc -# else - extru psr,31,1,neg - INC_KPC_1 - extru acc,30,15,zero - dep neg,16,1,zero - dep acc,31,1,psr /* set carry */ - b dispatch - dep zero,31,16,acc -# endif -#else INC_KPC_1; -# ifdef ACC8 +#ifdef ACC8 tmp1 = ((acc & 0xff) >> 1) + ((psr & 1) << 7); SET_CARRY8((acc << 8)); acc = (acc & 0xff00) + (tmp1 & 0xff); SET_NEG_ZERO8(tmp1 & 0xff); -# else +#else tmp1 = (acc >> 1) + ((psr & 1) << 15); SET_CARRY16((acc << 16)); acc = (tmp1 & 0xffff); SET_NEG_ZERO16(acc); -# endif #endif inst6b_SYM /* RTL */ -#ifdef ASM - bl pull_24,link - CYCLES_PLUS_1 -/* ret0 is new kpc-1 */ - copy ret0,kpc - addi 1,ret0,scratch1 - b dispatch - dep scratch1,31,16,kpc - -#else CYCLES_PLUS_1; PULL24(tmp1); kpc = (tmp1 & 0xff0000) + ((tmp1 + 1) & 0xffff); -#endif inst6c_SYM /* JMP (abs) */ -#ifdef ASM - ldb 1(scratch1),arg0 - CYCLES_PLUS_1 - ldb 2(scratch1),scratch1 - bl get_mem_long_16,link - dep scratch1,23,8,arg0 -/* ret0 is addr to jump to */ - b dispatch - dep ret0,31,16,kpc -#else GET_2BYTE_ARG; CYCLES_PLUS_1; GET_MEMORY16(arg, tmp1, 1); kpc = (kpc & 0xff0000) + tmp1; -#endif inst6d_SYM /* ADC abs */ GET_ABS_RD(); @@ -1364,16 +682,7 @@ inst6f_SYM /* ADC long */ inst70_SYM /* BVS disp8 */ -#ifdef ASM - COND_BR1 - bb,>= psr,25,inst70_2_SYM - COND_BR2 - -inst70_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8((psr & 0x40)); -#endif inst71_SYM /* ADC (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -1388,15 +697,9 @@ inst73_SYM /* ADC (Disp8,s),y */ ADC_INST(); inst74_SYM /* STZ Dloc,x */ -#ifdef ASM - ldb 1(scratch1),arg0 - GET_DLOC_X_WR(); - STZ_INST(1); -#else GET_1BYTE_ARG; GET_DLOC_X_WR(); STZ_INST(1); -#endif inst75_SYM /* ADC Dloc,x */ GET_DLOC_X_RD(); @@ -1411,43 +714,14 @@ inst77_SYM /* ADC [Dloc],Y */ ADC_INST(); inst78_SYM /* SEI */ -#ifdef ASM - INC_KPC_1 - b dispatch - depi 1,29,1,psr /* set int disable */ -#else psr = psr | 4; INC_KPC_1; -#endif inst79_SYM /* ADC abs,y */ GET_ABS_Y_RD(); ADC_INST(); inst7a_SYM /* PLY */ -#ifdef ASM - INC_KPC_1 - bb,>= psr,27,inst7a_16bit_SYM - nop - - bl pull_8,link - CYCLES_PLUS_1 - - extru ret0,31,8,zero - extru ret0,24,1,neg - b dispatch - copy zero,yreg - -inst7a_16bit_SYM - bl pull_16,link - CYCLES_PLUS_1 - - extru ret0,31,16,zero - extru ret0,16,1,neg - b dispatch - copy zero,yreg - -#else INC_KPC_1; CYCLES_PLUS_1 if(psr & 0x10) { @@ -1457,42 +731,19 @@ inst7a_16bit_SYM PULL16(yreg); SET_NEG_ZERO16(yreg); } -#endif inst7b_SYM /* TDC */ -#ifdef ASM - extru direct,31,16,zero - copy direct,acc - INC_KPC_1 - b dispatch - extru direct,16,1,neg -#else INC_KPC_1; acc = direct; SET_NEG_ZERO16(direct); -#endif inst7c_SYM /* JMP (Abs,x) */ /* always access kbank, xreg cannot wrap into next bank */ -#ifdef ASM - ldb 1(scratch1),ret0 - copy kpc,scratch2 - ldb 2(scratch1),scratch1 - dep xreg,31,16,scratch2 - CYCLES_PLUS_2 - dep scratch1,23,8,ret0 - add ret0,scratch2,arg0 - bl get_mem_long_16,link - extru arg0,31,24,arg0 - b dispatch - dep ret0,31,16,kpc -#else GET_2BYTE_ARG; arg = (kpc & 0xff0000) + ((xreg + arg) & 0xffff); CYCLES_PLUS_2; GET_MEMORY16(arg, tmp1, 1); kpc = (kpc & 0xff0000) + tmp1; -#endif inst7d_SYM /* ADC Abs,X */ GET_ABS_X_RD(); @@ -1506,35 +757,17 @@ inst7f_SYM /* ADC Long,X */ GET_LONG_X_RD(); ADC_INST(); - inst80_SYM /* BRA */ -#ifdef ASM - COND_BR1 - COND_BR2 -#else BRANCH_DISP8(1); -#endif - inst81_SYM /* STA (Dloc,X) */ GET_DLOC_X_IND_ADDR(); STA_INST(0); inst82_SYM /* BRL disp16 */ -#ifdef ASM - ldb 1(scratch1),ret0 - CYCLES_PLUS_1 - ldb 2(scratch1),scratch1 - addi 3,kpc,scratch2 - dep scratch1,23,8,ret0 - add ret0,scratch2,scratch2 - b dispatch - dep scratch2,31,16,kpc -#else GET_2BYTE_ARG; CYCLES_PLUS_1; kpc = (kpc & 0xff0000) + ((kpc + 3 + arg) & 0xffff); -#endif inst83_SYM /* STA Disp8,S */ GET_DISP8_S_ADDR(); @@ -1544,7 +777,6 @@ inst84_SYM /* STY Dloc */ GET_DLOC_ADDR(); STY_INST(1); - inst85_SYM /* STA Dloc */ GET_DLOC_ADDR(); STA_INST(1); @@ -1553,86 +785,30 @@ inst86_SYM /* STX Dloc */ GET_DLOC_ADDR(); STX_INST(1); - inst87_SYM /* STA [Dloc] */ GET_DLOC_L_IND_ADDR(); STA_INST(0); inst88_SYM /* DEY */ -#ifdef ASM - INC_KPC_1 - bb,< psr,27,inst88_8bit_SYM - addi -1,yreg,yreg -/* 16 bit */ - extru yreg,31,16,zero - extru yreg,16,1,neg - b dispatch - copy zero,yreg - -inst88_8bit_SYM - extru yreg,31,8,zero - extru yreg,24,1,neg - b dispatch - copy zero,yreg -#else INC_KPC_1; SET_INDEX_REG(yreg - 1, yreg); -#endif inst89_SYM /* BIT #imm */ -#ifdef ASM GET_IMM_MEM(); -# ifdef ACC8 -/* Immediate BIT does not set condition flags */ - and acc,ret0,zero - b dispatch - extru zero,31,8,zero -# else - and acc,ret0,zero - b dispatch - extru zero,31,16,zero -# endif -#else - GET_IMM_MEM(); -# ifdef ACC8 +#ifdef ACC8 zero = (acc & arg) & 0xff; -# else +#else zero = (acc & arg) & 0xffff; -# endif #endif inst8a_SYM /* TXA */ -#ifdef ASM -# ifdef ACC8 - extru xreg,31,8,zero - INC_KPC_1 - extru xreg,24,1,neg - b dispatch - dep zero,31,8,acc -# else - extru xreg,31,16,zero - INC_KPC_1 - extru xreg,16,1,neg - b dispatch - zdep zero,31,16,acc -# endif -#else INC_KPC_1; arg = xreg; LDA_INST(); -#endif inst8b_SYM /* PHB */ -#ifdef ASM - ldil l%dispatch,link - extru dbank,31,8,arg0 - INC_KPC_1 - b push_8 - ldo r%dispatch(link),link -#else INC_KPC_1; PUSH8(dbank); -#endif inst8c_SYM /* STY abs */ GET_ABS_ADDR(); @@ -1653,17 +829,7 @@ inst8f_SYM /* STA long */ inst90_SYM /* BCC disp8 */ -#ifdef ASM - COND_BR1 - bb,< psr,31,inst90_2_SYM - COND_BR2 - -inst90_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8((psr & 0x01) == 0); -#endif - inst91_SYM /* STA (Dloc),y */ GET_DLOC_IND_Y_ADDR_FOR_WR(); @@ -1694,61 +860,24 @@ inst97_SYM /* STA [Dloc],Y */ STA_INST(0); inst98_SYM /* TYA */ -#ifdef ASM -# ifdef ACC8 - extru yreg,31,8,zero - INC_KPC_1 - extru yreg,24,1,neg - b dispatch - dep zero,31,8,acc -# else - extru yreg,31,16,zero - INC_KPC_1 - extru yreg,16,1,neg - b dispatch - zdep zero,31,16,acc -# endif -#else INC_KPC_1; arg = yreg; LDA_INST(); -#endif inst99_SYM /* STA abs,y */ GET_ABS_INDEX_ADDR_FOR_WR(yreg) STA_INST(0); inst9a_SYM /* TXS */ -#ifdef ASM - copy xreg,stack - extru,= psr,23,1,0 - depi 1,23,24,stack - INC_KPC_1 - b dispatch - nop -#else stack = xreg; if(psr & 0x100) { stack = 0x100 | (stack & 0xff); } INC_KPC_1; -#endif - inst9b_SYM /* TXY */ -#ifdef ASM - extru xreg,24,1,neg - INC_KPC_1 - extru,<> psr,27,1,0 ;skip next if 8bit - extru xreg,16,1,neg - copy xreg,yreg - b dispatch - copy xreg,zero -#else SET_INDEX_REG(xreg, yreg); INC_KPC_1; -#endif - inst9c_SYM /* STZ Abs */ GET_ABS_ADDR(); @@ -1766,25 +895,7 @@ inst9f_SYM /* STA Long,X */ GET_LONG_X_ADDR_FOR_WR(); STA_INST(0); - insta0_SYM /* LDY #imm */ -#ifdef ASM - INC_KPC_2 - bb,>= psr,27,insta0_16bit_SYM - ldb 1(scratch1),zero - - extru zero,24,1,neg - b dispatch - copy zero,yreg -insta0_16bit_SYM - ldb 2(scratch1),scratch1 - INC_KPC_1 - CYCLES_PLUS_1 - extru scratch1,24,1,neg - dep scratch1,23,8,zero - b dispatch - copy zero,yreg -#else INC_KPC_2; if((psr & 0x10) == 0) { GET_2BYTE_ARG; @@ -1794,8 +905,6 @@ insta0_16bit_SYM GET_1BYTE_ARG; } SET_INDEX_REG(arg, yreg); -#endif - insta1_SYM /* LDA (Dloc,X) */ /* called with arg = val to LDA in */ @@ -1803,23 +912,6 @@ insta1_SYM /* LDA (Dloc,X) */ LDA_INST(); insta2_SYM /* LDX #imm */ -#ifdef ASM - ldb 1(scratch1),zero - bb,>= psr,27,insta2_16bit_SYM - INC_KPC_2; - - extru zero,24,1,neg - b dispatch - copy zero,xreg -insta2_16bit_SYM - ldb 2(scratch1),scratch1 - INC_KPC_1 - CYCLES_PLUS_1 - extru scratch1,24,1,neg - dep scratch1,23,8,zero - b dispatch - copy zero,xreg -#else INC_KPC_2; if((psr & 0x10) == 0) { GET_2BYTE_ARG; @@ -1829,7 +921,6 @@ insta2_16bit_SYM GET_1BYTE_ARG; } SET_INDEX_REG(arg, xreg); -#endif insta3_SYM /* LDA Disp8,S */ /* called with arg = val to LDA in */ @@ -1837,14 +928,7 @@ insta3_SYM /* LDA Disp8,S */ LDA_INST(); insta4_SYM /* LDY Dloc */ -#ifdef ASM - ldb 1(scratch1),arg0 - GET_DLOC_WR() - b get_yreg_from_mem - nop -#else C_LDY_DLOC(); -#endif insta5_SYM /* LDA Dloc */ /* called with arg = val to LDA in */ @@ -1852,102 +936,39 @@ insta5_SYM /* LDA Dloc */ LDA_INST(); insta6_SYM /* LDX Dloc */ -#ifdef ASM - ldb 1(scratch1),arg0 - GET_DLOC_WR() - b get_xreg_from_mem - nop -#else C_LDX_DLOC(); -#endif insta7_SYM /* LDA [Dloc] */ GET_DLOC_L_IND_RD(); LDA_INST(); insta8_SYM /* TAY */ -#ifdef ASM - INC_KPC_1 - bb,>= psr,27,insta8_16bit_SYM - extru acc,31,8,zero - - extru acc,24,1,neg - b dispatch - copy zero,yreg - -insta8_16bit_SYM - extru acc,31,16,zero - extru acc,16,1,neg - b dispatch - copy zero,yreg -#else INC_KPC_1; SET_INDEX_REG(acc, yreg); -#endif insta9_SYM /* LDA #imm */ GET_IMM_MEM(); LDA_INST(); instaa_SYM /* TAX */ -#ifdef ASM - INC_KPC_1 - bb,>= psr,27,instaa_16bit_SYM - extru acc,31,8,zero - - extru acc,24,1,neg - b dispatch - copy zero,xreg - -instaa_16bit_SYM - extru acc,31,16,zero - extru acc,16,1,neg - b dispatch - copy zero,xreg -#else INC_KPC_1; SET_INDEX_REG(acc, xreg); -#endif instab_SYM /* PLB */ -#ifdef ASM - INC_KPC_1 - bl pull_8,link - CYCLES_PLUS_1 - - extru ret0,31,8,zero - extru ret0,24,1,neg - b dispatch - copy zero,dbank -#else INC_KPC_1; CYCLES_PLUS_1 PULL8(dbank); SET_NEG_ZERO8(dbank); -#endif instac_SYM /* LDY abs */ -#ifdef ASM - GET_ABS_ADDR() - b get_yreg_from_mem - nop -#else C_LDY_ABS(); -#endif - instad_SYM /* LDA abs */ GET_ABS_RD(); LDA_INST(); instae_SYM /* LDX abs */ -#ifdef ASM - GET_ABS_ADDR() - b get_xreg_from_mem - nop -#else C_LDX_ABS(); -#endif instaf_SYM /* LDA long */ GET_LONG_RD(); @@ -1955,16 +976,7 @@ instaf_SYM /* LDA long */ instb0_SYM /* BCS disp8 */ -#ifdef ASM - COND_BR1 - bb,>= psr,31,instb0_2_SYM - COND_BR2 - -instb0_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8((psr & 0x01)); -#endif instb1_SYM /* LDA (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -1979,106 +991,44 @@ instb3_SYM /* LDA (Disp8,s),y */ LDA_INST(); instb4_SYM /* LDY Dloc,x */ -#ifdef ASM - ldb 1(scratch1),arg0 - GET_DLOC_X_WR(); - b get_yreg_from_mem - nop -#else C_LDY_DLOC_X(); -#endif instb5_SYM /* LDA Dloc,x */ GET_DLOC_X_RD(); LDA_INST(); instb6_SYM /* LDX Dloc,y */ -#ifdef ASM - ldb 1(scratch1),arg0 - GET_DLOC_Y_WR(); - b get_xreg_from_mem - nop -#else C_LDX_DLOC_Y(); -#endif instb7_SYM /* LDA [Dloc],Y */ GET_DLOC_L_IND_Y_RD(); LDA_INST(); instb8_SYM /* CLV */ -#ifdef ASM - INC_KPC_1 - b dispatch - depi 0,25,1,psr /* clear overflow */ -#else psr = psr & ~0x40; INC_KPC_1; -#endif instb9_SYM /* LDA abs,y */ GET_ABS_Y_RD(); LDA_INST(); instba_SYM /* TSX */ -#ifdef ASM - INC_KPC_1 - bb,>= psr,27,instba_16bit_SYM - extru stack,31,8,zero - - extru stack,24,1,neg - b dispatch - copy zero,xreg -instba_16bit_SYM - copy stack,zero - extru stack,16,1,neg - b dispatch - copy zero,xreg -#else INC_KPC_1; SET_INDEX_REG(stack, xreg); -#endif instbb_SYM /* TYX */ -#ifdef ASM - INC_KPC_1 - bb,>= psr,27,instbb_16bit_SYM - copy yreg,xreg - -/* 8 bit */ - extru yreg,24,1,neg - b dispatch - copy yreg,zero -instbb_16bit_SYM - extru yreg,16,1,neg - b dispatch - copy yreg,zero -#else INC_KPC_1; SET_INDEX_REG(yreg, xreg); -#endif instbc_SYM /* LDY Abs,X */ -#ifdef ASM - GET_ABS_INDEX_ADDR_FOR_RD(xreg) - b get_yreg_from_mem - nop -#else C_LDY_ABS_X(); -#endif instbd_SYM /* LDA Abs,X */ GET_ABS_X_RD(); LDA_INST(); instbe_SYM /* LDX Abs,y */ -#ifdef ASM - GET_ABS_INDEX_ADDR_FOR_RD(yreg) - b get_xreg_from_mem - nop -#else C_LDX_ABS_Y(); -#endif instbf_SYM /* LDA Long,X */ GET_LONG_X_RD(); @@ -2086,21 +1036,7 @@ instbf_SYM /* LDA Long,X */ instc0_SYM /* CPY #imm */ -#ifdef ASM - ldb 1(scratch1),ret0 - bb,>= psr,27,instc0_16bit_SYM - INC_KPC_2; - CMP_INDEX_REG_MEAT8(yreg) -instc0_16bit_SYM - ldb 2(scratch1),scratch1 - CYCLES_PLUS_1 - INC_KPC_1 - dep scratch1,23,8,ret0 - CMP_INDEX_REG_MEAT16(yreg) -#else C_CPY_IMM(); -#endif - instc1_SYM /* CMP (Dloc,X) */ /* called with arg = val to CMP in */ @@ -2108,23 +1044,6 @@ instc1_SYM /* CMP (Dloc,X) */ CMP_INST(); instc2_SYM /* REP #imm */ -#ifdef ASM - ldb 1(scratch1),ret0 - extru psr,27,2,arg0 /* save old x & m */ - INC_KPC_2; - dep neg,24,1,psr - CYCLES_PLUS_1 - depi 0,30,1,psr - comiclr,<> 0,zero,0 - depi 1,30,1,psr - andcm psr,ret0,ret0 - ldi 0,zero - extru,<> ret0,30,1,0 - ldi 1,zero - dep ret0,31,8,psr - b update_system_state - extru ret0,24,1,neg -#else GET_1BYTE_ARG; tmp2 = psr; CYCLES_PLUS_1; @@ -2134,8 +1053,6 @@ instc2_SYM /* REP #imm */ zero = !(psr & 2); neg = (psr >> 7) & 1; UPDATE_PSR(psr, tmp2); -#endif - instc3_SYM /* CMP Disp8,S */ /* called with arg = val to CMP in */ @@ -2143,13 +1060,7 @@ instc3_SYM /* CMP Disp8,S */ CMP_INST(); instc4_SYM /* CPY Dloc */ -#ifdef ASM - GET_DLOC_ADDR() - CMP_INDEX_REG_LOAD(instc4_16bit_SYM, yreg) -#else C_CPY_DLOC(); -#endif - instc5_SYM /* CMP Dloc */ GET_DLOC_RD(); @@ -2164,77 +1075,27 @@ instc7_SYM /* CMP [Dloc] */ CMP_INST(); instc8_SYM /* INY */ -#ifdef ASM - INC_KPC_1 - addi 1,yreg,yreg - bb,>= psr,27,instc8_16bit_SYM - extru yreg,31,8,zero - - extru yreg,24,1,neg - b dispatch - copy zero,yreg - -instc8_16bit_SYM - extru yreg,31,16,zero - extru yreg,16,1,neg - b dispatch - copy zero,yreg -#else INC_KPC_1; SET_INDEX_REG(yreg + 1, yreg); -#endif instc9_SYM /* CMP #imm */ GET_IMM_MEM(); CMP_INST(); instca_SYM /* DEX */ -#ifdef ASM - INC_KPC_1 - addi -1,xreg,xreg - bb,>= psr,27,instca_16bit_SYM - extru xreg,31,8,zero - - extru xreg,24,1,neg - b dispatch - copy zero,xreg - -instca_16bit_SYM - extru xreg,31,16,zero - extru xreg,16,1,neg - b dispatch - copy zero,xreg -#else INC_KPC_1; SET_INDEX_REG(xreg - 1, xreg); -#endif instcb_SYM /* WAI */ -#ifdef ASM - ldil l%g_wait_pending,scratch1 - CYCLES_FINISH - ldi 1,scratch2 - b dispatch - stw scratch2,r%g_wait_pending(scratch1) -#else if(g_irq_pending) { g_wait_pending = 0; INC_KPC_1; } else { g_wait_pending = 1; } -#endif instcc_SYM /* CPY abs */ -#ifdef ASM - GET_ABS_ADDR() - CMP_INDEX_REG_LOAD(instcc_16bit_SYM, yreg) -#else C_CPY_ABS(); -#endif - - - instcd_SYM /* CMP abs */ GET_ABS_RD(); @@ -2244,23 +1105,12 @@ instce_SYM /* DEC abs */ GET_ABS_RD(); DEC_INST(0); - instcf_SYM /* CMP long */ GET_LONG_RD(); CMP_INST(); - instd0_SYM /* BNE disp8 */ -#ifdef ASM - COND_BR1 - comib,= 0,zero,instd0_2_SYM - COND_BR2 - -instd0_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8(zero != 0); -#endif instd1_SYM /* CMP (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -2275,22 +1125,10 @@ instd3_SYM /* CMP (Disp8,s),y */ CMP_INST(); instd4_SYM /* PEI Dloc */ -#ifdef ASM - GET_DLOC_ADDR() - bl get_mem_long_16,link - CYCLES_PLUS_1 - -/* push ret0 */ - extru ret0,31,16,arg0 - ldil l%dispatch,link - b push_16_unsafe - ldo r%dispatch(link),link -#else GET_DLOC_ADDR() GET_MEMORY16(arg, arg, 1); CYCLES_PLUS_1; PUSH16_UNSAFE(arg); -#endif instd5_SYM /* CMP Dloc,x */ GET_DLOC_X_RD(); @@ -2305,68 +1143,29 @@ instd7_SYM /* CMP [Dloc],Y */ CMP_INST(); instd8_SYM /* CLD */ -#ifdef ASM - INC_KPC_1 - b dispatch - depi 0,28,1,psr /* clear decimal */ -#else psr = psr & (~0x8); INC_KPC_1; -#endif instd9_SYM /* CMP abs,y */ GET_ABS_Y_RD(); CMP_INST(); instda_SYM /* PHX */ -#ifdef ASM - INC_KPC_1 - bb,>= psr,27,instda_16bit_SYM - ldil l%dispatch,link - - extru xreg,31,8,arg0 - b push_8 - ldo r%dispatch(link),link - -instda_16bit_SYM - extru xreg,31,16,arg0 - b push_16 - ldo r%dispatch(link),link -#else INC_KPC_1; if(psr & 0x10) { PUSH8(xreg); } else { PUSH16(xreg); } -#endif instdb_SYM /* STP */ -#ifdef ASM - ldb 1(scratch1),ret0 - CYCLES_PLUS_1 - b dispatch_done - depi RET_STP,3,4,ret0 -#else CYCLES_FINISH FINISH(RET_STP, 0); -#endif instdc_SYM /* JML (Abs) */ -#ifdef ASM - ldb 1(scratch1),arg0 - ldb 2(scratch1),scratch1 - CYCLES_PLUS_1 - bl get_mem_long_24,link - dep scratch1,23,8,arg0 - - b dispatch - copy ret0,kpc -#else GET_2BYTE_ARG; CYCLES_PLUS_1; GET_MEMORY24(arg, kpc, 1); -#endif instdd_SYM /* CMP Abs,X */ GET_ABS_X_RD(); @@ -2382,20 +1181,7 @@ instdf_SYM /* CMP Long,X */ inste0_SYM /* CPX #imm */ -#ifdef ASM - ldb 1(scratch1),ret0 - bb,>= psr,27,inste0_16bit_SYM - INC_KPC_2; - CMP_INDEX_REG_MEAT8(xreg) -inste0_16bit_SYM - ldb 2(scratch1),scratch1 - CYCLES_PLUS_1 - INC_KPC_1 - dep scratch1,23,8,ret0 - CMP_INDEX_REG_MEAT16(xreg) -#else C_CPX_IMM(); -#endif inste1_SYM /* SBC (Dloc,X) */ @@ -2404,23 +1190,6 @@ inste1_SYM /* SBC (Dloc,X) */ SBC_INST(); inste2_SYM /* SEP #imm */ -#ifdef ASM - ldb 1(scratch1),ret0 - extru psr,27,2,arg0 /* save old x & m */ - INC_KPC_2; - dep neg,24,1,psr - CYCLES_PLUS_1 - depi 0,30,1,psr - comiclr,<> 0,zero,0 - depi 1,30,1,psr - or psr,ret0,ret0 - ldi 0,zero - extru,<> ret0,30,1,0 - ldi 1,zero - dep ret0,31,8,psr - b update_system_state - extru ret0,24,1,neg -#else GET_1BYTE_ARG; tmp2 = psr; CYCLES_PLUS_1; @@ -2430,8 +1199,6 @@ inste2_SYM /* SEP #imm */ zero = !(psr & 2); neg = (psr >> 7) & 1; UPDATE_PSR(psr, tmp2); -#endif - inste3_SYM /* SBC Disp8,S */ /* called with arg = val to SBC in */ @@ -2439,13 +1206,7 @@ inste3_SYM /* SBC Disp8,S */ SBC_INST(); inste4_SYM /* CPX Dloc */ -#ifdef ASM - GET_DLOC_ADDR() - CMP_INDEX_REG_LOAD(inste4_16bit_SYM, xreg) -#else C_CPX_DLOC(); -#endif - inste5_SYM /* SBC Dloc */ /* called with arg = val to SBC in */ @@ -2461,67 +1222,25 @@ inste7_SYM /* SBC [Dloc] */ SBC_INST(); inste8_SYM /* INX */ -#ifdef ASM - INC_KPC_1 - addi 1,xreg,xreg - bb,>= psr,27,inste8_16bit_SYM - extru xreg,31,8,zero - - extru xreg,24,1,neg - b dispatch - copy zero,xreg - -inste8_16bit_SYM - extru xreg,31,16,zero - extru xreg,16,1,neg - b dispatch - copy zero,xreg -#else INC_KPC_1; SET_INDEX_REG(xreg + 1, xreg); -#endif inste9_SYM /* SBC #imm */ GET_IMM_MEM(); SBC_INST(); instea_SYM /* NOP */ -#ifdef ASM - INC_KPC_1 - b dispatch - nop -#else INC_KPC_1; -#endif insteb_SYM /* XBA */ -#ifdef ASM - extru acc,16,1,neg /* Z and N reflect status of low 8 */ - CYCLES_PLUS_1 /* bits of final acc value! */ - copy acc,scratch1 /* regardlessof ACC 8 or 16 bit */ - extru acc,23,8,acc - INC_KPC_1 - copy acc,zero - b dispatch - dep scratch1,23,8,acc -#else tmp1 = acc & 0xff; CYCLES_PLUS_1 acc = (tmp1 << 8) + (acc >> 8); INC_KPC_1; SET_NEG_ZERO8(acc & 0xff); -#endif instec_SYM /* CPX abs */ -#ifdef ASM - GET_ABS_ADDR() - CMP_INDEX_REG_LOAD(instec_16bit_SYM, xreg) -#else C_CPX_ABS(); -#endif - - - insted_SYM /* SBC abs */ GET_ABS_RD(); @@ -2531,23 +1250,12 @@ instee_SYM /* INC abs */ GET_ABS_RD(); INC_INST(0); - instef_SYM /* SBC long */ GET_LONG_RD(); SBC_INST(); - instf0_SYM /* BEQ disp8 */ -#ifdef ASM - COND_BR1 - comib,<> 0,zero,instf0_2_SYM - COND_BR2 - -instf0_2_SYM - COND_BR_UNTAKEN -#else BRANCH_DISP8(zero == 0); -#endif instf1_SYM /* SBC (Dloc),y */ GET_DLOC_IND_Y_RD(); @@ -2562,21 +1270,10 @@ instf3_SYM /* SBC (Disp8,s),y */ SBC_INST(); instf4_SYM /* PEA Abs */ -#ifdef ASM - ldb 1(scratch1),arg0 - ldil l%dispatch,link - ldb 2(scratch1),scratch1 - INC_KPC_3 - CYCLES_PLUS_1 - ldo r%dispatch(link),link - b push_16_unsafe - dep scratch1,23,8,arg0 -#else GET_2BYTE_ARG; CYCLES_PLUS_1; INC_KPC_3; PUSH16_UNSAFE(arg); -#endif instf5_SYM /* SBC Dloc,x */ GET_DLOC_X_RD(); @@ -2591,43 +1288,14 @@ instf7_SYM /* SBC [Dloc],Y */ SBC_INST(); instf8_SYM /* SED */ -#ifdef ASM - INC_KPC_1 - b dispatch - depi 1,28,1,psr /* set decimal */ -#else INC_KPC_1; psr |= 0x8; -#endif instf9_SYM /* SBC abs,y */ GET_ABS_Y_RD(); SBC_INST(); instfa_SYM /* PLX */ -#ifdef ASM - bb,< psr,27,instfa_8bit_SYM - CYCLES_PLUS_1 - - INC_KPC_1 - bl pull_16,link - nop - - extru ret0,31,16,zero - extru ret0,16,1,neg - b dispatch - copy zero,xreg - -instfa_8bit_SYM - INC_KPC_1 - bl pull_8,link - nop - - extru ret0,31,8,zero - extru ret0,24,1,neg - b dispatch - copy zero,xreg -#else INC_KPC_1; CYCLES_PLUS_1; if(psr & 0x10) { @@ -2637,42 +1305,14 @@ instfa_8bit_SYM PULL16(xreg); SET_NEG_ZERO16(xreg); } -#endif instfb_SYM /* XCE */ -#ifdef ASM - extru psr,27,2,arg0 /* save old x & m */ - INC_KPC_1 - extru psr,23,1,scratch1 /* e bit */ - dep psr,23,1,psr /* copy carry to e bit */ - b update_system_state - dep scratch1,31,1,psr /* copy e bit to carry */ -#else tmp2 = psr; INC_KPC_1; psr = (tmp2 & 0xfe) | ((tmp2 & 1) << 8) | ((tmp2 >> 8) & 1); UPDATE_PSR(psr, tmp2); -#endif instfc_SYM /* JSR (Abs,X) */ -#ifdef ASM - ldb 1(scratch1),ret0 - extru kpc,15,8,scratch2 - ldb 2(scratch1),scratch1 - dep scratch2,15,16,ret0 - INC_KPC_2; - dep scratch1,23,8,ret0 - add xreg,ret0,arg0 - bl get_mem_long_16,link - extru arg0,31,24,arg0 - - CYCLES_PLUS_2 - extru kpc,31,16,arg0 - ldil l%dispatch,link - dep ret0,31,16,kpc - b push_16_unsafe - ldo r%dispatch(link),link -#else GET_2BYTE_ARG; INC_KPC_2; tmp1 = kpc; @@ -2681,7 +1321,6 @@ instfc_SYM /* JSR (Abs,X) */ kpc = (kpc & 0xff0000) + tmp2; CYCLES_PLUS_2 PUSH16_UNSAFE(tmp1); -#endif instfd_SYM /* SBC Abs,X */ GET_ABS_X_RD(); From 5230276e78238fedd99981723ecd9fab2e5a413a Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Wed, 19 Aug 2020 22:21:36 -0500 Subject: [PATCH 6/7] more asm removal from hp --- src/engine_c.c | 5 +- src/engine_s.s | 2467 ------------------------------------------------ src/vars_hp | 20 - 3 files changed, 1 insertion(+), 2491 deletions(-) delete mode 100644 src/engine_s.s delete mode 100644 src/vars_hp diff --git a/src/engine_c.c b/src/engine_c.c index 9372be2..f4110c5 100644 --- a/src/engine_c.c +++ b/src/engine_c.c @@ -353,11 +353,8 @@ extern word32 slow_mem_changed[]; } void check_breakpoints(word32 addr) { - int count; int i; - - count = g_num_breakpoints; - for(i = 0; i < count; i++) { + for(i = 0; i < g_num_breakpoints; i++) { if((g_breakpts[i] & 0xffffff) == addr) { g_dbg_step = -2; halt2_printf("Hit breakpoint at %06x\n", addr); diff --git a/src/engine_s.s b/src/engine_s.s deleted file mode 100644 index 2799a4b..0000000 --- a/src/engine_s.s +++ /dev/null @@ -1,2467 +0,0 @@ -/* - GSPLUS - Advanced Apple IIGS Emulator Environment - Based on the KEGS emulator written by Kent Dickey - See COPYRIGHT.txt for Copyright information - See LICENSE.txt for license (GPL v2) -*/ - - .code - - .level 1.1 - -#include "defs.h" - -#define ASM - - -/* -#define COUNT_GET_CALLS -*/ - -#if 0 -# define CHECK_SIZE_CONSISTENCY -#endif - - -#define STACK_ENGINE_SIZE 512 - -#define STACK_SAVE_CMP_INDEX_REG -64 -#define STACK_GET_MEM_B0_DIRECT_SAVELINK -68 -#define STACK_SAVE_ARG0 -72 -#define STACK_SAVE_INSTR -76 -#define STACK_SRC_BANK -80 -#define STACK_INST_TAB_PTR_DONT_USE_THIS -84 -#if 0 -#define STACK_BP_ARG0_SAVE -88 -#define STACK_BP_ARG1_SAVE -92 -#define STACK_BP_ARG2_SAVE -96 -#define STACK_BP_ARG3_SAVE -100 -#define STACK_BP_RP_SAVE -104 -#define STACK_BP_SCRATCH4_SAVE -108 -#endif - -#define STACK_GET_MEMORY_SAVE_LINK -112 -#define STACK_SET_MEMORY_SAVE_LINK -116 - -#define STACK_MEMORY16_SAVE1 -120 -#define STACK_MEMORY16_SAVE2 -124 -#define STACK_MEMORY16_SAVE3 -128 - -#define STACK_SAVE_CYCLES_WORD2 -132 /* Cycles = dword */ -#define STACK_SAVE_CYCLES -136 - -#define STACK_SET_MEMORY24_SAVE1 -140 -#define STACK_SET_MEMORY24_SAVE2 -144 -#define STACK_SET_MEMORY24_SAVE3 -148 - -#define STACK_GET_MEMORY24_SAVE1 -152 -#define STACK_GET_MEMORY24_SAVE2 -156 -#define STACK_GET_MEMORY24_SAVE3 -160 - -/* #define STACK_SAVE_INIT_CYCLES -164 */ -#define STACK_SAVE_DECIMAL16_A -168 -#define STACK_SAVE_DECIMAL16_B -172 -#define STACK_SAVE_INSTR_TMP1 -176 - -#define STACK_SAVE_DISPATCH_LINK -180 -#define STACK_SAVE_OP_LINK -184 -#define STACK_GET_MEMORY16_ADDR_LATCH -188 -#define STACK_GET_MEMORY24_ADDR_LATCH -192 - -#define STACK_GET_MEM_B0_DIRECT_ARG0 -200 -#define STACK_GET_MEM_B0_DIRECT_RET0 -204 -#define STACK_SAVE_PUSH16_LINK -208 -#define STACK_SAVE_PUSH16_ARG1 -212 - -#define STACK_SAVE_PULL16_LINK -216 -#define STACK_SAVE_PULL16_RET0 -220 -#define STACK_SAVE_PULL24_LINK -224 -#define STACK_SAVE_PULL24_RET0 -228 - -#define STACK_SAVE_COP_ARG0 -232 -#define STACK_SAVE_TMP_INST0 -236 -#define STACK_SAVE_TMP_INST -240 -#define STACK_SAVE_TMP_INST1 -244 -#define STACK_SAVE_DISP_PIECES_LINK -248 -#define STACK_SAVE_DISPATCH_SCRATCH1 -252 - -#if 0 -#define STACK_BP_SCRATCH2_SAVE -256 -#define STACK_BP_SCRATCH3_SAVE -260 -#endif - - - -#define CYCLES_PLUS_1 fadd,dbl fr_plus_1,fcycles,fcycles -#define CYCLES_PLUS_2 fadd,dbl fr_plus_2,fcycles,fcycles -#define CYCLES_PLUS_3 fadd,dbl fr_plus_3,fcycles,fcycles -#define CYCLES_PLUS_5 fadd,dbl fr_plus_3,fcycles,fcycles ! \ - fadd,dbl fr_plus_2,fcycles,fcycles - -#define CYCLES_MINUS_1 fsub,dbl fcycles,fr_plus_1,fcycles -#define CYCLES_MINUS_2 fsub,dbl fcycles,fr_plus_2,fcycles - -#define CYCLES_FINISH fadd,dbl fcycles_stop,fr_plus_1,fcycles - -#define FCYCLES_ROUND_1 fadd,dbl fcycles,fr_plus_x_m1,ftmp1 -#define FCYCLES_ROUND_2 fcnvfxt,dbl,dbl ftmp1,ftmp1 -#define FCYCLES_ROUND_3 fcnvxf,dbl,dbl ftmp1,fcycles - -/* HACK: INC_KPC* and DEC_KPC2 should avoid overflow into kbank! */ -#define INC_KPC_1 addi 1,kpc,kpc -#define INC_KPC_2 addi 2,kpc,kpc -#define INC_KPC_3 addi 3,kpc,kpc -#define INC_KPC_4 addi 4,kpc,kpc -#define DEC_KPC2 addi -2,kpc,kpc - -#define get_mem_b0_8 get_memory_asm -#define get_mem_b0_16 get_memory16_asm -#define get_mem_b0_24 get_memory24_asm - -#define get_mem_long_8 get_memory_asm -#define get_mem_long_16 get_memory16_asm -#define get_mem_long_24 get_memory24_asm - -#define set_mem_long_8 set_memory_asm -#define set_mem_long_16 set_memory16_asm - -#define set_mem_b0_8 set_memory_asm -#define set_mem_b0_16 set_memory16_asm -#define set_mem_b0_24 set_memory24_asm - - .code - .import halt_sim,data - .import g_fcycles_stop,data - .import g_irq_pending,data - .import g_wait_pending,data - .import g_rom_version,data - .import g_num_brk,data - .import g_num_cop,data - .import g_testing,data - - .import log_pc,code - .import toolbox_debug_c,code - - .import get_memory_io,code - - .import set_memory_io,code - .import set_memory16_pieces,code - .import set_memory24_pieces,code - -#include "op_routs.h" - - .import do_break,code - .import do_cop,code - .import page_info_rd_wr,data - .import get_memory_calls,data - .import slow_mem_changed,data - .import g_cur_dcycs,data - .import g_last_vbl_dcycs,data - .import g_slow_memory_ptr,data - .import g_memory_ptr,data - .import g_dummy_memory1_ptr,data - .import g_rom_fc_ff_ptr,data - .import g_rom_cards_ptr,data - - .export fixed_memory_ptrs_init,code -fixed_memory_ptrs_init - LDC(slow_memory,arg0) - LDC(g_slow_memory_ptr,arg1) - stw arg0,(arg1) - - LDC(dummy_memory1,arg0) - LDC(g_dummy_memory1_ptr,arg1) - stw arg0,(arg1) - - LDC(rom_fc_ff,arg0) - LDC(g_rom_fc_ff_ptr,arg1) - stw arg0,(arg1) - - LDC(rom_cards,arg0) - LDC(g_rom_cards_ptr,arg1) - stw arg0,(arg1) - - bv 0(link) - nop - - .export get_itimer,code -get_itimer - bv 0(link) - mfctl %cr16,ret0 - - .export enter_asm,data -enter_asm - stwm page_info_ptr,STACK_ENGINE_SIZE(sp) - stw link,-STACK_ENGINE_SIZE+4(sp) - ldo -STACK_ENGINE_SIZE+16(sp),scratch2 - stw addr_latch,-STACK_ENGINE_SIZE+8(sp) - fstds,ma fcycles,8(scratch2) - fstds,ma fr_plus_1,8(scratch2) - fcpy,dbl 0,fcycles - fstds,ma fr_plus_2,8(scratch2) - fstds,ma fr_plus_3,8(scratch2) - fcpy,dbl 0,fr_plus_1 - fstds,ma fr_plus_x_m1,8(scratch2) - fstds,ma fcycles_stop,8(scratch2) - fcpy,dbl 0,fr_plus_2 - fstds,ma fcycles_last_dcycs,8(scratch2) - ldil l%g_cur_dcycs,scratch2 - - ldil l%g_last_vbl_dcycs,scratch3 - fcpy,dbl 0,fr_plus_3 - ldo r%g_cur_dcycs(scratch2),scratch2 - fcpy,dbl 0,fr_plus_x_m1 - ldo r%g_last_vbl_dcycs(scratch3),scratch3 - fldds 0(scratch2),ftmp1 - ldil l%page_info_rd_wr,page_info_ptr - fldds 0(scratch3),fcycles_last_dcycs - fcpy,dbl 0,fcycles_stop - ldo r%page_info_rd_wr(page_info_ptr),page_info_ptr - bv 0(scratch1) - fsub,dbl ftmp1,fcycles_last_dcycs,fcycles - - - .export leave_asm,data -leave_asm - ldw -STACK_ENGINE_SIZE+4(sp),link - ldo -STACK_ENGINE_SIZE+16(sp),scratch2 - ldw -STACK_ENGINE_SIZE+8(sp),addr_latch - fldds,ma 8(scratch2),fcycles - fldds,ma 8(scratch2),fr_plus_1 - fldds,ma 8(scratch2),fr_plus_2 - fldds,ma 8(scratch2),fr_plus_3 - fldds,ma 8(scratch2),fr_plus_x_m1 - fldds,ma 8(scratch2),fcycles_stop - fldds,ma 8(scratch2),fcycles_last_dcycs - - bv (link) - ldwm -STACK_ENGINE_SIZE(sp),page_info_ptr - - - .align 8 - .export get_memory_c -get_memory_c -; arg0 = addr -; arg1 = cycles - bl enter_asm,scratch1 - nop - bl get_memory_asm,link - nop - b leave_asm - nop - - .export get_memory16_c -get_memory16_c -; arg0 = addr -; arg1 = cycles - bl enter_asm,scratch1 - nop - bl get_memory16_asm,link - nop - b leave_asm - nop - - .export get_memory24_c -get_memory24_c -; arg0 = addr -; arg1 = cycles - bl enter_asm,scratch1 - nop - bl get_memory24_asm,link - nop - b leave_asm - nop - -#define GET_MEM8(upper16,lower8,ret0) \ - extru arg0,23,16,arg3 ! \ - CYCLES_PLUS_1 ! \ - ldwx,s arg3(page_info_ptr),scratch3 ! \ - copy arg0,addr_latch ! \ - copy scratch3,scratch2 ! \ - dep arg0,31,8,scratch3 ! \ - extru,= scratch2,BANK_IO_BIT,1,0 ! \ - bl,n get_memory_iocheck_stub_asm,link ! \ - ldb (scratch3),ret0 - - .align 32 - - .export get_memory_asm -get_memory_asm -; arg0 = addr - extru arg0,23,16,arg3 - copy arg0,addr_latch - - ldwx,s arg3(page_info_ptr),scratch2 - CYCLES_PLUS_1 - bb,<,n scratch2,BANK_IO_BIT,get_memory_iocheck_stub_asm - dep arg0,31,8,scratch2 - bv 0(link) - ldb (scratch2),ret0 - - - .align 8 - - .export get_memory16_asm -get_memory16_asm -; arg0 = addr - ldi 0xff,scratch3 - extru arg0,23,16,arg3 - - and scratch3,arg0,scratch4 - ldwx,s arg3(page_info_ptr),scratch2 - copy arg0,addr_latch - comb,= scratch4,scratch3,get_memory16_pieces_stub_asm - and scratch2,scratch3,scratch3 - comb,<> 0,scratch3,get_memory16_pieces_stub_asm - dep arg0,31,8,scratch2 - ldb (scratch2),ret0 - CYCLES_PLUS_2 - ldb 1(scratch2),scratch1 - bv 0(link) - dep scratch1,23,8,ret0 - - .align 8 - - .export get_memory24_asm -get_memory24_asm -; arg0 = addr - ldi 0xfe,scratch3 - extru arg0,23,16,arg3 - - and scratch3,arg0,scratch4 - ldwx,s arg3(page_info_ptr),scratch2 - copy arg0,addr_latch - comb,= scratch4,scratch3,get_memory24_pieces_stub_asm - extru scratch2,31,8,scratch3 - comb,<> 0,scratch3,get_memory24_pieces_stub_asm - dep arg0,31,8,scratch2 - ldb (scratch2),ret0 - ldb 1(scratch2),scratch1 - CYCLES_PLUS_3 - ldb 2(scratch2),scratch2 - dep scratch1,23,8,ret0 - bv 0(link) - dep scratch2,15,8,ret0 - - - .align 0x20 - .export get_memory_iocheck_stub_asm,code -get_memory_iocheck_stub_asm - extru,= scratch2,BANK_BREAK_BIT,1,0 - bl check_breakpoints_asm,scratch4 - stw link,STACK_GET_MEMORY_SAVE_LINK(sp) - bb,< scratch2,BANK_IO2_BIT,get_memory_io_stub_asm - dep arg0,31,8,scratch2 - bv 0(link) - ldb (scratch2),ret0 - - .export get_memory_io_stub_asm -get_memory_io_stub_asm - FCYCLES_ROUND_1 - ldo STACK_SAVE_CYCLES(sp),arg1 - FCYCLES_ROUND_2 - FCYCLES_ROUND_3 - bl get_memory_io,link - fstds fcycles,(arg1) - - ldw STACK_GET_MEMORY_SAVE_LINK(sp),link - ldo STACK_SAVE_CYCLES(sp),arg1 - bv (link) - fldds (arg1),fcycles - - - - .export get_memory16_pieces_stub_asm,code -get_memory16_pieces_stub_asm - stw addr_latch,STACK_GET_MEMORY16_ADDR_LATCH(sp) - addi 1,arg0,scratch1 - stw link,STACK_MEMORY16_SAVE2(sp) - bl get_memory_asm,link - stw scratch1,STACK_MEMORY16_SAVE1(sp) - - stw ret0,STACK_MEMORY16_SAVE3(sp) - bl get_memory_asm,link - ldw STACK_MEMORY16_SAVE1(sp),arg0 - - ldw STACK_MEMORY16_SAVE2(sp),link - copy ret0,scratch1 - ldw STACK_MEMORY16_SAVE3(sp),ret0 - ldw STACK_GET_MEMORY16_ADDR_LATCH(sp),addr_latch - bv (link) - dep scratch1,23,8,ret0 - - - .export get_memory24_pieces_stub_asm,code -get_memory24_pieces_stub_asm - stw addr_latch,STACK_GET_MEMORY16_ADDR_LATCH(sp) - addi 1,arg0,scratch1 - stw link,STACK_GET_MEMORY24_SAVE2(sp) - bl get_memory_asm,link - stw scratch1,STACK_GET_MEMORY24_SAVE1(sp) - - stw ret0,STACK_GET_MEMORY24_SAVE3(sp) - bl get_memory_asm,link - ldw STACK_GET_MEMORY24_SAVE1(sp),arg0 - - ldw STACK_GET_MEMORY24_SAVE1(sp),arg0 - stb ret0,STACK_GET_MEMORY24_SAVE3+2(sp) - bl get_memory_asm,link - addi 1,arg0,arg0 - - ldw STACK_GET_MEMORY24_SAVE2(sp),link - copy ret0,scratch1 - ldw STACK_GET_MEMORY24_SAVE3(sp),ret0 - ldw STACK_GET_MEMORY16_ADDR_LATCH(sp),addr_latch - bv (link) - dep scratch1,15,8,ret0 - - - - -; C callable routine to wrap around set_memory_asm - .export set_memory_c -set_memory_c -;arg0 = addr -;arg1 = val -;arg2 = cycles - bl enter_asm,scratch1 - nop - bl set_memory_asm,link - nop - b leave_asm - nop - - - .export set_memory16_c -set_memory16_c -;arg0 = addr -;arg1 = val -;arg2 = cycles - bl enter_asm,scratch1 - nop - bl set_memory16_asm,link - nop - b leave_asm - nop - - .export set_memory24_c -set_memory24_c -;arg0 = addr -;arg1 = val -;arg2 = cycles - bl enter_asm,scratch1 - nop - bl set_memory24_asm,link - nop - b leave_asm - nop - - - .align 32 - - .export set_memory_asm -set_memory_asm -; arg0 = addr -; arg1 = val - extru arg0,23,16,arg3 - addil l%PAGE_INFO_WR_OFFSET,arg3 - CYCLES_PLUS_1 - ldwx,s r1(page_info_ptr),scratch2 - ldi 0xff,scratch3 - and scratch2,scratch3,scratch3 - dep arg0,31,8,scratch2 - comib,<>,n 0,scratch3,set_memory_special_case -set_memory_cont_asm - bv 0(link) - stb arg1,(scratch2) - - - .export set_memory_special_case -set_memory_special_case - extru,= scratch3,BANK_BREAK_BIT,1,0 - bl check_breakpoints_asm,scratch4 - extru arg1,31,8,arg1 - -set_memory_special_case2 - bb,< scratch3,BANK_IO2_BIT,set_memory_io_stub_asm - ldil l%slow_memory,scratch4 - bb,< scratch3,BANK_SHADOW_BIT,set_memory_shadow1_asm - extru arg0,31,16,arg3 - bb,< scratch3,BANK_SHADOW2_BIT,set_memory_shadow2_asm - nop - bb,< scratch3,BANK_BREAK_BIT,set_memory_cont_asm - nop - break - - -set_memory_shadow1_asm -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_1 -#endif - add arg3,scratch4,scratch4 - extru arg3,31-SHIFT_PER_CHANGE,5,scratch1 - ldb r%slow_memory(scratch4),arg2 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_2 -#endif - mtctl scratch1,cr11 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_3 -#endif - comclr,<> arg2,arg1,0 - bv 0(link) - stb arg1,(scratch2) - zvdepi 1,1,arg2 - extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2 - ldil l%slow_mem_changed,scratch1 - sh2add scratch2,scratch1,scratch1 - ldw r%slow_mem_changed(scratch1),scratch3 - stb arg1,r%slow_memory(scratch4) - or arg2,scratch3,scratch3 - bv 0(link) - stw scratch3,r%slow_mem_changed(scratch1) - -set_memory_shadow2_asm - depi 1,15,1,arg3 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_1 -#endif - add arg3,scratch4,scratch4 - extru arg3,31-SHIFT_PER_CHANGE,5,scratch1 - ldb r%slow_memory(scratch4),arg2 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_2 -#endif - mtctl scratch1,cr11 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_3 -#endif - comclr,<> arg2,arg1,0 - bv 0(link) - stb arg1,(scratch2) - zvdepi 1,1,arg2 - extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2 - ldil l%slow_mem_changed,scratch1 - sh2add scratch2,scratch1,scratch1 - ldw r%slow_mem_changed(scratch1),scratch3 - stb arg1,r%slow_memory(scratch4) - or arg2,scratch3,scratch3 - bv 0(link) - stw scratch3,r%slow_mem_changed(scratch1) - - -set_memory_io_stub_asm - FCYCLES_ROUND_1 - ldo STACK_SAVE_CYCLES(sp),arg2 - FCYCLES_ROUND_2 - stw link,STACK_SET_MEMORY_SAVE_LINK(sp) - FCYCLES_ROUND_3 - bl set_memory_io,link - fstds fcycles,(arg2) - - ldw STACK_SET_MEMORY_SAVE_LINK(sp),link - ldo STACK_SAVE_CYCLES(sp),arg2 - bv (link) - fldds (arg2),fcycles - - .align 8 - .export set_memory16_asm -set_memory16_asm -; arg0 = addr -; arg1 = val - extru arg0,23,16,arg3 - - addil l%PAGE_INFO_WR_OFFSET,arg3 - extrs arg0,31,8,scratch4 - ldwx,s r1(page_info_ptr),scratch2 - ldi 0xff,scratch3 - and scratch3,scratch2,scratch3 - dep arg0,31,8,scratch2 - comib,=,n -1,scratch4,set_memory16_pieces_stub_asm - comib,<>,n 0,scratch3,set_memory16_special_case -set_memory16_cont_asm - stb arg1,0(scratch2) - CYCLES_PLUS_2 - extru arg1,23,8,arg3 - bv 0(link) - stb arg3,1(scratch2) - - - .align 8 -set_memory16_shadow1_asm - CYCLES_PLUS_2 - copy arg1,arg2 - extru arg1,23,8,arg1 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_1 -#endif - add arg3,scratch4,scratch4 - dep arg2,23,8,arg1 - extru arg3,31-SHIFT_PER_CHANGE,5,scratch1 - ldh r%slow_memory(scratch4),arg2 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_2 -#endif - mtctl scratch1,cr11 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_3 -#endif - comclr,<> arg2,arg1,0 ;return if arg2 == arg1 - bv 0(link) - sth arg1,(scratch2) - zvdepi 1,1,arg2 - extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2 - ldil l%slow_mem_changed,scratch1 - sh2add scratch2,scratch1,scratch1 - ldw r%slow_mem_changed(scratch1),scratch3 - sth arg1,r%slow_memory(scratch4) - or arg2,scratch3,scratch3 - bv 0(link) - stw scratch3,r%slow_mem_changed(scratch1) - - .align 8 -set_memory16_shadow2_asm - CYCLES_PLUS_2 - copy arg1,arg2 - extru arg1,23,8,arg1 - depi 1,15,1,arg3 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_1 -#endif - dep arg2,23,8,arg1 - add arg3,scratch4,scratch4 - extru arg3,31-SHIFT_PER_CHANGE,5,scratch1 - ldh r%slow_memory(scratch4),arg2 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_2 -#endif - mtctl scratch1,cr11 -#ifdef ACCURATE_SLOW_MEM - FCYCLES_ROUND_3 -#endif - comclr,<> arg2,arg1,0 - bv 0(link) - sth arg1,(scratch2) - zvdepi 1,1,arg2 - extru arg3,31-CHANGE_SHIFT,16-CHANGE_SHIFT,scratch2 - ldil l%slow_mem_changed,scratch1 - sh2add scratch2,scratch1,scratch1 - ldw r%slow_mem_changed(scratch1),scratch3 - sth arg1,r%slow_memory(scratch4) - or arg2,scratch3,scratch3 - bv 0(link) - stw scratch3,r%slow_mem_changed(scratch1) - - - .align 8 -set_memory16_special_case - extru,= scratch3,BANK_BREAK_BIT,1,0 - bl check_breakpoints_asm,scratch4 - extru arg1,31,16,arg1 - -set_memory16_special_case2 - bb,< scratch3,BANK_IO2_BIT,set_memory16_pieces_stub_asm - ldil l%slow_memory,scratch4 - -; if not halfword aligned, go through pieces_stub_asm - bb,<,n arg0,31,set_memory16_pieces_stub_asm - bb,< scratch3,BANK_SHADOW2_BIT,set_memory16_shadow2_asm - extru arg0,31,16,arg3 - bb,< scratch3,BANK_SHADOW_BIT,set_memory16_shadow1_asm - nop - bb,< scratch3,BANK_BREAK_BIT,set_memory16_cont_asm - nop - break - - .align 8 -set_memory16_pieces_stub_asm - addi 1,arg0,scratch1 - stw link,STACK_MEMORY16_SAVE3(sp) - extru arg1,23,8,scratch2 - stw scratch1,STACK_MEMORY16_SAVE1(sp) - bl set_memory_asm,link - stw scratch2,STACK_MEMORY16_SAVE2(sp) - - ldw STACK_MEMORY16_SAVE1(sp),arg0 - ldw STACK_MEMORY16_SAVE2(sp),arg1 - b set_memory_asm - ldw STACK_MEMORY16_SAVE3(sp),link - - - .align 8 - .export set_memory24_asm -set_memory24_asm -; arg0 = addr -; arg1 = val - extru arg0,23,16,arg3 - - addil l%PAGE_INFO_WR_OFFSET,arg3 - extrs arg0,30,7,scratch4 - ldwx,s r1(page_info_ptr),scratch2 - ldi 0xff,scratch3 - and scratch3,scratch2,scratch3 - dep arg0,31,8,scratch2 - comib,=,n -1,scratch4,set_memory24_pieces_stub_asm - comib,<>,n 0,scratch3,set_memory24_pieces_stub_asm - stb arg1,0(scratch2) - extru arg1,23,8,arg3 - CYCLES_PLUS_3 - stb arg3,1(scratch2) - extru arg1,15,8,arg3 - bv 0(link) - stb arg3,2(scratch2) - -set_memory24_pieces_stub_asm - addi 1,arg0,scratch1 - stw link,STACK_SET_MEMORY24_SAVE3(sp) - extru arg1,23,16,scratch2 - stw scratch1,STACK_SET_MEMORY24_SAVE1(sp) - bl set_memory_asm,link - stw scratch2,STACK_SET_MEMORY24_SAVE2(sp) - - ldw STACK_SET_MEMORY24_SAVE1(sp),arg0 - bl set_memory_asm,link - ldw STACK_SET_MEMORY24_SAVE2(sp),arg1 - - ldw STACK_SET_MEMORY24_SAVE1(sp),arg0 - ldw STACK_SET_MEMORY24_SAVE3(sp),link - addi 1,arg0,arg0 - b set_memory_asm - ldb STACK_SET_MEMORY24_SAVE2+2(sp),arg1 - - - - - - .import g_num_breakpoints,data - .import g_breakpts,data - - .align 8 - .export check_breakpoints_asm,code -check_breakpoints_asm -; can't use arg0-arg3. don't use scratch2,scratch3 -; scratch4: return link -; - ldil l%g_num_breakpoints,scratch1 - ldil l%g_breakpts,ret0 - ldw r%g_num_breakpoints(scratch1),r1 - ldo r%g_breakpts(ret0),ret0 - addi,>= -1,r1,r1 - bv,n 0(scratch4) - ldwx,s r1(ret0),scratch1 -check_breakpoints_loop_asm - comb,=,n scratch1,arg0,check_breakpoints_hit - addib,>=,n -1,r1,check_breakpoints_loop_asm - ldwx,s r1(ret0),scratch1 - - bv 0(scratch4) - nop - - .export check_breakpoints_hit,code -check_breakpoints_hit - LDC(halt_sim,scratch1) - ldw (scratch1),r1 - ldil l%g_fcycles_stop,ret0 - depi 1,31,1,r1 - stw 0,r%g_fcycles_stop(ret0) - stw 0,r%g_fcycles_stop+4(ret0) - bv 0(scratch4) - stw r1,(scratch1) - nop - nop - nop - - - - .align 8 - .export set_mem_yreg -set_mem_yreg -; arg0 = addr to write - extru,= psr,27,1,0 ;null branch if 16 bit - b set_memory_asm - copy yreg,arg1 -;if get here, 16 bit yreg - b,n set_memory16_asm - nop - - - .align 8 - .export set_mem_xreg -set_mem_xreg -; arg0 = addr to write - extru,= psr,27,1,0 ;null branch if 16 bit - b set_memory_asm - copy xreg,arg1 -;if get here, 16 bit xreg - b,n set_memory16_asm - nop - - - - .export get_memory_outofrange,code -get_memory_outofrange - break - - -get_mem_b0_16_stub - b get_mem_b0_16 - nop - - .align 8 -get_mem_b0_direct_page_16 -; get 2 bytes for direct-page fetch. -; arg0 = addr; -; if emul and dl = 0, then stick dh in -; into high bytes. -; if emul, grab + 1 byte from dh page also. -; if not emul, just call get_mem_b0 - ldi 0xff,scratch2 - extru,<> psr,23,1,0 ;null next if emul bit set - b get_mem_b0_16 - extru direct,23,8,scratch1 - and arg0,scratch2,scratch3 - extru,<> direct,31,8,0 ;null if direct not page aligned - dep scratch1,23,24,arg0 ;..done only if direct is page aligned - comb,<> scratch3,scratch2,get_mem_b0_16_stub - stw link,STACK_GET_MEM_B0_DIRECT_SAVELINK(sp) -; we're at 0x??ff, so next byte needs to come from 0x??00. - bl get_mem_b0_8,link - stw arg0,STACK_GET_MEM_B0_DIRECT_ARG0(sp) -; now, get next byte - ldw STACK_GET_MEM_B0_DIRECT_ARG0(sp),arg0 - extru direct,23,8,scratch1 - stw ret0,STACK_GET_MEM_B0_DIRECT_RET0(sp) - addi 1,arg0,arg0 - extru,<> direct,31,8,0 ;null if direct not page aligned - dep scratch1,23,24,arg0 ;..done only if direct is page aligned - bl get_mem_b0_8,link - nop - -; and return - copy ret0,scratch2 - ldw STACK_GET_MEM_B0_DIRECT_SAVELINK(sp),scratch1 - ldb STACK_GET_MEM_B0_DIRECT_RET0+3(sp),ret0 - bv (scratch1) - dep scratch2,23,8,ret0 - - - -push_8 - copy arg0,arg1 - copy stack,arg0 - addi -1,stack,stack - extru,= psr,23,1,0 ;emul mode? - depi 1,23,24,stack - b set_mem_b0_8 - extru stack,31,16,stack - -pull_8 - addi 1,stack,stack - extru,= psr,23,1,0 - depi 1,23,24,stack - extru stack,31,16,stack - b get_mem_b0_8 - copy stack,arg0 - -push_16 - copy arg0,arg1 - bb,>= psr,23,push_16_native - extru stack,30,7,scratch1 - -; push_16_emul - addi -2,stack,stack - comib,= 0,scratch1,push_16_emul_page - addi 1,stack,arg0 ;we know we are not at end of page - b set_mem_b0_16 - depi 1,23,24,stack - - -push_16_emul_page - stw link,STACK_SAVE_PUSH16_LINK(sp) - addi 1,arg0,arg0 - stw arg1,STACK_SAVE_PUSH16_ARG1(sp) - depi 1,23,24,arg0 - bl set_mem_b0_8,link - extru arg1,23,8,arg1 -; and do next push - addi 1,stack,arg0 - depi 1,23,24,stack - ldw STACK_SAVE_PUSH16_LINK(sp),link - ldb STACK_SAVE_PUSH16_ARG1+3(sp),arg1 - b set_mem_b0_8 - depi 1,23,24,arg0 - -push_16_native -; here, we're a native push_16 - addi -2,stack,stack - comib,= 0,scratch1,push_16_nat_page - addi 1,stack,arg0 ;we know we are not at end of page - b set_mem_b0_16 - extru stack,31,16,stack - - -push_16_nat_page - stw link,STACK_SAVE_PUSH16_LINK(sp) - addi 1,arg0,arg0 - stw arg1,STACK_SAVE_PUSH16_ARG1(sp) - extru arg0,31,16,arg0 - bl set_mem_b0_8,link - extru arg1,23,8,arg1 -; and do next push - addi 1,stack,arg0 - extru stack,31,16,stack - ldw STACK_SAVE_PUSH16_LINK(sp),link - ldb STACK_SAVE_PUSH16_ARG1+3(sp),arg1 - b set_mem_b0_8 - extru arg0,31,16,arg0 - -push_16_unsafe - copy arg0,arg1 - addi -1,stack,arg0 - addi -2,stack,stack - extru,= psr,23,1,0 - depi 1,23,24,stack - extru arg0,31,16,arg0 - b set_mem_b0_16 - extru stack,31,16,stack - -push_24_unsafe - copy arg0,arg1 - addi -2,stack,arg0 - addi -3,stack,stack - extru,= psr,23,1,0 - depi 1,23,24,stack - extru arg0,31,16,arg0 - b set_mem_b0_24 - extru stack,31,16,stack - -pull_16_unsafe - addi 1,stack,stack - extru,= psr,23,1,0 - depi 1,23,24,stack - extru stack,31,16,arg0 - addi 1,stack,stack - extru,= psr,23,1,0 - depi 1,23,24,stack - b get_mem_b0_16 - extru stack,31,16,stack - - .align 8 -pull_16 - extrs stack,29,6,scratch1 - bb,< psr,23,pull_16_emul - addi 1,stack,arg0 - comib,= -1,scratch1,pull_16_nat_page - addi 2,stack,stack -; if we get here, native & not near page cross - extru arg0,31,16,arg0 - b get_mem_b0_16 - extru stack,31,16,stack - -pull_16_emul - comib,= -1,scratch1,pull_16_emul_page - addi 2,stack,stack -; if get here, emul & not near page cross - b get_mem_b0_16 - depi 1,23,24,stack - -pull_16_nat_page - stw link,STACK_SAVE_PULL16_LINK(sp) - bl get_mem_b0_8,link - extru arg0,31,16,arg0 -; got first byte - stw ret0,STACK_SAVE_PULL16_RET0(sp) - extru stack,31,16,stack - bl get_mem_b0_8,link - copy stack,arg0 -; got second byte - ldw STACK_SAVE_PULL16_LINK(sp),link - copy ret0,scratch1 - ldb STACK_SAVE_PULL16_RET0+3(sp),ret0 - bv 0(link) - dep scratch1,23,8,ret0 - -pull_16_emul_page - stw link,STACK_SAVE_PULL16_LINK(sp) - bl get_mem_b0_8,link - depi 1,23,24,arg0 -; got first byte - stw ret0,STACK_SAVE_PULL16_RET0(sp) - depi 1,23,24,stack - bl get_mem_b0_8,link - copy stack,arg0 -; got second byte - ldw STACK_SAVE_PULL16_LINK(sp),link - copy ret0,scratch1 - ldb STACK_SAVE_PULL16_RET0+3(sp),ret0 - bv 0(link) - dep scratch1,23,8,ret0 - - .export pull_24,code -pull_24 - extrs stack,29,6,scratch1 - bb,< psr,23,pull_24_emul - addi 1,stack,arg0 - comib,= -1,scratch1,pull_24_nat_page - addi 3,stack,stack -; if we get here, native & not near page cross, go for it - extru arg0,31,16,arg0 - b get_mem_b0_24 - extru stack,31,16,stack - -pull_24_emul - depi 1,23,24,arg0 - comib,= -1,scratch1,pull_24_emul_page - addi 3,stack,stack -; if we get here, emul & not near page cross - b get_mem_b0_24 - depi 1,23,24,stack - -pull_24_nat_page - stw link,STACK_SAVE_PULL24_LINK(sp) - bl get_mem_b0_8,link - extru arg0,31,16,arg0 -; got first byte - stw ret0,STACK_SAVE_PULL24_RET0(sp) - addi -1,stack,arg0 - extru stack,31,16,stack - bl get_mem_b0_8,link - extru arg0,31,16,arg0 -; got second byte - stb ret0,STACK_SAVE_PULL24_RET0+2(sp) - bl get_mem_b0_8,link - copy stack,arg0 -; got all bytes - ldw STACK_SAVE_PULL24_LINK(sp),link - copy ret0,scratch1 - ldw STACK_SAVE_PULL24_RET0(sp),ret0 - bv (link) - dep scratch1,15,8,ret0 - -pull_24_emul_page - stw link,STACK_SAVE_PULL24_LINK(sp) - bl get_mem_b0_8,link - nop -; got first byte - addi -1,stack,arg0 - stw ret0,STACK_SAVE_PULL24_RET0(sp) - depi 1,23,24,stack - bl get_mem_b0_8,link - depi 1,23,24,arg0 -; got second byte - stb ret0,STACK_SAVE_PULL24_RET0+2(sp) - bl get_mem_b0_8,link - copy stack,arg0 -; got all bytes - ldw STACK_SAVE_PULL24_LINK(sp),link - copy ret0,scratch1 - ldw STACK_SAVE_PULL24_RET0(sp),ret0 - bv (link) - dep scratch1,15,8,ret0 - -update_system_state_and_change_kbank -; kbank already changed..do nothing - -update_system_state -; psr is new psw state -; arg0 is old in bits 31 and 30 - ldi 0x30,scratch1 - extru,= psr,23,1,0 - depi 3,27,2,psr - and psr,scratch1,scratch1 - extru,= psr,23,1,0 - depi 1,23,24,stack - dep arg0,29,2,scratch1 - blr scratch1,0 - addit,>= -0x3d,scratch1,0 -; 0000: no change - b update_sys9 - nop ! nop ! nop - nop ! nop ! nop ! nop -; 0001: x from 1->0 - b update_sys9 - ldi 2,scratch1 - nop ! nop - nop ! nop ! nop ! nop -; 0010: m from 1->0 - b resize_acc_to16 - ldi 0,ret0 - nop ! nop - nop ! nop ! nop ! nop -; 0011: m,x from 1->0 - b resize_acc_to16 - ldi 0,ret0 - nop ! nop - nop ! nop ! nop ! nop -; 0100: x from 0->1 - depi 0,23,24,yreg - b update_sys9 - depi 0,23,24,xreg - nop - nop ! nop ! nop ! nop -; 0101: no change - b update_sys9 - nop ! nop ! nop - nop ! nop ! nop ! nop -; 0110: x from 0->1, m from 1->0 - depi 0,23,24,yreg - ldi 0,ret0 - b resize_acc_to16 - depi 0,23,24,xreg - nop ! nop ! nop ! nop -; 0111: m from 1->0 - b resize_acc_to16 - ldi 0,ret0 - nop ! nop - nop ! nop ! nop ! nop -; 1000: m from 0->1 - b resize_acc_to8 - ldi 0,ret0 - nop ! nop - nop ! nop ! nop ! nop -; 1001: m from 0->1, x from 1->0 - b resize_acc_to8 - ldi 0,ret0 - nop ! nop - nop ! nop ! nop ! nop -; 1010: no change - b update_sys9 - nop ! nop ! nop - nop ! nop ! nop ! nop -; 1011: x from 1->0 - b update_sys9 - nop ! nop ! nop - nop ! nop ! nop ! nop -; 1100: m,x from 0->1 - depi 0,23,24,yreg - ldi 0,ret0 - b resize_acc_to8 - depi 0,23,24,xreg - nop ! nop ! nop ! nop -; 1101: m from 0->1 - b resize_acc_to8 - ldi 0,ret0 - nop ! nop - nop ! nop ! nop ! nop -; 1110: x from 0->1 - depi 0,23,24,yreg - ldi 0,ret0 - b update_sys9 - depi 0,23,24,xreg - nop ! nop ! nop ! nop -; 1111: no change - b update_sys9 - nop ! nop ! nop - nop ! nop ! nop ! nop -; 10000 - break - - - .export get_yreg_from_mem,code -get_yreg_from_mem -; arg0 = addr to read from, write into yreg - bb,>=,n psr,27,get_yreg_from_mem16 - bl get_mem_b0_8,link - extru arg0,31,24,arg0 - - extru ret0,31,8,zero - extru ret0,24,1,neg - b dispatch - copy zero,yreg - - .export get_yreg_from_mem16,code -get_yreg_from_mem16 - bl get_mem_b0_16,link - extru arg0,31,24,arg0 - - extru ret0,31,16,zero - extru ret0,16,1,neg - b dispatch - copy zero,yreg - - - .export get_xreg_from_mem,code -get_xreg_from_mem -; arg0 = addr to read from, write into xreg - bb,>=,n psr,27,get_xreg_from_mem16 - bl get_mem_b0_8,link - extru arg0,31,24,arg0 - - extru ret0,31,8,zero - extru ret0,24,1,neg - b dispatch - copy zero,xreg - - .export get_xreg_from_mem16,code -get_xreg_from_mem16 - bl get_mem_b0_16,link - extru arg0,31,24,arg0 - - extru ret0,31,16,zero - extru ret0,16,1,neg - b dispatch - copy zero,xreg - - - - - .export enter_engine,code -enter_engine -; load up regs with struct vals - .proc - .callinfo frame=STACK_ENGINE_SIZE,caller,save_rp,entry_gr=18,entry_fr=19 - .enter - - ldw ENGINE_FPLUS_PTR(arg0),scratch1 ;fplus ptr - fldds ENGINE_FCYCLES(arg0),fcycles - - ldil l%g_fcycles_stop,fcycles_stop_ptr - ldw ENGINE_REG_ACC(arg0),acc - ldo r%g_fcycles_stop(fcycles_stop_ptr),fcycles_stop_ptr - fldds FPLUS_PLUS_1(scratch1),fr_plus_1 - ldo FPLUS_PLUS_3(scratch1),ret0 - fldds FPLUS_PLUS_2(scratch1),fr_plus_2 - ldil l%g_last_vbl_dcycs,ret1 - fldds FPLUS_PLUS_3-FPLUS_PLUS_3(ret0),fr_plus_3 - ldo r%g_last_vbl_dcycs(ret1),ret1 - fldds FPLUS_PLUS_X_M1-FPLUS_PLUS_3(ret0),fr_plus_x_m1 - fldds 0(ret1),fcycles_last_dcycs - ldil l%table8,ret0 - ldw ENGINE_REG_XREG(arg0),xreg - ldil l%table16,inst_tab_ptr - ldw ENGINE_REG_YREG(arg0),yreg - ldo r%table8(ret0),ret0 - ldw ENGINE_REG_STACK(arg0),stack - ldo r%table16(inst_tab_ptr),inst_tab_ptr - ldw ENGINE_REG_PSR(arg0),psr - ldi 0,zero - ldw ENGINE_REG_DBANK(arg0),dbank - ldil l%page_info_rd_wr,page_info_ptr - ldw ENGINE_REG_DIRECT(arg0),direct - extru,= psr,26,1,0 ;nullify if acc size = 0 == 16bit - copy ret0,inst_tab_ptr - ldw ENGINE_REG_KPC(arg0),kpc - - ldo r%page_info_rd_wr(page_info_ptr),page_info_ptr - extru,<> psr,30,1,0 - ldi 1,zero - extru psr,24,1,neg - stw arg0,STACK_SAVE_ARG0(sp) - ldi 0xfd,const_fd - b dispatch - ldi 0,scratch1 - - .export resize_acc_to8,code -resize_acc_to8 - ldil l%table8,inst_tab_ptr - extru psr,27,1,scratch1 ;size of x - b update_sys9 - ldo r%table8(inst_tab_ptr),inst_tab_ptr - - .export resize_acc_to16,code -resize_acc_to16 - ldil l%table16,inst_tab_ptr - extru psr,27,1,scratch1 - b update_sys9 - ldo r%table16(inst_tab_ptr),inst_tab_ptr - - - -dispatch_done_cycles_mismatch - ldi -1,ret0 - b dispatch_done - nop - - - - .export dispatch_done -dispatch_done - bl refresh_engine_struct,link - ldw STACK_SAVE_ARG0(sp),arg0 - .leave - .procend - -refresh_engine_struct -; warning--this routine must not change arg1, arg2, arg3, or ret0 -; can only change scratch1 - - comiclr,<> 0,zero,scratch1 - ldi 1,scratch1 - dep neg,24,1,psr - dep scratch1,30,1,psr - stw acc,ENGINE_REG_ACC(arg0) - stw xreg,ENGINE_REG_XREG(arg0) - stw yreg,ENGINE_REG_YREG(arg0) - stw stack,ENGINE_REG_STACK(arg0) - stw dbank,ENGINE_REG_DBANK(arg0) - stw direct,ENGINE_REG_DIRECT(arg0) - stw psr,ENGINE_REG_PSR(arg0) - stw kpc,ENGINE_REG_KPC(arg0) - bv 0(link) - fstds fcycles,ENGINE_FCYCLES(arg0) - - .export check_irqs_pending,code -update_sys9 -check_irqs_pending -; if any g_irq_pending, return RET_IRQ - ldil l%g_irq_pending,scratch1 - ldw r%g_irq_pending(scratch1),scratch2 - bb,<,n psr,29,dispatch - comib,= 0,scratch2,dispatch - zdepi RET_IRQ,3,4,ret0 - b,n dispatch_done - nop - - .export clr_halt_act - .export set_halt_act -clr_halt_act - LDC(halt_sim,scratch1) - bv 0(link) - stw 0,(scratch1) - -set_halt_act - LDC(halt_sim,scratch1) - ldw (scratch1),scratch2 - ldil l%g_fcycles_stop,scratch3 - stw 0,r%g_fcycles_stop(scratch3) - or scratch2,arg0,arg0 - stw 0,r%g_fcycles_stop+4(scratch3) - bv 0(link) - stw arg0,(scratch1) - - - .align 32 - .export dispatch_fast,code -dispatch_fast -; instr is the instr to fetch -#ifdef LOG_PC - b dispatch - nop -#endif - fldds 0(fcycles_stop_ptr),fcycles_stop - extru kpc,23,16,arg2 - - extru kpc,31,8,scratch4 - ldwx,s arg2(page_info_ptr),scratch2 - - ldwx,s instr(inst_tab_ptr),link - fcmp,>,dbl fcycles,fcycles_stop ;C=1 if must stop - - addl scratch4,scratch2,scratch1 - comclr,>= scratch4,const_fd,0 ;stop for pieces if near end of page - - ldi -1,scratch2 - bb,<,n scratch2,BANK_IO_BIT,dispatch_instr_io - - ftest ;null next if can cont - - bv 0(link) - CYCLES_PLUS_2 - - b dispatch_instr_io - CYCLES_MINUS_2 - - - .align 32 - .export dispatch,code -dispatch - -#ifdef CHECK_SIZE_CONSISTENCY - nop - bl check_size_consist,link - nop -#endif - -#ifdef DEBUG_TOOLBOX - ldil l%g_rom_version,scratch1 - ldw r%g_rom_version(scratch1),scratch1 - ldi 0x00db,scratch1 ;ROM 01 - comiclr,> 3,scratch1,0 - ldi 0x00e5,scratch1 ;ROM 03 - depi -2,15,8,scratch1 ;set bank to 0xfe - comb,<>,n scratch1,kpc,no_debug_toolbox - copy xreg,arg0 - copy stack,arg1 - bl toolbox_debug_c,link - copy cycles,arg2 - - extru kpc,23,16,scratch2 -no_debug_toolbox -#endif - fldds 0(fcycles_stop_ptr),fcycles_stop - extru kpc,23,16,arg2 - - ldi 0xfd,scratch3 - ldwx,s arg2(page_info_ptr),scratch2 - - fcmp,<=,dbl fcycles,fcycles_stop ;C=1 if can cont - extru kpc,31,8,scratch4 - - ldbx scratch4(scratch2),instr - comclr,>= scratch4,scratch3,0 ;stop for pieces if near end of page - - ftest ;null next if can cont - - ldi -1,scratch2 - ldwx,s instr(inst_tab_ptr),link - - addl scratch4,scratch2,scratch1 - bb,<,n scratch2,BANK_IO_BIT,dispatch_instr_io - - ; depi 0,31,3,link - -#ifndef LOG_PC - bv 0(link) - CYCLES_PLUS_2 -#else - CYCLES_PLUS_2 - - .import log_pc_ptr,data - .import log_pc_start_ptr,data - .import log_pc_end_ptr,data - .export log_pc_asm -log_pc_asm -; save regs into log_pc_ptr, wrap around to log_pc_start_ptr if -; log_pc_ptr gets > log_pc_end_ptr - ldb 1(scratch1),scratch3 - dep neg,24,1,psr ;set neg - ldb 2(scratch1),scratch2 - ldil l%log_pc_ptr,scratch4 - ldb 3(scratch1),ret0 - fsub,dbl fcycles_last_dcycs,fr_plus_2,ftmp1 - dep scratch2,23,8,scratch3 - ldo r%log_pc_ptr(scratch4),scratch4 - dep instr,7,8,scratch3 - ldw 0(scratch4),scratch2 - dep ret0,15,8,scratch3 - copy kpc,ret1 - depi 0,30,1,psr ;zero - comiclr,<> 0,zero,0 - depi 1,30,1,psr ;set zero - stw scratch3,LOG_PC_INSTR(scratch2) - dep dbank,7,8,ret1 - copy acc,scratch3 - dep psr,15,16,scratch3 - fadd,dbl fcycles,ftmp1,ftmp1 - stw ret1,LOG_PC_DBANK_KPC(scratch2) - copy yreg,ret1 - stw scratch3,LOG_PC_PSR_ACC(scratch2) - dep xreg,15,16,ret1 - copy direct,scratch3 - fstds ftmp1,LOG_PC_DCYCS(scratch2) - ldw rs%log_pc_end_ptr-log_pc_ptr(scratch4),ret0 - dep stack,15,16,scratch3 - stw ret1,LOG_PC_XREG_YREG(scratch2) - addi LOG_PC_SIZE,scratch2,r31 - stw scratch3,LOG_PC_STACK_DIRECT(scratch2) - -; comb,>= r31,ret0,log_pc_oflow -; nop - - comclr,< r31,ret0,0 -; reload log_pc with log_pc_start_ptr - ldw rs%log_pc_start_ptr-log_pc_ptr(scratch4),r31 - - bv 0(link) - stw r31,0(scratch4) - -log_pc_oflow - ldil l%g_fcycles_stop,scratch3 - ldil l%halt_sim,ret0 - stw 0,r%g_fcycles_stop(scratch3) - ldi 2,arg0 - stw 0,r%g_fcycles_stop+4(scratch3) - stw arg0,r%halt_sim(ret0) - - ldw rs%log_pc_start_ptr-log_pc_ptr(scratch4),r31 - bv 0(link) - stw r31,0(scratch4) -#endif - - - .export dispatch_instr_io,code -dispatch_instr_io -; check if we're here because of timeout or halt required - fcmp,<=,dbl fcycles,fcycles_stop ;C=1 if we can cont - ldwx,s arg2(page_info_ptr),scratch2 - - ftest ;do next instr if must stop - b,n dispatch_done_clr_ret0 - - bb,>=,n scratch2,BANK_IO_BIT,dispatch_instr_pieces - - ldil l%0xc700,scratch1 - ldo r%0xc700(scratch1),scratch1 - addi 0x0a,scratch1,scratch2 - comb,= scratch1,kpc,dispatch_done - zdepi RET_C700,3,4,ret0 - - addi 0xd,scratch1,scratch3 - comb,= scratch2,kpc,dispatch_done - zdepi RET_C70A,3,4,ret0 - - comb,= scratch3,kpc,dispatch_done - zdepi RET_C70D,3,4,ret0 - - .export dispatch_instr_pieces,code -dispatch_instr_pieces -; fetch pc, get size from inst_info_ptr - bl get_mem_long_8,link - copy kpc,arg0 -; ret is instr - ldwx,s ret0(inst_tab_ptr),link - ldil l%sizes_tab,scratch4 - copy ret0,instr - ldo r%sizes_tab(scratch4),scratch4 - addi 1,kpc,arg0 - ldbx instr(scratch4),scratch2 -#ifdef LOG_PC -; save "real" link so call_log_pc can restore it - - stw link,STACK_SAVE_DISPATCH_LINK(sp) - LDC(call_log_pc,link) - stw instr,STACK_SAVE_INSTR(sp) -#endif - stw link,STACK_SAVE_DISP_PIECES_LINK(sp) - - ldi 0x1bea,ret0 - sh3add scratch2,0,scratch2 - ldo STACK_SAVE_TMP_INST(sp),scratch1 - blr scratch2,0 - addit,>= -48,scratch2,0 - -/* must correct cycle count so all instrs are called with cycls += 2 */ -/* since get_mem will auto-inc cycles by the number of bytes, we */ -/* need to "patch" things here, by adding 1 for 1byte, and subbing */ -/* from 3 and 4 byte instrs */ -; 0 - bv 0(link) - CYCLES_PLUS_1 - nop - nop - nop ! nop ! nop ! nop - nop ! nop ! nop ! nop - nop ! nop ! nop ! nop -; 1 - bl get_mem_long_8,link - nop - ldw STACK_SAVE_DISP_PIECES_LINK(sp),link - dep ret0,15,8,ret0 - ldo STACK_SAVE_TMP_INST(sp),scratch1 - bv 0(link) - stw ret0,0(scratch1) - nop ! nop - nop ! nop ! nop ! nop - nop ! nop ! nop ! nop -; 2 - bl get_mem_long_16,link - CYCLES_MINUS_1 - ldo STACK_SAVE_TMP_INST(sp),scratch1 - ldw STACK_SAVE_DISP_PIECES_LINK(sp),link - dep ret0,15,8,ret0 - bv 0(link) - stw ret0,0(scratch1) - nop - nop ! nop ! nop ! nop - nop ! nop ! nop ! nop -; 3 - bl get_mem_long_24,link - CYCLES_MINUS_2 - shd ret0,ret0,16,scratch2 - ldw STACK_SAVE_DISP_PIECES_LINK(sp),link - extru ret0,23,8,ret0 - ldo STACK_SAVE_TMP_INST(sp),scratch1 - dep ret0,23,8,scratch2 - bv 0(link) - stw scratch2,0(scratch1) - nop ! nop ! nop - nop ! nop ! nop ! nop -; 4 variable acc size - extru,<> psr,26,1,0 - bl,n get_mem_long_16,link - bl,n get_mem_long_8,link - CYCLES_MINUS_1 - ldw STACK_SAVE_DISP_PIECES_LINK(sp),link - ldo STACK_SAVE_TMP_INST(sp),scratch1 - dep ret0,15,8,ret0 - bv 0(link) - stw ret0,0(scratch1) - nop ! nop ! nop - nop ! nop ! nop ! nop -; 5 variable x size - extru,<> psr,27,1,0 - bl,n get_mem_long_16,link - bl,n get_mem_long_8,link - CYCLES_MINUS_1 - ldw STACK_SAVE_DISP_PIECES_LINK(sp),link - ldo STACK_SAVE_TMP_INST(sp),scratch1 - dep ret0,15,8,ret0 - bv 0(link) - stw ret0,0(scratch1) - nop ! nop ! nop - nop ! nop ! nop ! nop -; 6 = evil - break - - -#ifdef LOG_PC - .export call_log_pc,code -call_log_pc -; ret0 = operands -; must get instr = instruction -; and link = correct dispatch loc - ldw STACK_SAVE_INSTR(sp),instr - b log_pc_asm - ldw STACK_SAVE_DISPATCH_LINK(sp),link -#endif - -dispatch_done_clr_ret0 - nop ;just in case of bad nullification - b dispatch_done - ldi 0,ret0 - - -#ifdef CHECK_SIZE_CONSISTENCY - .import size_fail,code - - .export check_size_consist -check_size_consist - ldil l%table16,scratch1 - ldil l%table8,scratch2 - ldo r%table16(scratch1),scratch1 - bb,< psr,26,check_tab_8_bit - ldo r%table8(scratch2),scratch2 -; else 16 - comb,= scratch1,inst_tab_ptr,acc_size_ok - nop - - .export acc_tab_fail1 -acc_tab_fail1 - copy inst_tab_ptr,arg1 - copy scratch1,arg2 - bl size_fail,link - ldi 0x100,arg0 - b,n dispatch_done_clr_ret0 -; 8 - .export check_tab_8_bit -check_tab_8_bit - comb,= scratch2,inst_tab_ptr,acc_size_ok - nop - - .export acc_tab_fail0 -acc_tab_fail0 - copy inst_tab_ptr,arg1 - copy scratch2,arg2 - bl size_fail,link - ldi 0x101,arg0 - b dispatch_done - ldi 0,ret0 - - .export acc_size_ok -acc_size_ok - bv 0(link) - nop -#endif - - .align 8 -adc_binary_8_entry2 - extru psr,31,1,scratch3 - add ret0,scratch3,ret0 - - dep ret0,31,8,acc - extru ret0,31,8,zero - -/* and calc overflow */ - xor arg0,ret0,arg2 /* cmp binary add res w/ src1 */ - xor arg0,scratch2,scratch3 /* cmp signs of two inputs */ - extru ret0,24,1,neg - andcm arg2,scratch3,scratch3 /* and that with ~res. */ - extru ret0,23,1,scratch4 - extru scratch3,24,1,scratch3 - dep scratch4,31,1,psr /* set carry */ - b dispatch - dep scratch3,25,1,psr /* set overflow */ - - .align 8 - .export adc_binary_8 -adc_binary_8 - extru ret0,31,8,scratch2 - bb,>= psr,28,adc_binary_8_entry2 - add arg0,scratch2,ret0 - - - ldil l%dispatch,link - b adc_decimal_8 - ldo r%dispatch(link),link - - .export adc_decimal_8 -/* adds arg0 to scratch2 */ -/* acc8 (in arg0) and ret0 have already been added into ret0. Ignore that */ -adc_decimal_8 - ldi 0xf,scratch1 - extru psr,31,1,ret0 - - and arg0,scratch1,scratch3 - and scratch2,scratch1,scratch4 - - add scratch3,scratch4,ret1 - ldi 0xf0,arg3 - - add ret0,ret1,ret0 - - and arg0,arg3,scratch3 - addi -0xa,ret0,ret1 - - and scratch2,arg3,scratch4 - depi 1,27,4,ret1 - comiclr,> 0xa,ret0,0 - copy ret1,ret0 - - add scratch3,scratch4,ret1 - add ret0,ret1,ret0 - - extru ret0,24,1,ret1 - extru ret0,23,1,arg1 - xor ret1,arg1,ret1 - dep ret1,25,1,psr /* ov=((sum>>2) ^ (sum>>1) & 0x40 */ - - comiclr,> 0xa0,ret0,0 - addi 0x60,ret0,ret0 - - xor arg0,scratch2,scratch4 - extru ret0,31,8,zero - - extru,= scratch4,24,1,0 - depi 0,25,1,psr /* no overflow! */ - - - depi 0,31,1,psr - comiclr,> 0x100,ret0,0 - addi 1,psr,psr - - extru ret0,24,1,neg - bv 0(link) - dep zero,31,8,acc - - - - .align 8 - .export sbc_binary_8,code -sbc_binary_8 - extru ret0,31,8,scratch2 - bb,>= psr,28,adc_binary_8_entry2 - add arg0,scratch2,ret0 - - ldil l%dispatch,link - b sbc_decimal_8 - ldo r%dispatch(link),link - - -/* else decimal */ - .export sbc_decimal_8,code -sbc_decimal_8 -/* do arg0 - scratch2 = acc */ - ldi 0xf,scratch1 - extru psr,31,1,ret0 - - and scratch2,scratch1,scratch3 - and arg0,scratch1,scratch4 - - add scratch3,ret0,ret0 - - add ret0,scratch4,ret0 - ldi 0xf0,arg3 - - addi -0x6,ret0,ret1 - and scratch2,arg3,scratch3 - - and ret1,scratch1,ret1 /* sum2 = (sum - 0x6) & 0xf */ - and arg0,arg3,scratch4 - comiclr,<= 0x10,ret0,0 - copy ret1,ret0 /* sum = sum2 */ - - add scratch3,scratch4,ret1 - ldi 0xff,arg2 - add ret0,ret1,ret0 - - extru ret0,24,1,ret1 - addi 0xa0,ret0,scratch3 - extru ret0,23,1,arg3 - and scratch3,arg2,scratch3 /* (sum = sum + 0xa0) & 0xff */ - xor ret1,arg3,ret1 - - dep ret1,25,1,psr /* overflow = ((sum >> 2) ^ */ - /* (sum >> 1)) & 0x40 */ - - depi 0,31,1,psr - comiclr,<= 0x100,ret0,arg3 - or,TR scratch3,0,ret0 - addi 1,psr,psr - - and ret0,arg2,zero - extru ret0,24,1,neg - - xor arg0,scratch2,ret1 - - extru,= ret1,24,1,0 - depi 0,25,1,psr /* clear overflow */ - - bv 0(link) - dep ret0,31,8,acc - - - - .align 8 - .export adc_binary_16 -adc_binary_16 - extru ret0,31,16,scratch2 - bb,< psr,28,adc_decimal_16 - add arg0,scratch2,ret0 - -adc_binary_16_entry2 - extru psr,31,1,scratch1 - add ret0,scratch1,ret0 - - dep ret0,31,16,acc - extru ret0,31,16,zero - -/* and calc overflow */ - xor arg0,ret0,arg2 /* cmp binary add res w/ src1 */ - xor arg0,scratch2,scratch3 - extru ret0,16,1,neg - andcm arg2,scratch3,scratch3 /* and that with ~res. */ - extru ret0,15,1,scratch4 - extru scratch3,16,1,scratch3 - dep scratch4,31,1,psr /* set carry */ - b dispatch - dep scratch3,25,1,psr /* set overflow */ - - - .export adc_decimal_16 -adc_decimal_16 -/* must save arg0, scratch2 */ - stw arg0,STACK_SAVE_DECIMAL16_A(sp) - extru arg0,31,8,arg0 - stw scratch2,STACK_SAVE_DECIMAL16_B(sp) - bl adc_decimal_8,link - extru scratch2,31,8,scratch2 - - ldb STACK_SAVE_DECIMAL16_A+2(sp),arg0 - ldb STACK_SAVE_DECIMAL16_B+2(sp),scratch2 - bl adc_decimal_8,link - stw acc,STACK_SAVE_DECIMAL16_A(sp) - - ldw STACK_SAVE_DECIMAL16_A(sp),scratch1 - zdep acc,23,8,acc - dep scratch1,31,8,acc - b dispatch - copy acc,zero - - - .align 8 - .export sbc_binary_16,code -sbc_binary_16 - extru ret0,31,16,scratch2 - bb,>= psr,28,adc_binary_16_entry2 - add arg0,scratch2,ret0 - -/* else decimal */ - .export sbc_decimal_16,code -sbc_decimal_16 - stw arg0,STACK_SAVE_DECIMAL16_A(sp) - extru arg0,31,8,arg0 - stw scratch2,STACK_SAVE_DECIMAL16_B(sp) - bl sbc_decimal_8,link - extru scratch2,31,8,scratch2 - - ldb STACK_SAVE_DECIMAL16_A+2(sp),arg0 - ldb STACK_SAVE_DECIMAL16_B+2(sp),scratch2 - bl sbc_decimal_8,link - stw acc,STACK_SAVE_DECIMAL16_A(sp) - - ldw STACK_SAVE_DECIMAL16_A(sp),scratch1 - zdep acc,23,8,acc - dep scratch1,31,8,acc - b dispatch - copy acc,zero - - - - -#define ACC8 - .code -#include "defs_instr.h" -#include "8inst_s.h" - .code -#undef SYM -#undef ACC8 - - .code -#include "defs_instr.h" -#include "16inst_s.h" - .code -#undef SYM - - .export inst00_8 - .export inst01_8 - .export inst02_8 - .export inst03_8 - .export inst04_8 - .export inst05_8 - .export inst06_8 - .export inst07_8 - .export inst08_8 - .export inst09_8 - .export inst0a_8 - .export inst0b_8 - .export inst0c_8 - .export inst0d_8 - .export inst0e_8 - .export inst0f_8 - - .export inst10_8 - .export inst11_8 - .export inst12_8 - .export inst13_8 - .export inst14_8 - .export inst15_8 - .export inst16_8 - .export inst17_8 - .export inst18_8 - .export inst19_8 - .export inst1a_8 - .export inst1b_8 - .export inst1c_8 - .export inst1d_8 - .export inst1e_8 - .export inst1f_8 - - .export inst20_8 - .export inst21_8 - .export inst22_8 - .export inst23_8 - .export inst24_8 - .export inst25_8 - .export inst26_8 - .export inst27_8 - .export inst28_8 - .export inst29_8 - .export inst2a_8 - .export inst2b_8 - .export inst2c_8 - .export inst2d_8 - .export inst2e_8 - .export inst2f_8 - - .export inst30_8 - .export inst31_8 - .export inst32_8 - .export inst33_8 - .export inst34_8 - .export inst35_8 - .export inst36_8 - .export inst37_8 - .export inst38_8 - .export inst39_8 - .export inst3a_8 - .export inst3b_8 - .export inst3c_8 - .export inst3d_8 - .export inst3e_8 - .export inst3f_8 - - .export inst40_8 - .export inst41_8 - .export inst42_8 - .export inst43_8 - .export inst44_8 - .export inst45_8 - .export inst46_8 - .export inst47_8 - .export inst48_8 - .export inst49_8 - .export inst4a_8 - .export inst4b_8 - .export inst4c_8 - .export inst4d_8 - .export inst4e_8 - .export inst4f_8 - - .export inst50_8 - .export inst51_8 - .export inst52_8 - .export inst53_8 - .export inst54_8 - .export inst55_8 - .export inst56_8 - .export inst57_8 - .export inst58_8 - .export inst59_8 - .export inst5a_8 - .export inst5b_8 - .export inst5c_8 - .export inst5d_8 - .export inst5e_8 - .export inst5f_8 - - .export inst60_8 - .export inst61_8 - .export inst62_8 - .export inst63_8 - .export inst64_8 - .export inst65_8 - .export inst66_8 - .export inst67_8 - .export inst68_8 - .export inst69_8 - .export inst6a_8 - .export inst6b_8 - .export inst6c_8 - .export inst6d_8 - .export inst6e_8 - .export inst6f_8 - - .export inst70_8 - .export inst71_8 - .export inst72_8 - .export inst73_8 - .export inst74_8 - .export inst75_8 - .export inst76_8 - .export inst77_8 - .export inst78_8 - .export inst79_8 - .export inst7a_8 - .export inst7b_8 - .export inst7c_8 - .export inst7d_8 - .export inst7e_8 - .export inst7f_8 - - .export inst80_8 - .export inst81_8 - .export inst82_8 - .export inst83_8 - .export inst84_8 - .export inst85_8 - .export inst86_8 - .export inst87_8 - .export inst88_8 - .export inst89_8 - .export inst8a_8 - .export inst8b_8 - .export inst8c_8 - .export inst8d_8 - .export inst8e_8 - .export inst8f_8 - .export inst90_8 - .export inst91_8 - .export inst92_8 - .export inst93_8 - .export inst94_8 - .export inst95_8 - .export inst96_8 - .export inst97_8 - .export inst98_8 - .export inst99_8 - .export inst9a_8 - .export inst9b_8 - .export inst9c_8 - .export inst9d_8 - .export inst9e_8 - .export inst9f_8 - .export insta0_8 - .export insta1_8 - .export insta2_8 - .export insta3_8 - .export insta4_8 - .export insta5_8 - .export insta6_8 - .export insta7_8 - .export insta8_8 - .export insta9_8 - .export instaa_8 - .export instab_8 - .export instac_8 - .export instad_8 - .export instae_8 - .export instaf_8 - .export instb0_8 - .export instb1_8 - .export instb2_8 - .export instb3_8 - .export instb4_8 - .export instb5_8 - .export instb6_8 - .export instb7_8 - .export instb8_8 - .export instb9_8 - .export instba_8 - .export instbb_8 - .export instbc_8 - .export instbd_8 - .export instbe_8 - .export instbf_8 - .export instc0_8 - .export instc1_8 - .export instc2_8 - .export instc3_8 - .export instc4_8 - .export instc5_8 - .export instc6_8 - .export instc7_8 - .export instc8_8 - .export instc9_8 - .export instca_8 - .export instcb_8 - .export instcc_8 - .export instcd_8 - .export instce_8 - .export instcf_8 - .export instd0_8 - .export instd1_8 - .export instd2_8 - .export instd3_8 - .export instd4_8 - .export instd5_8 - .export instd6_8 - .export instd7_8 - .export instd8_8 - .export instd9_8 - .export instda_8 - .export instdb_8 - .export instdc_8 - .export instdd_8 - .export instde_8 - .export instdf_8 - .export inste0_8 - .export inste1_8 - .export inste2_8 - .export inste3_8 - .export inste4_8 - .export inste5_8 - .export inste6_8 - .export inste7_8 - .export inste8_8 - .export inste9_8 - .export instea_8 - .export insteb_8 - .export instec_8 - .export insted_8 - .export instee_8 - .export instef_8 - .export instf0_8 - .export instf1_8 - .export instf2_8 - .export instf3_8 - .export instf4_8 - .export instf5_8 - .export instf6_8 - .export instf7_8 - .export instf8_8 - .export instf9_8 - .export instfa_8 - .export instfb_8 - .export instfc_8 - .export instfd_8 - .export instfe_8 - .export instff_8 - - - .export inst00_16 - .export inst01_16 - .export inst02_16 - .export inst03_16 - .export inst04_16 - .export inst05_16 - .export inst06_16 - .export inst07_16 - .export inst08_16 - .export inst09_16 - .export inst0a_16 - .export inst0b_16 - .export inst0c_16 - .export inst0d_16 - .export inst0e_16 - .export inst0f_16 - - .export inst10_16 - .export inst11_16 - .export inst12_16 - .export inst13_16 - .export inst14_16 - .export inst15_16 - .export inst16_16 - .export inst17_16 - .export inst18_16 - .export inst19_16 - .export inst1a_16 - .export inst1b_16 - .export inst1c_16 - .export inst1d_16 - .export inst1e_16 - .export inst1f_16 - - .export inst20_16 - .export inst21_16 - .export inst22_16 - .export inst23_16 - .export inst24_16 - .export inst25_16 - .export inst26_16 - .export inst27_16 - .export inst28_16 - .export inst29_16 - .export inst2a_16 - .export inst2b_16 - .export inst2c_16 - .export inst2d_16 - .export inst2e_16 - .export inst2f_16 - - .export inst30_16 - .export inst31_16 - .export inst32_16 - .export inst33_16 - .export inst34_16 - .export inst35_16 - .export inst36_16 - .export inst37_16 - .export inst38_16 - .export inst39_16 - .export inst3a_16 - .export inst3b_16 - .export inst3c_16 - .export inst3d_16 - .export inst3e_16 - .export inst3f_16 - - .export inst40_16 - .export inst41_16 - .export inst42_16 - .export inst43_16 - .export inst44_16 - .export inst45_16 - .export inst46_16 - .export inst47_16 - .export inst48_16 - .export inst49_16 - .export inst4a_16 - .export inst4b_16 - .export inst4c_16 - .export inst4d_16 - .export inst4e_16 - .export inst4f_16 - - .export inst50_16 - .export inst51_16 - .export inst52_16 - .export inst53_16 - .export inst54_16 - .export inst55_16 - .export inst56_16 - .export inst57_16 - .export inst58_16 - .export inst59_16 - .export inst5a_16 - .export inst5b_16 - .export inst5c_16 - .export inst5d_16 - .export inst5e_16 - .export inst5f_16 - - .export inst60_16 - .export inst61_16 - .export inst62_16 - .export inst63_16 - .export inst64_16 - .export inst65_16 - .export inst66_16 - .export inst67_16 - .export inst68_16 - .export inst69_16 - .export inst6a_16 - .export inst6b_16 - .export inst6c_16 - .export inst6d_16 - .export inst6e_16 - .export inst6f_16 - - .export inst70_16 - .export inst71_16 - .export inst72_16 - .export inst73_16 - .export inst74_16 - .export inst75_16 - .export inst76_16 - .export inst77_16 - .export inst78_16 - .export inst79_16 - .export inst7a_16 - .export inst7b_16 - .export inst7c_16 - .export inst7d_16 - .export inst7e_16 - .export inst7f_16 - - .export inst80_16 - .export inst81_16 - .export inst82_16 - .export inst83_16 - .export inst84_16 - .export inst85_16 - .export inst86_16 - .export inst87_16 - .export inst88_16 - .export inst89_16 - .export inst8a_16 - .export inst8b_16 - .export inst8c_16 - .export inst8d_16 - .export inst8e_16 - .export inst8f_16 - .export inst90_16 - .export inst91_16 - .export inst92_16 - .export inst93_16 - .export inst94_16 - .export inst95_16 - .export inst96_16 - .export inst97_16 - .export inst98_16 - .export inst99_16 - .export inst9a_16 - .export inst9b_16 - .export inst9c_16 - .export inst9d_16 - .export inst9e_16 - .export inst9f_16 - .export insta0_16 - .export insta1_16 - .export insta2_16 - .export insta3_16 - .export insta4_16 - .export insta5_16 - .export insta6_16 - .export insta7_16 - .export insta8_16 - .export insta9_16 - .export instaa_16 - .export instab_16 - .export instac_16 - .export instad_16 - .export instae_16 - .export instaf_16 - .export instb0_16 - .export instb1_16 - .export instb2_16 - .export instb3_16 - .export instb4_16 - .export instb5_16 - .export instb6_16 - .export instb7_16 - .export instb8_16 - .export instb9_16 - .export instba_16 - .export instbb_16 - .export instbc_16 - .export instbd_16 - .export instbe_16 - .export instbf_16 - .export instc0_16 - .export instc1_16 - .export instc2_16 - .export instc3_16 - .export instc4_16 - .export instc5_16 - .export instc6_16 - .export instc7_16 - .export instc8_16 - .export instc9_16 - .export instca_16 - .export instcb_16 - .export instcc_16 - .export instcd_16 - .export instce_16 - .export instcf_16 - .export instd0_16 - .export instd1_16 - .export instd2_16 - .export instd3_16 - .export instd4_16 - .export instd5_16 - .export instd6_16 - .export instd7_16 - .export instd8_16 - .export instd9_16 - .export instda_16 - .export instdb_16 - .export instdc_16 - .export instdd_16 - .export instde_16 - .export instdf_16 - .export inste0_16 - .export inste1_16 - .export inste2_16 - .export inste3_16 - .export inste4_16 - .export inste5_16 - .export inste6_16 - .export inste7_16 - .export inste8_16 - .export inste9_16 - .export instea_16 - .export insteb_16 - .export instec_16 - .export insted_16 - .export instee_16 - .export instef_16 - .export instf0_16 - .export instf1_16 - .export instf2_16 - .export instf3_16 - .export instf4_16 - .export instf5_16 - .export instf6_16 - .export instf7_16 - .export instf8_16 - .export instf9_16 - .export instfa_16 - .export instfb_16 - .export instfc_16 - .export instfd_16 - .export instfe_16 - .export instff_16 - - - .data -#include "8size_s.h" - - .export table8,data -table8 -#include "8size_s.h" - - .export table16,data -table16 -#include "16size_s.h" - - .export sizes_tab,data -sizes_tab -#include "size_s.h" - - - .export g_engine_c_mode,data -g_engine_c_mode - .word 0 - - .bss - - .export slow_memory,data - .export rom_fc_ff,data - .export rom_cards,data - .export dummy_memory1,data - .align 0x100 -slow_memory .block 128*1024 -dummy_memory1 .block 3*1024 -rom_fc_ff .block 256*1024 -rom_cards .block 256*16 diff --git a/src/vars_hp b/src/vars_hp deleted file mode 100644 index f598cff..0000000 --- a/src/vars_hp +++ /dev/null @@ -1,20 +0,0 @@ - -TARGET = gsportx -OBJECTS = engine_s.o $(OBJECTS1) sound_driver.o xdriver.o -CC = cc -Ae +DA1.1 -CCOPTS = -O -OPTS = -DNDEBUG -SUFFIX = -NAME = gsportx -LDFLAGS = -LDOPTS = -z -LD = $(CC) -EXTRA_LIBS = -lXext -lX11 -lcl -lc -EXTRA_SPECIALS = 8inst_s 16inst_s 8size 16size size_s Alib.h - -AS = cc -Ae -PERL = perl - -XOPTS = -DHPUX -I/usr/include/X11R5 -XLIBS = -L/usr/lib/X11R5 -L/opt/audio/lib - From b20927211daa8c335d17f19010e1438e7ec1662f Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Mon, 17 May 2021 19:07:32 -0500 Subject: [PATCH 7/7] test updated workflow --- .github/workflows/release.yml | 2 +- .gitmodules | 3 +++ cmake/sdl2 | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 160000 cmake/sdl2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38de821..9b3a92d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,7 +64,7 @@ jobs: run: | export MACOSX_DEPLOYMENT_TARGET=10.14 # see: https://gist.github.com/fabianfett/fd811d7921eb856bb100c5c15565077f - sudo xcode-select -s /Applications/Xcode_11.app/Contents/Developer + #sudo xcode-select -s /Applications/Xcode_11.app/Contents/Developer xcode-select -p brew update diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..14d180e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cmake/sdl2"] + path = cmake/sdl2 + url = https://gitlab.com/aminosbh/sdl2-cmake-modules.git diff --git a/cmake/sdl2 b/cmake/sdl2 new file mode 160000 index 0000000..ad006a3 --- /dev/null +++ b/cmake/sdl2 @@ -0,0 +1 @@ +Subproject commit ad006a3daae65a612ed87415037e32188b81071e